Chaste Release::3.1
|
00001 /* 00002 00003 Copyright (c) 2005-2012, University of Oxford. 00004 All rights reserved. 00005 00006 University of Oxford means the Chancellor, Masters and Scholars of the 00007 University of Oxford, having an administrative office at Wellington 00008 Square, Oxford OX1 2JD, UK. 00009 00010 This file is part of Chaste. 00011 00012 Redistribution and use in source and binary forms, with or without 00013 modification, are permitted provided that the following conditions are met: 00014 * Redistributions of source code must retain the above copyright notice, 00015 this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright notice, 00017 this list of conditions and the following disclaimer in the documentation 00018 and/or other materials provided with the distribution. 00019 * Neither the name of the University of Oxford nor the names of its 00020 contributors may be used to endorse or promote products derived from this 00021 software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 */ 00035 00036 #include "LinearSpringWithVariableSpringConstantsForce.hpp" 00037 #include "MeshBasedCellPopulation.hpp" 00038 #include "VanLeeuwen2009WntSwatCellCycleModelHypothesisOne.hpp" 00039 #include "VanLeeuwen2009WntSwatCellCycleModelHypothesisTwo.hpp" 00040 #include "ApoptoticCellProperty.hpp" 00041 00042 template<unsigned DIM> 00043 LinearSpringWithVariableSpringConstantsForce<DIM>::LinearSpringWithVariableSpringConstantsForce() 00044 : GeneralisedLinearSpringForce<DIM>(), 00045 mUseEdgeBasedSpringConstant(false), 00046 mUseMutantSprings(false), 00047 mMutantMutantMultiplier(DOUBLE_UNSET), 00048 mNormalMutantMultiplier(DOUBLE_UNSET), 00049 mUseBCatSprings(false), 00050 mUseApoptoticSprings(false), 00051 mBetaCatSpringScaler(18.14/6.0), // scale spring constant with beta-catenin level (divided by 6 for heaxagonal cells) 00052 mApoptoticSpringTensionStiffness(15.0*0.25), 00053 mApoptoticSpringCompressionStiffness(15.0*0.75) 00054 { 00055 } 00056 00057 template<unsigned DIM> 00058 LinearSpringWithVariableSpringConstantsForce<DIM>::~LinearSpringWithVariableSpringConstantsForce() 00059 { 00060 } 00061 00062 template<unsigned DIM> 00063 void LinearSpringWithVariableSpringConstantsForce<DIM>::SetEdgeBasedSpringConstant(bool useEdgeBasedSpringConstant) 00064 { 00065 assert(DIM == 2); 00066 mUseEdgeBasedSpringConstant = useEdgeBasedSpringConstant; 00067 } 00068 00069 template<unsigned DIM> 00070 void LinearSpringWithVariableSpringConstantsForce<DIM>::SetMutantSprings(bool useMutantSprings, double mutantMutantMultiplier, double normalMutantMultiplier) 00071 { 00072 mUseMutantSprings = useMutantSprings; 00073 mMutantMutantMultiplier = mutantMutantMultiplier; 00074 mNormalMutantMultiplier = normalMutantMultiplier; 00075 } 00076 00077 template<unsigned DIM> 00078 void LinearSpringWithVariableSpringConstantsForce<DIM>::SetBetaCateninSprings(bool useBCatSprings) 00079 { 00080 mUseBCatSprings = useBCatSprings; 00081 } 00082 00083 template<unsigned DIM> 00084 void LinearSpringWithVariableSpringConstantsForce<DIM>::SetApoptoticSprings(bool useApoptoticSprings) 00085 { 00086 mUseApoptoticSprings = useApoptoticSprings; 00087 } 00088 00089 template<unsigned DIM> 00090 double LinearSpringWithVariableSpringConstantsForce<DIM>::VariableSpringConstantMultiplicationFactor( 00091 unsigned nodeAGlobalIndex, 00092 unsigned nodeBGlobalIndex, 00093 AbstractCellPopulation<DIM>& rCellPopulation, 00094 bool isCloserThanRestLength) 00095 { 00096 00097 double multiplication_factor = GeneralisedLinearSpringForce<DIM>::VariableSpringConstantMultiplicationFactor(nodeAGlobalIndex, 00098 nodeBGlobalIndex, 00099 rCellPopulation, 00100 isCloserThanRestLength); 00101 00102 CellPtr p_cell_A = rCellPopulation.GetCellUsingLocationIndex(nodeAGlobalIndex); 00103 CellPtr p_cell_B = rCellPopulation.GetCellUsingLocationIndex(nodeBGlobalIndex); 00104 00105 if (mUseEdgeBasedSpringConstant) 00106 { 00107 assert(dynamic_cast<MeshBasedCellPopulation<DIM>*>(&rCellPopulation)); 00108 assert(!mUseBCatSprings); // don't want to do both (both account for edge length) 00109 00110 multiplication_factor = (static_cast<MeshBasedCellPopulation<DIM>*>(&rCellPopulation))->GetVoronoiEdgeLength(nodeAGlobalIndex, nodeBGlobalIndex)*sqrt(3); 00111 } 00112 00113 if (mUseMutantSprings) 00114 { 00115 unsigned number_of_mutants = 0; 00116 00117 if (p_cell_A->GetMutationState()->IsType<ApcTwoHitCellMutationState>() || p_cell_A->GetMutationState()->IsType<BetaCateninOneHitCellMutationState>()) 00118 { 00119 // If cell A is mutant 00120 number_of_mutants++; 00121 } 00122 00123 if (p_cell_B->GetMutationState()->IsType<ApcTwoHitCellMutationState>() || p_cell_B->GetMutationState()->IsType<BetaCateninOneHitCellMutationState>()) 00124 { 00125 // If cell B is mutant 00126 number_of_mutants++; 00127 } 00128 00129 switch (number_of_mutants) 00130 { 00131 case 1u: 00132 { 00133 multiplication_factor *= mNormalMutantMultiplier; 00134 break; 00135 } 00136 case 2u: 00137 { 00138 multiplication_factor *= mMutantMutantMultiplier; 00139 break; 00140 } 00141 } 00142 } 00143 00144 if (mUseBCatSprings) 00145 { 00146 assert(dynamic_cast<MeshBasedCellPopulation<DIM>*>(&rCellPopulation)); 00147 00148 // If using beta-cat dependent springs, both cell-cycle models had better be VanLeeuwen2009WntSwatCellCycleModel 00149 AbstractVanLeeuwen2009WntSwatCellCycleModel* p_model_A = dynamic_cast<AbstractVanLeeuwen2009WntSwatCellCycleModel*>(p_cell_A->GetCellCycleModel()); 00150 AbstractVanLeeuwen2009WntSwatCellCycleModel* p_model_B = dynamic_cast<AbstractVanLeeuwen2009WntSwatCellCycleModel*>(p_cell_B->GetCellCycleModel()); 00151 00152 assert(!mUseEdgeBasedSpringConstant); // This already adapts for edge lengths - don't want to do it twice. 00153 double beta_cat_cell_1 = p_model_A->GetMembraneBoundBetaCateninLevel(); 00154 double beta_cat_cell_2 = p_model_B->GetMembraneBoundBetaCateninLevel(); 00155 00156 MeshBasedCellPopulation<DIM>* p_static_cast_cell_population = (static_cast<MeshBasedCellPopulation<DIM>*>(&rCellPopulation)); 00157 00158 double perim_cell_1 = p_static_cast_cell_population->GetSurfaceAreaOfVoronoiElement(nodeAGlobalIndex); 00159 double perim_cell_2 = p_static_cast_cell_population->GetSurfaceAreaOfVoronoiElement(nodeBGlobalIndex); 00160 double edge_length_between_1_and_2 = p_static_cast_cell_population->GetVoronoiEdgeLength(nodeAGlobalIndex, nodeBGlobalIndex); 00161 00162 double beta_cat_on_cell_1_edge = beta_cat_cell_1 * edge_length_between_1_and_2 / perim_cell_1; 00163 double beta_cat_on_cell_2_edge = beta_cat_cell_2 * edge_length_between_1_and_2 / perim_cell_2; 00164 00165 double min_beta_Cat_of_two_cells = std::min(beta_cat_on_cell_1_edge, beta_cat_on_cell_2_edge); 00166 00167 multiplication_factor *= min_beta_Cat_of_two_cells / mBetaCatSpringScaler; 00168 } 00169 00170 if (mUseApoptoticSprings) 00171 { 00172 bool cell_A_is_apoptotic = p_cell_A->HasCellProperty<ApoptoticCellProperty>(); 00173 bool cell_B_is_apoptotic = p_cell_B->HasCellProperty<ApoptoticCellProperty>(); 00174 00175 if (cell_A_is_apoptotic || cell_B_is_apoptotic) 00176 { 00177 double spring_a_stiffness = 2.0 * this->GetMeinekeSpringStiffness(); 00178 double spring_b_stiffness = 2.0 * this->GetMeinekeSpringStiffness(); 00179 00180 if (cell_A_is_apoptotic) 00181 { 00182 if (!isCloserThanRestLength) // if under tension 00183 { 00184 spring_a_stiffness = mApoptoticSpringTensionStiffness; 00185 } 00186 else // if under compression 00187 { 00188 spring_a_stiffness = mApoptoticSpringCompressionStiffness; 00189 } 00190 } 00191 if (cell_B_is_apoptotic) 00192 { 00193 if (!isCloserThanRestLength) // if under tension 00194 { 00195 spring_b_stiffness = mApoptoticSpringTensionStiffness; 00196 } 00197 else // if under compression 00198 { 00199 spring_b_stiffness = mApoptoticSpringCompressionStiffness; 00200 } 00201 } 00202 00203 multiplication_factor /= (1.0/spring_a_stiffness + 1.0/spring_b_stiffness)*this->GetMeinekeSpringStiffness(); 00204 } 00205 } 00206 00207 return multiplication_factor; 00208 } 00209 00210 template<unsigned DIM> 00211 void LinearSpringWithVariableSpringConstantsForce<DIM>::AddForceContribution(std::vector<c_vector<double, DIM> >& rForces, 00212 AbstractCellPopulation<DIM>& rCellPopulation) 00213 { 00214 // Throw an exception message if not using a MeshBasedCellPopulation 00215 if (dynamic_cast<MeshBasedCellPopulation<DIM>*>(&rCellPopulation) == NULL) 00216 { 00217 EXCEPTION("LinearSpringWithVariableSpringConstantsForce is to be used with a subclass of MeshBasedCellPopulation only"); 00218 } 00219 00220 MeshBasedCellPopulation<DIM>* p_static_cast_cell_population = static_cast<MeshBasedCellPopulation<DIM>*>(&rCellPopulation); 00221 00222 for (typename MeshBasedCellPopulation<DIM>::SpringIterator spring_iterator = p_static_cast_cell_population->SpringsBegin(); 00223 spring_iterator != p_static_cast_cell_population->SpringsEnd(); 00224 ++spring_iterator) 00225 { 00226 unsigned nodeA_global_index = spring_iterator.GetNodeA()->GetIndex(); 00227 unsigned nodeB_global_index = spring_iterator.GetNodeB()->GetIndex(); 00228 00229 c_vector<double, DIM> force = CalculateForceBetweenNodes(nodeA_global_index, nodeB_global_index, rCellPopulation); 00230 00231 rForces[nodeB_global_index] -= force; 00232 rForces[nodeA_global_index] += force; 00233 } 00234 } 00235 00236 template<unsigned DIM> 00237 double LinearSpringWithVariableSpringConstantsForce<DIM>::GetBetaCatSpringScaler() 00238 { 00239 return mBetaCatSpringScaler; 00240 } 00241 00242 template<unsigned DIM> 00243 void LinearSpringWithVariableSpringConstantsForce<DIM>::SetBetaCatSpringScaler(double betaCatSpringScaler) 00244 { 00245 assert(betaCatSpringScaler > 0.0); 00246 mBetaCatSpringScaler = betaCatSpringScaler; 00247 } 00248 00249 template<unsigned DIM> 00250 double LinearSpringWithVariableSpringConstantsForce<DIM>::GetApoptoticSpringTensionStiffness() 00251 { 00252 return mApoptoticSpringTensionStiffness; 00253 } 00254 00255 template<unsigned DIM> 00256 void LinearSpringWithVariableSpringConstantsForce<DIM>::SetApoptoticSpringTensionStiffness(double apoptoticSpringTensionStiffness) 00257 { 00258 assert(apoptoticSpringTensionStiffness >= 0.0); 00259 mApoptoticSpringTensionStiffness = apoptoticSpringTensionStiffness; 00260 } 00261 00262 template<unsigned DIM> 00263 double LinearSpringWithVariableSpringConstantsForce<DIM>::GetApoptoticSpringCompressionStiffness() 00264 { 00265 return mApoptoticSpringCompressionStiffness; 00266 } 00267 00268 template<unsigned DIM> 00269 void LinearSpringWithVariableSpringConstantsForce<DIM>::SetApoptoticSpringCompressionStiffness(double apoptoticSpringCompressionStiffness) 00270 { 00271 assert(apoptoticSpringCompressionStiffness >= 0.0); 00272 mApoptoticSpringCompressionStiffness = apoptoticSpringCompressionStiffness; 00273 } 00274 00275 template<unsigned DIM> 00276 void LinearSpringWithVariableSpringConstantsForce<DIM>::OutputForceParameters(out_stream& rParamsFile) 00277 { 00278 *rParamsFile << "\t\t\t<UseEdgeBasedSpringConstant>" << mUseEdgeBasedSpringConstant << "</UseEdgeBasedSpringConstant>\n"; 00279 *rParamsFile << "\t\t\t<UseMutantSprings>" << mUseMutantSprings << "</UseMutantSprings>\n"; 00280 *rParamsFile << "\t\t\t<MutantMutantMultiplier>" << mMutantMutantMultiplier << "</MutantMutantMultiplier>\n"; 00281 *rParamsFile << "\t\t\t<NormalMutantMultiplier>" << mNormalMutantMultiplier << "</NormalMutantMultiplier>\n"; 00282 *rParamsFile << "\t\t\t<UseBCatSprings>" << mUseBCatSprings << "</UseBCatSprings>\n"; 00283 *rParamsFile << "\t\t\t<UseApoptoticSprings>" << mUseApoptoticSprings << "</UseApoptoticSprings>\n"; 00284 *rParamsFile << "\t\t\t<BetaCatSpringScaler>" << mBetaCatSpringScaler << "</BetaCatSpringScaler>\n"; 00285 *rParamsFile << "\t\t\t<ApoptoticSpringTensionStiffness>" << mApoptoticSpringTensionStiffness << "</ApoptoticSpringTensionStiffness>\n"; 00286 *rParamsFile << "\t\t\t<ApoptoticSpringCompressionStiffness>" << mApoptoticSpringCompressionStiffness << "</ApoptoticSpringCompressionStiffness>\n"; 00287 00288 // Call method on direct parent class 00289 GeneralisedLinearSpringForce<DIM>::OutputForceParameters(rParamsFile); 00290 } 00291 00293 // Explicit instantiation 00295 00296 template class LinearSpringWithVariableSpringConstantsForce<1>; 00297 template class LinearSpringWithVariableSpringConstantsForce<2>; 00298 template class LinearSpringWithVariableSpringConstantsForce<3>; 00299 00300 00301 // Serialization for Boost >= 1.36 00302 #include "SerializationExportWrapperForCpp.hpp" 00303 EXPORT_TEMPLATE_CLASS_SAME_DIMS(LinearSpringWithVariableSpringConstantsForce)