Chaste Release::3.1
LinearSpringWithVariableSpringConstantsForce.cpp
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)