36#include "GeneralisedLinearSpringForce.hpp"
38#include "AbstractCentreBasedCellPopulation.hpp"
39#include "MeshBasedCellPopulation.hpp"
40#include "NodeBasedCellPopulation.hpp"
42template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
45 mMeinekeSpringStiffness(15.0),
46 mMeinekeDivisionRestingSpringLength(0.5),
47 mMeinekeSpringGrowthDuration(1.0)
55template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
57 unsigned nodeBGlobalIndex,
59 bool isCloserThanRestLength)
64template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
69template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
71 unsigned nodeBGlobalIndex,
75 assert(nodeAGlobalIndex != nodeBGlobalIndex);
81 const c_vector<double, SPACE_DIM>& r_node_a_location = p_node_a->
rGetLocation();
82 const c_vector<double, SPACE_DIM>& r_node_b_location = p_node_b->
rGetLocation();
85 double node_a_radius = 0.0;
86 double node_b_radius = 0.0;
95 c_vector<double, SPACE_DIM> unit_difference;
102 unit_difference = rCellPopulation.
rGetMesh().GetVectorFromAtoB(r_node_a_location, r_node_b_location);
105 double distance_between_nodes = norm_2(unit_difference);
106 assert(distance_between_nodes > 0);
107 assert(!std::isnan(distance_between_nodes));
109 unit_difference /= distance_between_nodes;
115 if (this->mUseCutOffLength)
117 if (distance_between_nodes >= this->GetCutOffLength())
119 return zero_vector<double>(SPACE_DIM);
127 double rest_length_final = 1.0;
135 assert(node_a_radius > 0 && node_b_radius > 0);
136 rest_length_final = node_a_radius+node_b_radius;
139 double rest_length = rest_length_final;
144 double ageA = p_cell_A->GetAge();
145 double ageB = p_cell_B->GetAge();
147 assert(!std::isnan(ageA));
148 assert(!std::isnan(ageB));
154 if (ageA < mMeinekeSpringGrowthDuration && ageB < mMeinekeSpringGrowthDuration)
158 std::pair<CellPtr,CellPtr> cell_pair = p_static_cast_cell_population->
CreateCellPair(p_cell_A, p_cell_B);
163 double lambda = mMeinekeDivisionRestingSpringLength;
164 rest_length = lambda + (rest_length_final - lambda) * ageA/mMeinekeSpringGrowthDuration;
176 double a_rest_length = rest_length*0.5;
177 double b_rest_length = a_rest_length;
181 assert(node_a_radius > 0 && node_b_radius > 0);
182 a_rest_length = (node_a_radius/(node_a_radius+node_b_radius))*rest_length;
183 b_rest_length = (node_b_radius/(node_a_radius+node_b_radius))*rest_length;
190 if (p_cell_A->HasApoptosisBegun())
192 double time_until_death_a = p_cell_A->GetTimeUntilDeath();
193 a_rest_length = a_rest_length * time_until_death_a / p_cell_A->GetApoptosisTime();
195 if (p_cell_B->HasApoptosisBegun())
197 double time_until_death_b = p_cell_B->GetTimeUntilDeath();
198 b_rest_length = b_rest_length * time_until_death_b / p_cell_B->GetApoptosisTime();
201 rest_length = a_rest_length + b_rest_length;
206 double overlap = distance_between_nodes - rest_length;
207 bool is_closer_than_rest_length = (overlap <= 0);
208 double multiplication_factor = VariableSpringConstantMultiplicationFactor(nodeAGlobalIndex, nodeBGlobalIndex, rCellPopulation, is_closer_than_rest_length);
209 double spring_stiffness = mMeinekeSpringStiffness;
213 return multiplication_factor * spring_stiffness * unit_difference * overlap;
218 if (is_closer_than_rest_length)
221 assert(overlap > -rest_length_final);
222 c_vector<double, SPACE_DIM> temp = multiplication_factor*spring_stiffness * unit_difference * rest_length_final* log(1.0 + overlap/rest_length_final);
228 c_vector<double, SPACE_DIM> temp = multiplication_factor*spring_stiffness * unit_difference * overlap * exp(-alpha * overlap/rest_length_final);
234template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
237 return mMeinekeSpringStiffness;
240template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
243 return mMeinekeDivisionRestingSpringLength;
246template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
249 return mMeinekeSpringGrowthDuration;
252template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
255 assert(springStiffness > 0.0);
256 mMeinekeSpringStiffness = springStiffness;
259template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
262 assert(divisionRestingSpringLength <= 1.0);
263 assert(divisionRestingSpringLength >= 0.0);
265 mMeinekeDivisionRestingSpringLength = divisionRestingSpringLength;
268template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
271 assert(springGrowthDuration >= 0.0);
273 mMeinekeSpringGrowthDuration = springGrowthDuration;
276template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
279 *rParamsFile <<
"\t\t\t<MeinekeSpringStiffness>" << mMeinekeSpringStiffness <<
"</MeinekeSpringStiffness>\n";
280 *rParamsFile <<
"\t\t\t<MeinekeDivisionRestingSpringLength>" << mMeinekeDivisionRestingSpringLength <<
"</MeinekeDivisionRestingSpringLength>\n";
281 *rParamsFile <<
"\t\t\t<MeinekeSpringGrowthDuration>" << mMeinekeSpringGrowthDuration <<
"</MeinekeSpringGrowthDuration>\n";
#define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
virtual Node< SPACE_DIM > * GetNode(unsigned index)=0
virtual CellPtr GetCellUsingLocationIndex(unsigned index)
AbstractMesh< ELEMENT_DIM, SPACE_DIM > & rGetMesh()
void UnmarkSpring(std::pair< CellPtr, CellPtr > &rCellPair)
std::pair< CellPtr, CellPtr > CreateCellPair(CellPtr pCell1, CellPtr pCell2)
bool IsMarkedSpring(const std::pair< CellPtr, CellPtr > &rCellPair)
virtual void OutputForceParameters(out_stream &rParamsFile)
void SetMeinekeSpringGrowthDuration(double springGrowthDuration)
virtual double VariableSpringConstantMultiplicationFactor(unsigned nodeAGlobalIndex, unsigned nodeBGlobalIndex, AbstractCellPopulation< ELEMENT_DIM, SPACE_DIM > &rCellPopulation, bool isCloserThanRestLength)
void SetMeinekeSpringStiffness(double springStiffness)
double GetMeinekeSpringStiffness()
double GetMeinekeDivisionRestingSpringLength()
void SetMeinekeDivisionRestingSpringLength(double divisionRestingSpringLength)
virtual ~GeneralisedLinearSpringForce()
c_vector< double, SPACE_DIM > CalculateForceBetweenNodes(unsigned nodeAGlobalIndex, unsigned nodeBGlobalIndex, AbstractCellPopulation< ELEMENT_DIM, SPACE_DIM > &rCellPopulation)
double mMeinekeSpringStiffness
GeneralisedLinearSpringForce()
virtual void OutputForceParameters(out_stream &rParamsFile)
double GetMeinekeSpringGrowthDuration()
const c_vector< double, SPACE_DIM > & rGetLocation() const
double GetTimeStep() const
static SimulationTime * Instance()