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 #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>;