36#include "GeneralisedLinearSpringForce.hpp"
38template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
41 mMeinekeSpringStiffness(15.0),
42 mMeinekeDivisionRestingSpringLength(0.5),
43 mMeinekeSpringGrowthDuration(1.0)
51template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
53 unsigned nodeBGlobalIndex,
55 bool isCloserThanRestLength)
60template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
65template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
67 unsigned nodeBGlobalIndex,
71 assert(nodeAGlobalIndex != nodeBGlobalIndex);
77 const c_vector<double, SPACE_DIM>& r_node_a_location = p_node_a->
rGetLocation();
78 const c_vector<double, SPACE_DIM>& r_node_b_location = p_node_b->
rGetLocation();
81 double node_a_radius = 0.0;
82 double node_b_radius = 0.0;
91 c_vector<double, SPACE_DIM> unit_difference;
98 unit_difference = rCellPopulation.
rGetMesh().GetVectorFromAtoB(r_node_a_location, r_node_b_location);
101 double distance_between_nodes = norm_2(unit_difference);
102 assert(distance_between_nodes > 0);
103 assert(!std::isnan(distance_between_nodes));
105 unit_difference /= distance_between_nodes;
111 if (this->mUseCutOffLength)
113 if (distance_between_nodes >= this->GetCutOffLength())
115 return zero_vector<double>(SPACE_DIM);
123 double rest_length_final = 1.0;
131 assert(node_a_radius > 0 && node_b_radius > 0);
132 rest_length_final = node_a_radius+node_b_radius;
135 double rest_length = rest_length_final;
140 double ageA = p_cell_A->GetAge();
141 double ageB = p_cell_B->GetAge();
143 assert(!std::isnan(ageA));
144 assert(!std::isnan(ageB));
150 if (ageA < mMeinekeSpringGrowthDuration && ageB < mMeinekeSpringGrowthDuration)
154 std::pair<CellPtr,CellPtr> cell_pair = p_static_cast_cell_population->
CreateCellPair(p_cell_A, p_cell_B);
159 double lambda = mMeinekeDivisionRestingSpringLength;
160 rest_length = lambda + (rest_length_final - lambda) * ageA/mMeinekeSpringGrowthDuration;
172 double a_rest_length = rest_length*0.5;
173 double b_rest_length = a_rest_length;
177 assert(node_a_radius > 0 && node_b_radius > 0);
178 a_rest_length = (node_a_radius/(node_a_radius+node_b_radius))*rest_length;
179 b_rest_length = (node_b_radius/(node_a_radius+node_b_radius))*rest_length;
186 if (p_cell_A->HasApoptosisBegun())
188 double time_until_death_a = p_cell_A->GetTimeUntilDeath();
189 a_rest_length = a_rest_length * time_until_death_a / p_cell_A->GetApoptosisTime();
191 if (p_cell_B->HasApoptosisBegun())
193 double time_until_death_b = p_cell_B->GetTimeUntilDeath();
194 b_rest_length = b_rest_length * time_until_death_b / p_cell_B->GetApoptosisTime();
197 rest_length = a_rest_length + b_rest_length;
202 double overlap = distance_between_nodes - rest_length;
203 bool is_closer_than_rest_length = (overlap <= 0);
204 double multiplication_factor = VariableSpringConstantMultiplicationFactor(nodeAGlobalIndex, nodeBGlobalIndex, rCellPopulation, is_closer_than_rest_length);
205 double spring_stiffness = mMeinekeSpringStiffness;
209 return multiplication_factor * spring_stiffness * unit_difference * overlap;
214 if (is_closer_than_rest_length)
217 assert(overlap > -rest_length_final);
218 c_vector<double, SPACE_DIM> temp = multiplication_factor*spring_stiffness * unit_difference * rest_length_final* log(1.0 + overlap/rest_length_final);
224 c_vector<double, SPACE_DIM> temp = multiplication_factor*spring_stiffness * unit_difference * overlap * exp(-alpha * overlap/rest_length_final);
230template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
233 return mMeinekeSpringStiffness;
236template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
239 return mMeinekeDivisionRestingSpringLength;
242template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
245 return mMeinekeSpringGrowthDuration;
248template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
251 assert(springStiffness > 0.0);
252 mMeinekeSpringStiffness = springStiffness;
255template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
258 assert(divisionRestingSpringLength <= 1.0);
259 assert(divisionRestingSpringLength >= 0.0);
261 mMeinekeDivisionRestingSpringLength = divisionRestingSpringLength;
264template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
267 assert(springGrowthDuration >= 0.0);
269 mMeinekeSpringGrowthDuration = springGrowthDuration;
272template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
275 *rParamsFile <<
"\t\t\t<MeinekeSpringStiffness>" << mMeinekeSpringStiffness <<
"</MeinekeSpringStiffness>\n";
276 *rParamsFile <<
"\t\t\t<MeinekeDivisionRestingSpringLength>" << mMeinekeDivisionRestingSpringLength <<
"</MeinekeDivisionRestingSpringLength>\n";
277 *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()