36#include "AbstractVariableSizeTwoBodyInteractionForce.hpp"
38#include "AbstractCentreBasedCellPopulation.hpp"
39#include "MeshBasedCellPopulation.hpp"
40#include "NodeBasedCellPopulation.hpp"
42template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
45 mSpringStiffness(15.0),
46 mDivisionRestingSpringLength(0.5),
47 mSpringGrowthDuration(1.0)
49 if constexpr (SPACE_DIM == 1)
55template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
60template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
62 unsigned nodeAGlobalIndex,
63 unsigned nodeBGlobalIndex,
65 bool isCloserThanRestLength)
70template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
72 unsigned nodeAGlobalIndex,
73 unsigned nodeBGlobalIndex,
77 assert(nodeAGlobalIndex != nodeBGlobalIndex);
83 const c_vector<double, SPACE_DIM>& r_node_a_location = p_node_a->
rGetLocation();
84 const c_vector<double, SPACE_DIM>& r_node_b_location = p_node_b->
rGetLocation();
87 double node_a_radius = 0.0;
88 double node_b_radius = 0.0;
97 c_vector<double, SPACE_DIM> unit_difference;
104 unit_difference = rCellPopulation.
rGetMesh().GetVectorFromAtoB(r_node_a_location, r_node_b_location);
107 double distance_between_nodes = norm_2(unit_difference);
108 assert(distance_between_nodes > 0);
109 assert(!std::isnan(distance_between_nodes));
111 unit_difference /= distance_between_nodes;
117 if (this->mUseCutOffLength)
119 if (distance_between_nodes >= this->GetCutOffLength())
121 return zero_vector<double>(SPACE_DIM);
129 double rest_length_final = 1.0;
137 assert(node_a_radius > 0 && node_b_radius > 0);
138 rest_length_final = node_a_radius + node_b_radius;
141 double rest_length = rest_length_final;
146 double ageA = p_cell_A->GetAge();
147 double ageB = p_cell_B->GetAge();
149 assert(!std::isnan(ageA));
150 assert(!std::isnan(ageB));
156 if (ageA < mSpringGrowthDuration && ageB < mSpringGrowthDuration)
160 std::pair<CellPtr,CellPtr> cell_pair = p_static_cast_cell_population->
CreateCellPair(p_cell_A, p_cell_B);
165 double lambda = mDivisionRestingSpringLength;
166 rest_length = lambda + (rest_length_final - lambda) * ageA/mSpringGrowthDuration;
178 double a_rest_length = rest_length*0.5;
179 double b_rest_length = a_rest_length;
183 assert(node_a_radius > 0 && node_b_radius > 0);
184 a_rest_length = (node_a_radius/(node_a_radius+node_b_radius))*rest_length;
185 b_rest_length = (node_b_radius/(node_a_radius+node_b_radius))*rest_length;
192 if (p_cell_A->HasApoptosisBegun())
194 double time_until_death_a = p_cell_A->GetTimeUntilDeath();
195 a_rest_length = a_rest_length * time_until_death_a / p_cell_A->GetApoptosisTime();
197 if (p_cell_B->HasApoptosisBegun())
199 double time_until_death_b = p_cell_B->GetTimeUntilDeath();
200 b_rest_length = b_rest_length * time_until_death_b / p_cell_B->GetApoptosisTime();
203 rest_length = a_rest_length + b_rest_length;
205 double overlap = distance_between_nodes - rest_length;
206 bool is_closer_than_rest_length = (overlap <= 0);
207 double multiplication_factor = VariableSpringConstantMultiplicationFactor(nodeAGlobalIndex,
210 is_closer_than_rest_length);
213 return CalculateLinkInteraction(overlap, rest_length_final, unit_difference, multiplication_factor);
216template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
219 return mSpringStiffness;
222template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
225 return mDivisionRestingSpringLength;
228template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
231 return mSpringGrowthDuration;
234template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
237 assert(springStiffness > 0.0);
238 mSpringStiffness = springStiffness;
241template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
244 assert(divisionRestingSpringLength <= 1.0);
245 assert(divisionRestingSpringLength >= 0.0);
247 mDivisionRestingSpringLength = divisionRestingSpringLength;
250template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
253 assert(springGrowthDuration >= 0.0);
255 mSpringGrowthDuration = springGrowthDuration;
258template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
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 SetDivisionRestingSpringLength(double divisionRestingSpringLength)
double GetSpringGrowthDuration()
c_vector< double, SPACE_DIM > CalculateForceBetweenNodes(unsigned nodeAGlobalIndex, unsigned nodeBGlobalIndex, AbstractCellPopulation< ELEMENT_DIM, SPACE_DIM > &rCellPopulation)
void SetSpringGrowthDuration(double springGrowthDuration)
void SetSpringStiffness(double springStiffness)
AbstractVariableSizeTwoBodyInteractionForce()
virtual ~AbstractVariableSizeTwoBodyInteractionForce()
virtual void OutputForceParameters(out_stream &rParamsFile)
virtual double VariableSpringConstantMultiplicationFactor(unsigned nodeAGlobalIndex, unsigned nodeBGlobalIndex, AbstractCellPopulation< ELEMENT_DIM, SPACE_DIM > &rCellPopulation, bool isCloserThanRestLength)
double GetSpringStiffness()
double GetDivisionRestingSpringLength()
const c_vector< double, SPACE_DIM > & rGetLocation() const
double GetTimeStep() const
static SimulationTime * Instance()