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