GeneralisedLinearSpringForce.cpp
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
00029 #include "GeneralisedLinearSpringForce.hpp"
00030
00031
00032 template<unsigned DIM>
00033 GeneralisedLinearSpringForce<DIM>::GeneralisedLinearSpringForce()
00034 : AbstractTwoBodyInteractionForce<DIM>()
00035 {
00036 }
00037
00038 template<unsigned DIM>
00039 double GeneralisedLinearSpringForce<DIM>::VariableSpringConstantMultiplicationFactor(unsigned nodeAGlobalIndex,
00040 unsigned nodeBGlobalIndex,
00041 AbstractTissue<DIM>& rTissue,
00042 bool isCloserThanRestLength)
00043 {
00044 return 1.0;
00045 }
00046
00047 template<unsigned DIM>
00048 GeneralisedLinearSpringForce<DIM>::~GeneralisedLinearSpringForce()
00049 {
00050 }
00051
00052 template<unsigned DIM>
00053 c_vector<double, DIM> GeneralisedLinearSpringForce<DIM>::CalculateForceBetweenNodes(unsigned nodeAGlobalIndex,
00054 unsigned nodeBGlobalIndex,
00055 AbstractTissue<DIM>& rTissue)
00056 {
00057
00058 TissueConfig* p_config = TissueConfig::Instance();
00059
00060
00061 assert(nodeAGlobalIndex != nodeBGlobalIndex);
00062
00063
00064 c_vector<double, DIM> node_a_location = rTissue.GetNode(nodeAGlobalIndex)->rGetLocation();
00065 c_vector<double, DIM> node_b_location = rTissue.GetNode(nodeBGlobalIndex)->rGetLocation();
00066
00067
00068 c_vector<double, DIM> unit_difference;
00069 if (rTissue.HasMesh())
00070 {
00071
00072
00073
00074
00075
00076
00077 unit_difference = (static_cast<MeshBasedTissue<DIM>*>(&rTissue))->rGetMesh().GetVectorFromAtoB(node_a_location, node_b_location);
00078 }
00079 else
00080 {
00081 unit_difference = node_b_location - node_a_location;
00082 }
00083
00084
00085 double distance_between_nodes = norm_2(unit_difference);
00086 assert(distance_between_nodes > 0);
00087 assert(!std::isnan(distance_between_nodes));
00088
00089 unit_difference /= distance_between_nodes;
00090
00091
00092
00093
00094
00095 if (this->mUseCutoffPoint)
00096 {
00097 if (distance_between_nodes >= p_config->GetMechanicsCutOffLength())
00098 {
00099 return zero_vector<double>(DIM);
00100 }
00101 }
00102
00103
00104
00105 double rest_length = 1.0;
00106
00107 TissueCell& r_cell_A = rTissue.rGetCellUsingLocationIndex(nodeAGlobalIndex);
00108 TissueCell& r_cell_B = rTissue.rGetCellUsingLocationIndex(nodeBGlobalIndex);
00109
00110 double ageA = r_cell_A.GetAge();
00111 double ageB = r_cell_B.GetAge();
00112
00113 assert(!std::isnan(ageA));
00114 assert(!std::isnan(ageB));
00115
00116 double m_duration = p_config->GetMDuration();
00117
00118
00119
00120
00121
00122 if ( ageA < m_duration && ageB < m_duration )
00123 {
00124 if (rTissue.HasMesh())
00125 {
00126 MeshBasedTissue<DIM>* p_static_cast_tissue = static_cast<MeshBasedTissue<DIM>*>(&rTissue);
00127
00128 std::set<TissueCell*> cell_pair = p_static_cast_tissue->CreateCellPair(r_cell_A, r_cell_B);
00129
00130 if (p_static_cast_tissue->IsMarkedSpring(cell_pair))
00131 {
00132
00133 double lambda = p_config->GetDivisionRestingSpringLength();
00134 rest_length = lambda + (1.0 - lambda) * ageA/m_duration;
00135 }
00136 if (ageA + SimulationTime::Instance()->GetTimeStep() >= m_duration)
00137 {
00138
00139 p_static_cast_tissue->UnmarkSpring(cell_pair);
00140 }
00141 }
00142 else
00143 {
00144
00145 double lambda = p_config->GetDivisionRestingSpringLength();
00146 rest_length = lambda + (1.0 - lambda) * ageA/m_duration;
00147 }
00148 }
00149
00150 double a_rest_length = rest_length*0.5;
00151 double b_rest_length = a_rest_length;
00152
00153
00154
00155
00156
00157 if (r_cell_A.HasApoptosisBegun())
00158 {
00159 double time_until_death_a = r_cell_A.GetTimeUntilDeath();
00160 a_rest_length = a_rest_length * time_until_death_a / p_config->GetApoptosisTime();
00161 }
00162 if (r_cell_B.HasApoptosisBegun())
00163 {
00164 double time_until_death_b = r_cell_B.GetTimeUntilDeath();
00165 b_rest_length = b_rest_length * time_until_death_b / p_config->GetApoptosisTime();
00166 }
00167
00168 rest_length = a_rest_length + b_rest_length;
00169 assert(rest_length <= 1.0+1e-12);
00170
00171 bool is_closer_than_rest_length = (distance_between_nodes - rest_length <= 0);
00172
00173
00174
00175 double multiplication_factor = VariableSpringConstantMultiplicationFactor(nodeAGlobalIndex, nodeBGlobalIndex, rTissue, is_closer_than_rest_length);
00176 double spring_stiffness = p_config->GetSpringStiffness();
00177 double overlap = distance_between_nodes - rest_length;
00178
00179 if (rTissue.HasMesh())
00180 {
00181 return multiplication_factor * spring_stiffness * unit_difference * overlap;
00182 }
00183 else
00184 {
00185
00186 if (distance_between_nodes > rest_length)
00187 {
00188 double alpha = 5;
00189 c_vector<double, DIM> temp = spring_stiffness * unit_difference * overlap * exp(-alpha * overlap);
00190 for (unsigned i=0; i<DIM; i++)
00191 {
00192 assert(!std::isnan(temp[i]));
00193 }
00194 return temp;
00195 }
00196 else
00197 {
00198 c_vector<double, DIM> temp = spring_stiffness * unit_difference * log(1 + overlap);
00199 for (unsigned i=0; i<DIM; i++)
00200 {
00201 assert(!std::isnan(temp[i]));
00202 }
00203 return temp;
00204 }
00205 }
00206 }
00207
00208
00210
00212
00213 template class GeneralisedLinearSpringForce<1>;
00214 template class GeneralisedLinearSpringForce<2>;
00215 template class GeneralisedLinearSpringForce<3>;
00216
00217
00218
00219 #include "SerializationExportWrapperForCpp.hpp"
00220 EXPORT_TEMPLATE_CLASS_SAME_DIMS(GeneralisedLinearSpringForce)