Chaste Release::3.1
WntConcentration.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 #include "WntConcentration.hpp"
00036 
00038 template<unsigned DIM>
00039 WntConcentration<DIM>* WntConcentration<DIM>::mpInstance = NULL;
00040 
00041 template<unsigned DIM>
00042 WntConcentration<DIM>* WntConcentration<DIM>::Instance()
00043 {
00044     if (mpInstance == NULL)
00045     {
00046         mpInstance = new WntConcentration;
00047     }
00048     return mpInstance;
00049 }
00050 
00051 template<unsigned DIM>
00052 WntConcentration<DIM>::WntConcentration()
00053     : mCryptLength(DOUBLE_UNSET),
00054       mLengthSet(false),
00055       mWntType(NONE),
00056       mpCellPopulation(NULL),
00057       mTypeSet(false),
00058       mConstantWntValueForTesting(0),
00059       mUseConstantWntValueForTesting(false),
00060       mWntConcentrationParameter(1.0),
00061       mCryptProjectionParameterA(0.5),
00062       mCryptProjectionParameterB(2.0)
00063 {
00064     // Make sure there's only one instance - enforces correct serialization
00065     assert(mpInstance == NULL);
00066 }
00067 
00068 template<unsigned DIM>
00069 WntConcentration<DIM>::~WntConcentration()
00070 {
00071 }
00072 
00073 template<unsigned DIM>
00074 void WntConcentration<DIM>::Destroy()
00075 {
00076     if (mpInstance)
00077     {
00078         delete mpInstance;
00079         mpInstance = NULL;
00080     }
00081 }
00082 
00083 template<unsigned DIM>
00084 double WntConcentration<DIM>::GetWntLevel(CellPtr pCell)
00085 {
00086     if (mUseConstantWntValueForTesting)  // to test a cell and cell-cycle models without a cell population
00087     {
00088         return mConstantWntValueForTesting;
00089     }
00090 
00091     assert(mpCellPopulation!=NULL);
00092     assert(mTypeSet);
00093     assert(mLengthSet);
00094 
00095     double height;
00096 
00097     if (mWntType == RADIAL)
00098     {
00099         double a = GetCryptProjectionParameterA();
00100         double b = GetCryptProjectionParameterB();
00101         height = a*pow(norm_2(mpCellPopulation->GetLocationOfCellCentre(pCell)), b);
00102     }
00103     else
00104     {
00105         height = mpCellPopulation->GetLocationOfCellCentre(pCell)[DIM-1];
00106     }
00107 
00108     return GetWntLevel(height);
00109 }
00110 
00111 template<unsigned DIM>
00112 c_vector<double, DIM> WntConcentration<DIM>::GetWntGradient(CellPtr pCell)
00113 {
00114     if (mUseConstantWntValueForTesting)  // to test a cell and cell-cycle models without a cell population
00115     {
00116         return zero_vector<double>(DIM);
00117     }
00118     assert(mpCellPopulation!=NULL);
00119     assert(mTypeSet);
00120     assert(mLengthSet);
00121 
00122     c_vector<double, DIM> location_of_cell = mpCellPopulation->GetLocationOfCellCentre(pCell);
00123 
00124     return GetWntGradient(location_of_cell);
00125 }
00126 
00127 template<unsigned DIM>
00128 void WntConcentration<DIM>::SetCellPopulation(AbstractCellPopulation<DIM>& rCellPopulation)
00129 {
00130     mpCellPopulation = &rCellPopulation;
00131 }
00132 
00133 template<unsigned DIM>
00134 AbstractCellPopulation<DIM>& WntConcentration<DIM>::rGetCellPopulation()
00135 {
00136     return *mpCellPopulation;
00137 }
00138 
00139 template<unsigned DIM>
00140 double WntConcentration<DIM>::GetCryptLength()
00141 {
00142     return mCryptLength;
00143 }
00144 
00145 template<unsigned DIM>
00146 void WntConcentration<DIM>::SetCryptLength(double cryptLength)
00147 {
00148     assert(cryptLength > 0.0);
00149     if (mLengthSet==true)
00150     {
00151         EXCEPTION("Destroy has not been called");
00152     }
00153 
00154     mCryptLength = cryptLength;
00155     mLengthSet = true;
00156 }
00157 
00158 template<unsigned DIM>
00159 WntConcentrationType WntConcentration<DIM>::GetType()
00160 {
00161     return mWntType;
00162 }
00163 
00164 template<unsigned DIM>
00165 void WntConcentration<DIM>::SetType(WntConcentrationType type)
00166 {
00167     if (mTypeSet==true)
00168     {
00169         EXCEPTION("Destroy has not been called");
00170     }
00171     mWntType = type;
00172     mTypeSet = true;
00173 }
00174 
00175 template<unsigned DIM>
00176 double WntConcentration<DIM>::GetWntLevel(double height)
00177 {
00178     if (mWntType == NONE)
00179     {
00180         return 0.0;
00181     }
00182 
00183     // Need to call SetCryptLength first
00184     assert(mLengthSet);
00185 
00186     double wnt_level = -1.0; // Test this is changed before leaving method.
00187 
00188     // The first type of Wnt concentration to try
00189     if (mWntType==LINEAR || mWntType==RADIAL)
00190     {
00191         if ((height >= -1e-9) && (height < mWntConcentrationParameter*GetCryptLength()))
00192         {
00193             wnt_level = 1.0 - height/(mWntConcentrationParameter*GetCryptLength());
00194         }
00195         else
00196         {
00197             wnt_level = 0.0;
00198         }
00199     }
00200 
00201     if (mWntType==EXPONENTIAL)
00202     {
00203         if ((height >= -1e-9) && (height < GetCryptLength()))
00204         {
00205             wnt_level = exp(-height/(GetCryptLength()*mWntConcentrationParameter));
00206         }
00207         else
00208         {
00209             wnt_level = 0.0;
00210         }
00211     }
00212 
00213     assert(wnt_level >= 0.0);
00214 
00215     return wnt_level;
00216 }
00217 
00218 template<unsigned DIM>
00219 c_vector<double, DIM> WntConcentration<DIM>::GetWntGradient(c_vector<double, DIM>& rLocation)
00220 {
00221     c_vector<double, DIM> wnt_gradient = zero_vector<double>(DIM);
00222 
00223     if (mWntType!=NONE)
00224     {
00225         if (mWntType==LINEAR)
00226         {
00227             if ((rLocation[DIM-1] >= -1e-9) && (rLocation[DIM-1] < mWntConcentrationParameter*GetCryptLength()))
00228             {
00229                 wnt_gradient[DIM-1] = -1.0/(mWntConcentrationParameter*GetCryptLength());
00230             }
00231         }
00232         else if (mWntType==RADIAL) // RADIAL Wnt concentration
00233         {
00234             double a = GetCryptProjectionParameterA();
00235             double b = GetCryptProjectionParameterB();
00236             double r = norm_2(rLocation);
00237             double r_critical = pow(mWntConcentrationParameter*GetCryptLength()/a, 1.0/b);
00238 
00239             double dwdr = 0.0;
00240 
00241             if (r>=-1e-9 && r<r_critical)
00242             {
00243                 dwdr = -mWntConcentrationParameter*GetCryptLength()*pow(r, b-1.0)/a;
00244             }
00245 
00246             for (unsigned i=0; i<DIM; i++)
00247             {
00248                 wnt_gradient[i] = rLocation[i]*dwdr/r;
00249             }
00250         }
00251         else
00252         {
00253             EXCEPTION("No method to calculate gradient of this Wnt type");
00254         }
00255     }
00256     return wnt_gradient;
00257 }
00258 
00259 template<unsigned DIM>
00260 bool WntConcentration<DIM>::IsWntSetUp()
00261 {
00262     bool result = false;
00263     if (mTypeSet && mLengthSet && mpCellPopulation!=NULL && mWntType!=NONE)
00264     {
00265         result = true;
00266     }
00267     return result;
00268 }
00269 
00270 template<unsigned DIM>
00271 void WntConcentration<DIM>::SetConstantWntValueForTesting(double value)
00272 {
00273     if (value < 0)
00274     {
00275         EXCEPTION("WntConcentration<DIM>::SetConstantWntValueForTesting - Wnt value for testing should be non-negative.\n");
00276     }
00277     mConstantWntValueForTesting = value;
00278     mUseConstantWntValueForTesting = true;
00279     if (!mTypeSet)
00280     {
00281         mWntType = NONE;
00282     }
00283 }
00284 
00285 template<unsigned DIM>
00286 double WntConcentration<DIM>::GetWntConcentrationParameter()
00287 {
00288     return mWntConcentrationParameter;
00289 }
00290 
00291 template<unsigned DIM>
00292 void WntConcentration<DIM>::SetWntConcentrationParameter(double wntConcentrationParameter)
00293 {
00294     assert(wntConcentrationParameter > 0.0);
00295     mWntConcentrationParameter = wntConcentrationParameter;
00296 }
00297 
00298 template<unsigned DIM>
00299 double WntConcentration<DIM>::GetCryptProjectionParameterA()
00300 {
00301     return mCryptProjectionParameterA;
00302 }
00303 
00304 template<unsigned DIM>
00305 double WntConcentration<DIM>::GetCryptProjectionParameterB()
00306 {
00307     return mCryptProjectionParameterB;
00308 }
00309 
00310 template<unsigned DIM>
00311 void WntConcentration<DIM>::SetCryptProjectionParameterA(double cryptProjectionParameterA)
00312 {
00313     assert(cryptProjectionParameterA >= 0.0);
00314     mCryptProjectionParameterA = cryptProjectionParameterA;
00315 }
00316 
00317 template<unsigned DIM>
00318 void WntConcentration<DIM>::SetCryptProjectionParameterB(double cryptProjectionParameterB)
00319 {
00320     assert(cryptProjectionParameterB >= 0.0);
00321     mCryptProjectionParameterB = cryptProjectionParameterB;
00322 }
00323 
00325 // Explicit instantiation
00327 
00328 template class WntConcentration<1>;
00329 template class WntConcentration<2>;
00330 template class WntConcentration<3>;