NagaiHondaForce.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 "NagaiHondaForce.hpp"
00030
00031 template<unsigned DIM>
00032 NagaiHondaForce<DIM>::NagaiHondaForce()
00033 : AbstractForce<DIM>(),
00034 mNagaiHondaDeformationEnergyParameter(100.0),
00035 mNagaiHondaMembraneSurfaceEnergyParameter(10.0),
00036 mNagaiHondaCellCellAdhesionEnergyParameter(1.0),
00037 mNagaiHondaCellBoundaryAdhesionEnergyParameter(1.0),
00038 mMatureCellTargetArea(1.0)
00039 {
00040 }
00041
00042 template<unsigned DIM>
00043 NagaiHondaForce<DIM>::~NagaiHondaForce()
00044 {
00045 }
00046
00047 template<unsigned DIM>
00048 void NagaiHondaForce<DIM>::AddForceContribution(std::vector<c_vector<double, DIM> >& rForces,
00049 AbstractCellPopulation<DIM>& rCellPopulation)
00050 {
00051
00052 if (dynamic_cast<VertexBasedCellPopulation<DIM>*>(&rCellPopulation) == NULL)
00053 {
00054 EXCEPTION("NagaiHondaForce is to be used with a VertexBasedCellPopulation only");
00055 }
00056
00057
00058 VertexBasedCellPopulation<DIM>* p_cell_population = static_cast<VertexBasedCellPopulation<DIM>*>(&rCellPopulation);
00059
00060
00061 for (unsigned node_index=0; node_index<p_cell_population->GetNumNodes(); node_index++)
00062 {
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 c_vector<double, DIM> deformation_contribution = zero_vector<double>(DIM);
00080 c_vector<double, DIM> membrane_surface_tension_contribution = zero_vector<double>(DIM);
00081 c_vector<double, DIM> adhesion_contribution = zero_vector<double>(DIM);
00082
00083
00084 std::set<unsigned> containing_elem_indices = p_cell_population->GetNode(node_index)->rGetContainingElementIndices();
00085
00086
00087 for (std::set<unsigned>::iterator iter = containing_elem_indices.begin();
00088 iter != containing_elem_indices.end();
00089 ++iter)
00090 {
00091
00092 VertexElement<DIM, DIM>* p_element = p_cell_population->GetElement(*iter);
00093 unsigned element_index = p_element->GetIndex();
00094
00095
00096 unsigned local_index = p_element->GetNodeLocalIndex(node_index);
00097
00098
00099
00100
00101 double element_area = p_cell_population->rGetMesh().GetVolumeOfElement(*iter);
00102 c_vector<double, DIM> element_area_gradient = p_cell_population->rGetMesh().GetAreaGradientOfElementAtNode(p_element, local_index);
00103
00104
00105 double cell_target_area = GetTargetAreaOfCell(p_cell_population->GetCellUsingLocationIndex(element_index));
00106
00107
00108 deformation_contribution -= 2*GetNagaiHondaDeformationEnergyParameter()*(element_area - cell_target_area)*element_area_gradient;
00109
00110
00111
00112
00113
00114
00115 double element_perimeter = p_cell_population->rGetMesh().GetSurfaceAreaOfElement(*iter);
00116 c_vector<double, DIM> element_perimeter_gradient = p_cell_population->rGetMesh().GetPerimeterGradientOfElementAtNode(p_element, local_index);
00117
00118
00119 double cell_target_perimeter = 2*sqrt(M_PI*cell_target_area);
00120
00121
00122 membrane_surface_tension_contribution -= 2*GetNagaiHondaMembraneSurfaceEnergyParameter()*(element_perimeter - cell_target_perimeter)*element_perimeter_gradient;
00123
00124
00125
00126
00127
00128
00129 Node<DIM>* p_current_node = p_element->GetNode(local_index);
00130
00131 unsigned previous_node_local_index = (p_element->GetNumNodes()+local_index-1)%(p_element->GetNumNodes());
00132 Node<DIM>* p_previous_node = p_element->GetNode(previous_node_local_index);
00133
00134 unsigned next_node_local_index = (local_index+1)%(p_element->GetNumNodes());
00135 Node<DIM>* p_next_node = p_element->GetNode(next_node_local_index);
00136
00137
00138 double previous_edge_adhesion_parameter;
00139 double next_edge_adhesion_parameter;
00140
00141 previous_edge_adhesion_parameter = GetAdhesionParameter(p_previous_node, p_current_node, *p_cell_population);
00142 next_edge_adhesion_parameter = GetAdhesionParameter(p_current_node, p_next_node, *p_cell_population);
00143
00144
00145 c_vector<double, DIM> previous_edge_gradient = p_cell_population->rGetMesh().GetPreviousEdgeGradientOfElementAtNode(p_element, local_index);
00146
00147
00148 c_vector<double, DIM> next_edge_gradient = p_cell_population->rGetMesh().GetNextEdgeGradientOfElementAtNode(p_element, local_index);
00149
00150
00151 adhesion_contribution -= previous_edge_adhesion_parameter*previous_edge_gradient + next_edge_adhesion_parameter*next_edge_gradient;
00152
00153
00154 }
00155
00156 c_vector<double, DIM> force_on_node = deformation_contribution +
00157 membrane_surface_tension_contribution +
00158 adhesion_contribution;
00159
00160 rForces[node_index] += force_on_node;
00161 }
00162 }
00163
00164 template<unsigned DIM>
00165 double NagaiHondaForce<DIM>::GetAdhesionParameter(Node<DIM>* pNodeA, Node<DIM>* pNodeB, VertexBasedCellPopulation<DIM>& rVertexCellPopulation)
00166 {
00167
00168 std::set<unsigned> elements_containing_nodeA = pNodeA->rGetContainingElementIndices();
00169 std::set<unsigned> elements_containing_nodeB = pNodeB->rGetContainingElementIndices();
00170
00171
00172 std::set<unsigned> shared_elements;
00173 std::set_intersection(elements_containing_nodeA.begin(),
00174 elements_containing_nodeA.end(),
00175 elements_containing_nodeB.begin(),
00176 elements_containing_nodeB.end(),
00177 std::inserter(shared_elements, shared_elements.begin()));
00178
00179
00180 assert(!shared_elements.empty());
00181
00182 double adhesion_parameter = GetNagaiHondaCellCellAdhesionEnergyParameter();
00183
00184
00185 if (shared_elements.size() == 1)
00186 {
00187 adhesion_parameter = GetNagaiHondaCellBoundaryAdhesionEnergyParameter();
00188 }
00189
00190 return adhesion_parameter;
00191 }
00192
00193 template<unsigned DIM>
00194 double NagaiHondaForce<DIM>::GetNagaiHondaDeformationEnergyParameter()
00195 {
00196 return mNagaiHondaDeformationEnergyParameter;
00197 }
00198
00199 template<unsigned DIM>
00200 double NagaiHondaForce<DIM>::GetNagaiHondaMembraneSurfaceEnergyParameter()
00201 {
00202 return mNagaiHondaMembraneSurfaceEnergyParameter;
00203 }
00204
00205 template<unsigned DIM>
00206 double NagaiHondaForce<DIM>::GetNagaiHondaCellCellAdhesionEnergyParameter()
00207 {
00208 return mNagaiHondaCellCellAdhesionEnergyParameter;
00209 }
00210
00211 template<unsigned DIM>
00212 double NagaiHondaForce<DIM>::GetNagaiHondaCellBoundaryAdhesionEnergyParameter()
00213 {
00214 return mNagaiHondaCellBoundaryAdhesionEnergyParameter;
00215 }
00216
00217 template<unsigned DIM>
00218 void NagaiHondaForce<DIM>::SetNagaiHondaDeformationEnergyParameter(double deformationEnergyParameter)
00219 {
00220 mNagaiHondaDeformationEnergyParameter = deformationEnergyParameter;
00221 }
00222
00223 template<unsigned DIM>
00224 void NagaiHondaForce<DIM>::SetNagaiHondaMembraneSurfaceEnergyParameter(double membraneSurfaceEnergyParameter)
00225 {
00226 mNagaiHondaMembraneSurfaceEnergyParameter = membraneSurfaceEnergyParameter;
00227 }
00228
00229 template<unsigned DIM>
00230 void NagaiHondaForce<DIM>::SetNagaiHondaCellCellAdhesionEnergyParameter(double cellCellAdhesionEnergyParameter)
00231 {
00232 mNagaiHondaCellCellAdhesionEnergyParameter = cellCellAdhesionEnergyParameter;
00233 }
00234
00235 template<unsigned DIM>
00236 void NagaiHondaForce<DIM>::SetNagaiHondaCellBoundaryAdhesionEnergyParameter(double cellBoundaryAdhesionEnergyParameter)
00237 {
00238 mNagaiHondaCellBoundaryAdhesionEnergyParameter = cellBoundaryAdhesionEnergyParameter;
00239 }
00240
00241 template<unsigned DIM>
00242 double NagaiHondaForce<DIM>::GetTargetAreaOfCell(const CellPtr pCell) const
00243 {
00244
00245 double cell_target_area = mMatureCellTargetArea;
00246
00247 double cell_age = pCell->GetAge();
00248 double g1_duration = pCell->GetCellCycleModel()->GetG1Duration();
00249
00250
00251 if (g1_duration == DBL_MAX)
00252 {
00253
00254 g1_duration = pCell->GetCellCycleModel()->GetTransitCellG1Duration();
00255 }
00256
00257 if (pCell->HasCellProperty<ApoptoticCellProperty>())
00258 {
00259
00260 if (pCell->GetStartOfApoptosisTime() - pCell->GetBirthTime() < g1_duration)
00261 {
00262 cell_target_area *= 0.5*(1 + (pCell->GetStartOfApoptosisTime() - pCell->GetBirthTime())/g1_duration);
00263 }
00264
00265
00266 cell_target_area = cell_target_area - 0.5*cell_target_area/(pCell->GetApoptosisTime())*(SimulationTime::Instance()->GetTime()-pCell->GetStartOfApoptosisTime());
00267
00268
00269 if (cell_target_area < 0)
00270 {
00271 cell_target_area = 0;
00272 }
00273 }
00274 else
00275 {
00276
00277 if (cell_age < g1_duration)
00278 {
00279 cell_target_area *= 0.5*(1 + cell_age/g1_duration);
00280 }
00281 }
00282
00283 return cell_target_area;
00284 }
00285
00286 template<unsigned DIM>
00287 double NagaiHondaForce<DIM>::GetMatureCellTargetArea() const
00288 {
00289 return mMatureCellTargetArea;
00290 }
00291
00292 template<unsigned DIM>
00293 void NagaiHondaForce<DIM>::SetMatureCellTargetArea(double matureCellTargetArea)
00294 {
00295 assert(matureCellTargetArea >= 0.0);
00296 mMatureCellTargetArea = matureCellTargetArea;
00297 }
00298
00299 template<unsigned DIM>
00300 void NagaiHondaForce<DIM>::OutputForceParameters(out_stream& rParamsFile)
00301 {
00302 *rParamsFile << "\t\t\t<NagaiHondaDeformationEnergyParameter>" << mNagaiHondaDeformationEnergyParameter << "</NagaiHondaDeformationEnergyParameter>\n";
00303 *rParamsFile << "\t\t\t<NagaiHondaMembraneSurfaceEnergyParameter>" << mNagaiHondaMembraneSurfaceEnergyParameter << "</NagaiHondaMembraneSurfaceEnergyParameter>\n";
00304 *rParamsFile << "\t\t\t<NagaiHondaCellCellAdhesionEnergyParameter>" << mNagaiHondaCellCellAdhesionEnergyParameter << "</NagaiHondaCellCellAdhesionEnergyParameter>\n";
00305 *rParamsFile << "\t\t\t<NagaiHondaCellBoundaryAdhesionEnergyParameter>" << mNagaiHondaCellBoundaryAdhesionEnergyParameter << "</NagaiHondaCellBoundaryAdhesionEnergyParameter>\n";
00306 *rParamsFile << "\t\t\t<MatureCellTargetArea>" << mMatureCellTargetArea << "</MatureCellTargetArea>\n";
00307
00308
00309 AbstractForce<DIM>::OutputForceParameters(rParamsFile);
00310 }
00311
00313
00315
00316 template class NagaiHondaForce<1>;
00317 template class NagaiHondaForce<2>;
00318 template class NagaiHondaForce<3>;
00319
00320
00321 #include "SerializationExportWrapperForCpp.hpp"
00322 EXPORT_TEMPLATE_CLASS_SAME_DIMS(NagaiHondaForce)