36 #include "GeneralisedLinearSpringForce.hpp"
39 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
42 mMeinekeSpringStiffness(15.0),
43 mMeinekeDivisionRestingSpringLength(0.5),
44 mMeinekeSpringGrowthDuration(1.0)
52 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
54 unsigned nodeBGlobalIndex,
56 bool isCloserThanRestLength)
61 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
66 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
68 unsigned nodeBGlobalIndex,
72 assert(nodeAGlobalIndex != nodeBGlobalIndex);
78 c_vector<double, SPACE_DIM> node_a_location = p_node_a->
rGetLocation();
79 c_vector<double, SPACE_DIM> node_b_location = p_node_b->
rGetLocation();
82 double node_a_radius = 0.0;
83 double node_b_radius = 0.0;
92 c_vector<double, SPACE_DIM> unit_difference;
99 unit_difference = rCellPopulation.
rGetMesh().GetVectorFromAtoB(node_a_location, node_b_location);
102 double distance_between_nodes = norm_2(unit_difference);
103 assert(distance_between_nodes > 0);
104 assert(!std::isnan(distance_between_nodes));
106 unit_difference /= distance_between_nodes;
112 if (this->mUseCutOffLength)
114 if (distance_between_nodes >= this->GetCutOffLength())
116 return zero_vector<double>(SPACE_DIM);
124 double rest_length_final = 1.0;
132 assert(node_a_radius > 0 && node_b_radius > 0);
133 rest_length_final = node_a_radius+node_b_radius;
136 double rest_length = rest_length_final;
141 double ageA = p_cell_A->GetAge();
142 double ageB = p_cell_B->GetAge();
144 assert(!std::isnan(ageA));
145 assert(!std::isnan(ageB));
151 if (ageA < mMeinekeSpringGrowthDuration && ageB < mMeinekeSpringGrowthDuration)
155 std::pair<CellPtr,CellPtr> cell_pair = p_static_cast_cell_population->
CreateCellPair(p_cell_A, p_cell_B);
160 double lambda = mMeinekeDivisionRestingSpringLength;
161 rest_length = lambda + (rest_length_final - lambda) * ageA/mMeinekeSpringGrowthDuration;
173 double a_rest_length = rest_length*0.5;
174 double b_rest_length = a_rest_length;
178 assert(node_a_radius > 0 && node_b_radius > 0);
179 a_rest_length = (node_a_radius/(node_a_radius+node_b_radius))*rest_length;
180 b_rest_length = (node_b_radius/(node_a_radius+node_b_radius))*rest_length;
187 if (p_cell_A->HasApoptosisBegun())
189 double time_until_death_a = p_cell_A->GetTimeUntilDeath();
190 a_rest_length = a_rest_length * time_until_death_a / p_cell_A->GetApoptosisTime();
192 if (p_cell_B->HasApoptosisBegun())
194 double time_until_death_b = p_cell_B->GetTimeUntilDeath();
195 b_rest_length = b_rest_length * time_until_death_b / p_cell_B->GetApoptosisTime();
198 rest_length = a_rest_length + b_rest_length;
203 double overlap = distance_between_nodes - rest_length;
204 bool is_closer_than_rest_length = (overlap <= 0);
205 double multiplication_factor = VariableSpringConstantMultiplicationFactor(nodeAGlobalIndex, nodeBGlobalIndex, rCellPopulation, is_closer_than_rest_length);
206 double spring_stiffness = mMeinekeSpringStiffness;
210 return multiplication_factor * spring_stiffness * unit_difference * overlap;
215 if (is_closer_than_rest_length)
218 assert(overlap > -rest_length_final);
219 c_vector<double, SPACE_DIM> temp = multiplication_factor*spring_stiffness * unit_difference * rest_length_final* log(1.0 + overlap/rest_length_final);
225 c_vector<double, SPACE_DIM> temp = multiplication_factor*spring_stiffness * unit_difference * overlap * exp(-alpha * overlap/rest_length_final);
231 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
234 return mMeinekeSpringStiffness;
236 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
239 return mMeinekeDivisionRestingSpringLength;
241 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
244 return mMeinekeSpringGrowthDuration;
247 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
250 assert(springStiffness > 0.0);
251 mMeinekeSpringStiffness = springStiffness;
254 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
257 assert(divisionRestingSpringLength <= 1.0);
258 assert(divisionRestingSpringLength >= 0.0);
260 mMeinekeDivisionRestingSpringLength = divisionRestingSpringLength;
263 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
266 assert(springGrowthDuration >= 0.0);
268 mMeinekeSpringGrowthDuration = springGrowthDuration;
271 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
274 *rParamsFile <<
"\t\t\t<MeinekeSpringStiffness>" << mMeinekeSpringStiffness <<
"</MeinekeSpringStiffness>\n";
275 *rParamsFile <<
"\t\t\t<MeinekeDivisionRestingSpringLength>" << mMeinekeDivisionRestingSpringLength <<
"</MeinekeDivisionRestingSpringLength>\n";
276 *rParamsFile <<
"\t\t\t<MeinekeSpringGrowthDuration>" << mMeinekeSpringGrowthDuration <<
"</MeinekeSpringGrowthDuration>\n";
virtual Node< SPACE_DIM > * GetNode(unsigned index)=0
virtual void OutputForceParameters(out_stream &rParamsFile)
void UnmarkSpring(std::pair< CellPtr, CellPtr > &rCellPair)
virtual CellPtr GetCellUsingLocationIndex(unsigned index)
c_vector< double, SPACE_DIM > CalculateForceBetweenNodes(unsigned nodeAGlobalIndex, unsigned nodeBGlobalIndex, AbstractCellPopulation< ELEMENT_DIM, SPACE_DIM > &rCellPopulation)
static SimulationTime * Instance()
double GetTimeStep() const
std::pair< CellPtr, CellPtr > CreateCellPair(CellPtr pCell1, CellPtr pCell2)
double GetMeinekeSpringStiffness()
double GetMeinekeSpringGrowthDuration()
#define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
void SetMeinekeDivisionRestingSpringLength(double divisionRestingSpringLength)
bool IsMarkedSpring(const std::pair< CellPtr, CellPtr > &rCellPair)
double GetMeinekeDivisionRestingSpringLength()
void SetMeinekeSpringGrowthDuration(double springGrowthDuration)
const c_vector< double, SPACE_DIM > & rGetLocation() const
virtual double VariableSpringConstantMultiplicationFactor(unsigned nodeAGlobalIndex, unsigned nodeBGlobalIndex, AbstractCellPopulation< ELEMENT_DIM, SPACE_DIM > &rCellPopulation, bool isCloserThanRestLength)
AbstractMesh< ELEMENT_DIM, SPACE_DIM > & rGetMesh()
virtual void OutputForceParameters(out_stream &rParamsFile)
GeneralisedLinearSpringForce()
void SetMeinekeSpringStiffness(double springStiffness)
virtual ~GeneralisedLinearSpringForce()
double mMeinekeSpringStiffness