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 #include "SurfaceAreaConstraintPottsUpdateRule.hpp"
00030
00031 template<unsigned DIM>
00032 SurfaceAreaConstraintPottsUpdateRule<DIM>::SurfaceAreaConstraintPottsUpdateRule()
00033 : AbstractPottsUpdateRule<DIM>(),
00034 mDeformationEnergyParameter(0.5),
00035 mMatureCellTargetSurfaceArea(16.0)
00036 {
00038 }
00039
00040 template<unsigned DIM>
00041 SurfaceAreaConstraintPottsUpdateRule<DIM>::~SurfaceAreaConstraintPottsUpdateRule()
00042 {
00043 }
00044
00045 template<unsigned DIM>
00046 double SurfaceAreaConstraintPottsUpdateRule<DIM>::EvaluateHamiltonianContribution(unsigned currentNodeIndex,
00047 unsigned targetNodeIndex,
00048 PottsBasedCellPopulation<DIM>& rCellPopulation)
00049 {
00050 double delta_H = 0.0;
00051
00052
00053 assert(DIM == 2);
00054
00055 std::set<unsigned> containing_elements = rCellPopulation.GetNode(currentNodeIndex)->rGetContainingElementIndices();
00056 std::set<unsigned> new_location_containing_elements = rCellPopulation.GetNode(targetNodeIndex)->rGetContainingElementIndices();
00057
00058 bool current_node_contained = !containing_elements.empty();
00059 bool target_node_contained = !new_location_containing_elements.empty();
00060
00061
00062 assert(new_location_containing_elements.size() < 2);
00063
00064 if(!current_node_contained && !target_node_contained)
00065 {
00066 EXCEPTION("At least one of the current node or target node must be in an element.");
00067 }
00068
00069 if (current_node_contained && target_node_contained)
00070 {
00071 if(*(new_location_containing_elements.begin()) == *(containing_elements.begin()))
00072 {
00073 EXCEPTION("The current node and target node must not be in the same element.");
00074 }
00075 }
00076
00077
00078 unsigned neighbours_in_same_element_as_current_node = 0;
00079 unsigned neighbours_in_same_element_as_target_node = 0;
00080 std::set<unsigned> target_neighbouring_node_indices = rCellPopulation.rGetMesh().GetVonNeumannNeighbouringNodeIndices(targetNodeIndex);
00081 for (std::set<unsigned>::iterator iter = target_neighbouring_node_indices.begin();
00082 iter != target_neighbouring_node_indices.end();
00083 ++iter)
00084 {
00085 std::set<unsigned> neighbouring_node_containing_elements = rCellPopulation.rGetMesh().GetNode(*iter)->rGetContainingElementIndices();
00086
00087
00088 assert(neighbouring_node_containing_elements.size() < 2);
00089
00090 bool neighbouring_node_contained = !neighbouring_node_containing_elements.empty();
00091
00092 if (neighbouring_node_contained && target_node_contained)
00093 {
00094 unsigned neighbour_element = (*neighbouring_node_containing_elements.begin());
00095 unsigned target_element = (*new_location_containing_elements.begin());
00096 if (target_element == neighbour_element)
00097 {
00098 neighbours_in_same_element_as_target_node++;
00099 }
00100 }
00101 if (neighbouring_node_contained && current_node_contained)
00102 {
00103 unsigned neighbour_element = (*neighbouring_node_containing_elements.begin());
00104 unsigned current_element = (*containing_elements.begin());
00105 if (current_element == neighbour_element)
00106 {
00107 neighbours_in_same_element_as_current_node++;
00108 }
00109 }
00110 }
00111 assert(neighbours_in_same_element_as_current_node<5);
00112 assert(neighbours_in_same_element_as_target_node<5);
00113
00114 double change_in_surface_area[5] = {4,2,0,-2,-4};
00115
00116 if (current_node_contained)
00117 {
00118 unsigned current_element = (*containing_elements.begin());
00119 double current_surface_area = rCellPopulation.rGetMesh().GetSurfaceAreaOfElement(current_element);
00120 double current_surface_area_difference = current_surface_area - mMatureCellTargetSurfaceArea;
00121 double current_surface_area_difference_after_switch = current_surface_area_difference + change_in_surface_area[neighbours_in_same_element_as_current_node];
00122
00123 delta_H += mDeformationEnergyParameter*(current_surface_area_difference_after_switch*current_surface_area_difference_after_switch - current_surface_area_difference*current_surface_area_difference);
00124 }
00125 if (target_node_contained)
00126 {
00127 unsigned target_element = (*new_location_containing_elements.begin());
00128 double target_surface_area = rCellPopulation.rGetMesh().GetSurfaceAreaOfElement(target_element);
00129 double target_surface_area_difference = target_surface_area - mMatureCellTargetSurfaceArea;
00130 double target_surface_area_difference_after_switch = target_surface_area_difference - change_in_surface_area[neighbours_in_same_element_as_target_node];
00131
00132 delta_H += mDeformationEnergyParameter*(target_surface_area_difference_after_switch*target_surface_area_difference_after_switch - target_surface_area_difference*target_surface_area_difference);
00133 }
00134
00135 return delta_H;
00136 }
00137
00138 template<unsigned DIM>
00139 double SurfaceAreaConstraintPottsUpdateRule<DIM>::GetDeformationEnergyParameter()
00140 {
00141 return mDeformationEnergyParameter;
00142 }
00143
00144 template<unsigned DIM>
00145 void SurfaceAreaConstraintPottsUpdateRule<DIM>::SetDeformationEnergyParameter(double deformationEnergyParameter)
00146 {
00147 mDeformationEnergyParameter = deformationEnergyParameter;
00148 }
00149
00150 template<unsigned DIM>
00151 double SurfaceAreaConstraintPottsUpdateRule<DIM>::GetMatureCellTargetSurfaceArea() const
00152 {
00153 return mMatureCellTargetSurfaceArea;
00154 }
00155
00156 template<unsigned DIM>
00157 void SurfaceAreaConstraintPottsUpdateRule<DIM>::SetMatureCellTargetSurfaceArea(double matureCellTargetSurfaceArea)
00158 {
00159 assert(matureCellTargetSurfaceArea >= 0.0);
00160 mMatureCellTargetSurfaceArea = matureCellTargetSurfaceArea;
00161 }
00162
00163 template<unsigned DIM>
00164 void SurfaceAreaConstraintPottsUpdateRule<DIM>::OutputUpdateRuleParameters(out_stream& rParamsFile)
00165 {
00166 *rParamsFile << "\t\t\t<DeformationEnergyParameter>" << mDeformationEnergyParameter << "</DeformationEnergyParameter>\n";
00167 *rParamsFile << "\t\t\t<MatureCellTargetSurfaceArea>" << mMatureCellTargetSurfaceArea << "</MatureCellTargetSurfaceArea>\n";
00168
00169
00170 AbstractPottsUpdateRule<DIM>::OutputUpdateRuleParameters(rParamsFile);
00171 }
00172
00174
00176
00177 template class SurfaceAreaConstraintPottsUpdateRule<1>;
00178 template class SurfaceAreaConstraintPottsUpdateRule<2>;
00179 template class SurfaceAreaConstraintPottsUpdateRule<3>;
00180
00181
00182 #include "SerializationExportWrapperForCpp.hpp"
00183 EXPORT_TEMPLATE_CLASS_SAME_DIMS(SurfaceAreaConstraintPottsUpdateRule)