SurfaceAreaConstraintPottsUpdateRule.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "SurfaceAreaConstraintPottsUpdateRule.hpp"
00037
00038 template<unsigned DIM>
00039 SurfaceAreaConstraintPottsUpdateRule<DIM>::SurfaceAreaConstraintPottsUpdateRule()
00040 : AbstractPottsUpdateRule<DIM>(),
00041 mDeformationEnergyParameter(0.5),
00042 mMatureCellTargetSurfaceArea(16.0)
00043 {
00045 }
00046
00047 template<unsigned DIM>
00048 SurfaceAreaConstraintPottsUpdateRule<DIM>::~SurfaceAreaConstraintPottsUpdateRule()
00049 {
00050 }
00051
00052 template<unsigned DIM>
00053 double SurfaceAreaConstraintPottsUpdateRule<DIM>::EvaluateHamiltonianContribution(unsigned currentNodeIndex,
00054 unsigned targetNodeIndex,
00055 PottsBasedCellPopulation<DIM>& rCellPopulation)
00056 {
00057 double delta_H = 0.0;
00058
00059
00060 assert(DIM == 2 || DIM == 3);
00061
00062 std::set<unsigned> containing_elements = rCellPopulation.GetNode(currentNodeIndex)->rGetContainingElementIndices();
00063 std::set<unsigned> new_location_containing_elements = rCellPopulation.GetNode(targetNodeIndex)->rGetContainingElementIndices();
00064
00065 bool current_node_contained = !containing_elements.empty();
00066 bool target_node_contained = !new_location_containing_elements.empty();
00067
00068
00069 assert(new_location_containing_elements.size() < 2);
00070
00071 if (!current_node_contained && !target_node_contained)
00072 {
00073 EXCEPTION("At least one of the current node or target node must be in an element.");
00074 }
00075
00076 if (current_node_contained && target_node_contained)
00077 {
00078 if (*(new_location_containing_elements.begin()) == *(containing_elements.begin()))
00079 {
00080 EXCEPTION("The current node and target node must not be in the same element.");
00081 }
00082 }
00083
00084
00085 unsigned neighbours_in_same_element_as_current_node = 0;
00086 unsigned neighbours_in_same_element_as_target_node = 0;
00087 std::set<unsigned> target_neighbouring_node_indices = rCellPopulation.rGetMesh().GetVonNeumannNeighbouringNodeIndices(targetNodeIndex);
00088 for (std::set<unsigned>::iterator iter = target_neighbouring_node_indices.begin();
00089 iter != target_neighbouring_node_indices.end();
00090 ++iter)
00091 {
00092 std::set<unsigned> neighbouring_node_containing_elements = rCellPopulation.rGetMesh().GetNode(*iter)->rGetContainingElementIndices();
00093
00094
00095 assert(neighbouring_node_containing_elements.size() < 2);
00096
00097 bool neighbouring_node_contained = !neighbouring_node_containing_elements.empty();
00098
00099 if (neighbouring_node_contained && target_node_contained)
00100 {
00101 unsigned neighbour_element = (*neighbouring_node_containing_elements.begin());
00102 unsigned target_element = (*new_location_containing_elements.begin());
00103 if (target_element == neighbour_element)
00104 {
00105 neighbours_in_same_element_as_target_node++;
00106 }
00107 }
00108 if (neighbouring_node_contained && current_node_contained)
00109 {
00110 unsigned neighbour_element = (*neighbouring_node_containing_elements.begin());
00111 unsigned current_element = (*containing_elements.begin());
00112 if (current_element == neighbour_element)
00113 {
00114 neighbours_in_same_element_as_current_node++;
00115 }
00116 }
00117 }
00118
00119 if (DIM == 2)
00120 {
00121 assert(neighbours_in_same_element_as_current_node<5);
00122 assert(neighbours_in_same_element_as_target_node<5);
00123
00124 double change_in_surface_area[5] = {4,2,0,-2,-4};
00125
00126 if (current_node_contained)
00127 {
00128 unsigned current_element = (*containing_elements.begin());
00129 double current_surface_area = rCellPopulation.rGetMesh().GetSurfaceAreaOfElement(current_element);
00130 double current_surface_area_difference = current_surface_area - mMatureCellTargetSurfaceArea;
00131 double current_surface_area_difference_after_switch = current_surface_area_difference + change_in_surface_area[neighbours_in_same_element_as_current_node];
00132
00133 delta_H += mDeformationEnergyParameter*(current_surface_area_difference_after_switch*current_surface_area_difference_after_switch - current_surface_area_difference*current_surface_area_difference);
00134 }
00135 if (target_node_contained)
00136 {
00137 unsigned target_element = (*new_location_containing_elements.begin());
00138 double target_surface_area = rCellPopulation.rGetMesh().GetSurfaceAreaOfElement(target_element);
00139 double target_surface_area_difference = target_surface_area - mMatureCellTargetSurfaceArea;
00140 double target_surface_area_difference_after_switch = target_surface_area_difference - change_in_surface_area[neighbours_in_same_element_as_target_node];
00141
00142 delta_H += mDeformationEnergyParameter*(target_surface_area_difference_after_switch*target_surface_area_difference_after_switch - target_surface_area_difference*target_surface_area_difference);
00143 }
00144 }
00145 else if (DIM==3)
00146 {
00147 assert(neighbours_in_same_element_as_current_node < 7);
00148 assert(neighbours_in_same_element_as_target_node < 7);
00149
00150 double change_in_surface_area[7] = {6,4,2,0,-2,-4,-6};
00151
00152 if (current_node_contained)
00153 {
00154 unsigned current_element = (*containing_elements.begin());
00155 double current_surface_area = rCellPopulation.rGetMesh().GetSurfaceAreaOfElement(current_element);
00156 double current_surface_area_difference = current_surface_area - mMatureCellTargetSurfaceArea;
00157 double current_surface_area_difference_after_switch = current_surface_area_difference + change_in_surface_area[neighbours_in_same_element_as_current_node];
00158
00159 delta_H += mDeformationEnergyParameter*(current_surface_area_difference_after_switch*current_surface_area_difference_after_switch - current_surface_area_difference*current_surface_area_difference);
00160 }
00161 if (target_node_contained)
00162 {
00163 unsigned target_element = (*new_location_containing_elements.begin());
00164 double target_surface_area = rCellPopulation.rGetMesh().GetSurfaceAreaOfElement(target_element);
00165 double target_surface_area_difference = target_surface_area - mMatureCellTargetSurfaceArea;
00166 double target_surface_area_difference_after_switch = target_surface_area_difference - change_in_surface_area[neighbours_in_same_element_as_target_node];
00167
00168 delta_H += mDeformationEnergyParameter*(target_surface_area_difference_after_switch*target_surface_area_difference_after_switch - target_surface_area_difference*target_surface_area_difference);
00169 }
00170 }
00171
00172 return delta_H;
00173 }
00174
00175 template<unsigned DIM>
00176 double SurfaceAreaConstraintPottsUpdateRule<DIM>::GetDeformationEnergyParameter()
00177 {
00178 return mDeformationEnergyParameter;
00179 }
00180
00181 template<unsigned DIM>
00182 void SurfaceAreaConstraintPottsUpdateRule<DIM>::SetDeformationEnergyParameter(double deformationEnergyParameter)
00183 {
00184 mDeformationEnergyParameter = deformationEnergyParameter;
00185 }
00186
00187 template<unsigned DIM>
00188 double SurfaceAreaConstraintPottsUpdateRule<DIM>::GetMatureCellTargetSurfaceArea() const
00189 {
00190 return mMatureCellTargetSurfaceArea;
00191 }
00192
00193 template<unsigned DIM>
00194 void SurfaceAreaConstraintPottsUpdateRule<DIM>::SetMatureCellTargetSurfaceArea(double matureCellTargetSurfaceArea)
00195 {
00196 assert(matureCellTargetSurfaceArea >= 0.0);
00197 mMatureCellTargetSurfaceArea = matureCellTargetSurfaceArea;
00198 }
00199
00200 template<unsigned DIM>
00201 void SurfaceAreaConstraintPottsUpdateRule<DIM>::OutputUpdateRuleParameters(out_stream& rParamsFile)
00202 {
00203 *rParamsFile << "\t\t\t<DeformationEnergyParameter>" << mDeformationEnergyParameter << "</DeformationEnergyParameter>\n";
00204 *rParamsFile << "\t\t\t<MatureCellTargetSurfaceArea>" << mMatureCellTargetSurfaceArea << "</MatureCellTargetSurfaceArea>\n";
00205
00206
00207 AbstractPottsUpdateRule<DIM>::OutputUpdateRuleParameters(rParamsFile);
00208 }
00209
00211
00213
00214 template class SurfaceAreaConstraintPottsUpdateRule<1>;
00215 template class SurfaceAreaConstraintPottsUpdateRule<2>;
00216 template class SurfaceAreaConstraintPottsUpdateRule<3>;
00217
00218
00219 #include "SerializationExportWrapperForCpp.hpp"
00220 EXPORT_TEMPLATE_CLASS_SAME_DIMS(SurfaceAreaConstraintPottsUpdateRule)