FarhadifarForce.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 "FarhadifarForce.hpp"
00037
00038 template<unsigned DIM>
00039 FarhadifarForce<DIM>::FarhadifarForce()
00040 : AbstractForce<DIM>(),
00041 mAreaElasticityParameter(1.0),
00042 mPerimeterContractilityParameter(0.04),
00043 mLineTensionParameter(0.12),
00044 mBoundaryLineTensionParameter(0.12)
00045 {
00046 }
00047
00048 template<unsigned DIM>
00049 FarhadifarForce<DIM>::~FarhadifarForce()
00050 {
00051 }
00052
00053 template<unsigned DIM>
00054 void FarhadifarForce<DIM>::AddForceContribution(AbstractCellPopulation<DIM>& rCellPopulation)
00055 {
00056
00058 if (dynamic_cast<VertexBasedCellPopulation<DIM>*>(&rCellPopulation) == NULL)
00059 {
00060 EXCEPTION("FarhadifarForce is to be used with a VertexBasedCellPopulation only");
00061 }
00062
00063
00064 VertexBasedCellPopulation<DIM>* p_cell_population = static_cast<VertexBasedCellPopulation<DIM>*>(&rCellPopulation);
00065 unsigned num_nodes = p_cell_population->GetNumNodes();
00066 unsigned num_elements = p_cell_population->GetNumElements();
00067
00068
00069 std::vector<double> element_areas(num_elements);
00070 std::vector<double> element_perimeters(num_elements);
00071 std::vector<double> target_areas(num_elements);
00072 for (typename VertexMesh<DIM,DIM>::VertexElementIterator elem_iter = p_cell_population->rGetMesh().GetElementIteratorBegin();
00073 elem_iter != p_cell_population->rGetMesh().GetElementIteratorEnd();
00074 ++elem_iter)
00075 {
00076 unsigned elem_index = elem_iter->GetIndex();
00077 element_areas[elem_index] = p_cell_population->rGetMesh().GetVolumeOfElement(elem_index);
00078 element_perimeters[elem_index] = p_cell_population->rGetMesh().GetSurfaceAreaOfElement(elem_index);
00079 try
00080 {
00081
00082
00083
00084
00085 target_areas[elem_index] = p_cell_population->GetCellUsingLocationIndex(elem_index)->GetCellData()->GetItem("target area");
00086 }
00087 catch (Exception&)
00088 {
00089 EXCEPTION("You need to add an AbstractTargetAreaModifier to the simulation in order to use a FarhadifarForce");
00090 }
00091 }
00092
00093
00094 for (unsigned node_index=0; node_index<num_nodes; node_index++)
00095 {
00096 Node<DIM>* p_this_node = p_cell_population->GetNode(node_index);
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 c_vector<double, DIM> area_elasticity_contribution = zero_vector<double>(DIM);
00111 c_vector<double, DIM> perimeter_contractility_contribution = zero_vector<double>(DIM);
00112 c_vector<double, DIM> line_tension_contribution = zero_vector<double>(DIM);
00113
00114
00115 std::set<unsigned> containing_elem_indices = p_cell_population->GetNode(node_index)->rGetContainingElementIndices();
00116
00117
00118 for (std::set<unsigned>::iterator iter = containing_elem_indices.begin();
00119 iter != containing_elem_indices.end();
00120 ++iter)
00121 {
00122
00123 VertexElement<DIM, DIM>* p_element = p_cell_population->GetElement(*iter);
00124 unsigned elem_index = p_element->GetIndex();
00125 unsigned num_nodes_elem = p_element->GetNumNodes();
00126
00127
00128 unsigned local_index = p_element->GetNodeLocalIndex(node_index);
00129
00130
00131 c_vector<double, DIM> element_area_gradient =
00132 p_cell_population->rGetMesh().GetAreaGradientOfElementAtNode(p_element, local_index);
00133 area_elasticity_contribution -= GetAreaElasticityParameter()*(element_areas[elem_index] -
00134 target_areas[elem_index])*element_area_gradient;
00135
00136
00137
00138 unsigned previous_node_local_index = (num_nodes_elem+local_index-1)%num_nodes_elem;
00139 Node<DIM>* p_previous_node = p_element->GetNode(previous_node_local_index);
00140
00141 unsigned next_node_local_index = (local_index+1)%num_nodes_elem;
00142 Node<DIM>* p_next_node = p_element->GetNode(next_node_local_index);
00143
00144
00145
00146 double previous_edge_line_tension_parameter = GetLineTensionParameter(p_previous_node, p_this_node, *p_cell_population);
00147 double next_edge_line_tension_parameter = GetLineTensionParameter(p_this_node, p_next_node, *p_cell_population);
00148
00149
00150 c_vector<double, DIM> previous_edge_gradient =
00151 -p_cell_population->rGetMesh().GetNextEdgeGradientOfElementAtNode(p_element, previous_node_local_index);
00152 c_vector<double, DIM> next_edge_gradient = p_cell_population->rGetMesh().GetNextEdgeGradientOfElementAtNode(p_element, local_index);
00153
00154
00155 line_tension_contribution -= previous_edge_line_tension_parameter*previous_edge_gradient +
00156 next_edge_line_tension_parameter*next_edge_gradient;
00157
00158
00159 c_vector<double, DIM> element_perimeter_gradient = previous_edge_gradient + next_edge_gradient;
00160 perimeter_contractility_contribution -= GetPerimeterContractilityParameter()* element_perimeters[elem_index]*
00161 element_perimeter_gradient;
00162 }
00163
00164 c_vector<double, DIM> force_on_node = area_elasticity_contribution + perimeter_contractility_contribution + line_tension_contribution;
00165 p_cell_population->GetNode(node_index)->AddAppliedForceContribution(force_on_node);
00166 }
00167 }
00168
00169 template<unsigned DIM>
00170 double FarhadifarForce<DIM>::GetLineTensionParameter(Node<DIM>* pNodeA, Node<DIM>* pNodeB, VertexBasedCellPopulation<DIM>& rVertexCellPopulation)
00171 {
00172
00173 std::set<unsigned> elements_containing_nodeA = pNodeA->rGetContainingElementIndices();
00174 std::set<unsigned> elements_containing_nodeB = pNodeB->rGetContainingElementIndices();
00175
00176
00177 std::set<unsigned> shared_elements;
00178 std::set_intersection(elements_containing_nodeA.begin(),
00179 elements_containing_nodeA.end(),
00180 elements_containing_nodeB.begin(),
00181 elements_containing_nodeB.end(),
00182 std::inserter(shared_elements, shared_elements.begin()));
00183
00184
00185 assert(!shared_elements.empty());
00186
00187
00188
00189 double line_tension_parameter_in_calculation = GetLineTensionParameter()/2.0;
00190
00191
00192 if (shared_elements.size() == 1)
00193 {
00194 line_tension_parameter_in_calculation = GetBoundaryLineTensionParameter();
00195 }
00196
00197 return line_tension_parameter_in_calculation;
00198 }
00199
00200 template<unsigned DIM>
00201 double FarhadifarForce<DIM>::GetAreaElasticityParameter()
00202 {
00203 return mAreaElasticityParameter;
00204 }
00205
00206 template<unsigned DIM>
00207 double FarhadifarForce<DIM>::GetPerimeterContractilityParameter()
00208 {
00209 return mPerimeterContractilityParameter;
00210 }
00211
00212 template<unsigned DIM>
00213 double FarhadifarForce<DIM>::GetLineTensionParameter()
00214 {
00215 return mLineTensionParameter;
00216 }
00217
00218 template<unsigned DIM>
00219 double FarhadifarForce<DIM>::GetBoundaryLineTensionParameter()
00220 {
00221 return mBoundaryLineTensionParameter;
00222 }
00223
00224 template<unsigned DIM>
00225 void FarhadifarForce<DIM>::SetAreaElasticityParameter(double areaElasticityParameter)
00226 {
00227 mAreaElasticityParameter = areaElasticityParameter;
00228 }
00229
00230 template<unsigned DIM>
00231 void FarhadifarForce<DIM>::SetPerimeterContractilityParameter(double perimeterContractilityParameter)
00232 {
00233 mPerimeterContractilityParameter = perimeterContractilityParameter;
00234 }
00235
00236 template<unsigned DIM>
00237 void FarhadifarForce<DIM>::SetLineTensionParameter(double lineTensionParameter)
00238 {
00239 mLineTensionParameter = lineTensionParameter;
00240 }
00241
00242 template<unsigned DIM>
00243 void FarhadifarForce<DIM>::SetBoundaryLineTensionParameter(double boundaryLineTensionParameter)
00244 {
00245 mBoundaryLineTensionParameter = boundaryLineTensionParameter;
00246 }
00247
00248
00249 template<unsigned DIM>
00250 void FarhadifarForce<DIM>::OutputForceParameters(out_stream& rParamsFile)
00251 {
00252 *rParamsFile << "\t\t\t<AreaElasticityParameter>" << mAreaElasticityParameter << "</AreaElasticityParameter>\n";
00253 *rParamsFile << "\t\t\t<PerimeterContractilityParameter>" << mPerimeterContractilityParameter << "</PerimeterContractilityParameter>\n";
00254 *rParamsFile << "\t\t\t<LineTensionParameter>" << mLineTensionParameter << "</LineTensionParameter>\n";
00255 *rParamsFile << "\t\t\t<BoundaryLineTensionParameter>" << mBoundaryLineTensionParameter << "</BoundaryLineTensionParameter>\n";
00256
00257
00258 AbstractForce<DIM>::OutputForceParameters(rParamsFile);
00259 }
00260
00262
00264
00265 template class FarhadifarForce<1>;
00266 template class FarhadifarForce<2>;
00267 template class FarhadifarForce<3>;
00268
00269
00270 #include "SerializationExportWrapperForCpp.hpp"
00271 EXPORT_TEMPLATE_CLASS_SAME_DIMS(FarhadifarForce)