Chaste  Release::2018.1
WntConcentration.cpp
1 /*
2 
3 Copyright (c) 2005-2018, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 #include "WntConcentration.hpp"
36 
38 template<unsigned DIM>
40 
41 template<unsigned DIM>
43 {
44  if (mpInstance == nullptr)
45  {
46  mpInstance = new WntConcentration;
47  }
48  return mpInstance;
49 }
50 
51 template<unsigned DIM>
53  : mCryptLength(DOUBLE_UNSET),
54  mLengthSet(false),
55  mWntType(NONE),
56  mpCellPopulation(nullptr),
57  mTypeSet(false),
58  mConstantWntValueForTesting(0),
59  mUseConstantWntValueForTesting(false),
60  mWntConcentrationParameter(1.0),
61  mCryptProjectionParameterA(0.5),
62  mCryptProjectionParameterB(2.0)
63 {
64  // Make sure there's only one instance - enforces correct serialization
65  assert(mpInstance == nullptr);
66 }
67 
68 template<unsigned DIM>
70 {
71 }
72 
73 template<unsigned DIM>
75 {
76  if (mpInstance)
77  {
78  delete mpInstance;
79  mpInstance = nullptr;
80  }
81 }
82 
83 template<unsigned DIM>
85 {
86  if (mUseConstantWntValueForTesting) // to test a cell and cell-cycle models without a cell population
87  {
88  return mConstantWntValueForTesting;
89  }
90 
91  assert(mpCellPopulation!=nullptr);
92  assert(mTypeSet);
93  assert(mLengthSet);
94 
95  double height;
96 
97  if (mWntType == RADIAL)
98  {
99  double a = GetCryptProjectionParameterA();
100  double b = GetCryptProjectionParameterB();
101  height = a*pow(norm_2(mpCellPopulation->GetLocationOfCellCentre(pCell)), b);
102  }
103  else
104  {
105  height = mpCellPopulation->GetLocationOfCellCentre(pCell)[DIM-1];
106  }
107 
108  return GetWntLevel(height);
109 }
110 
111 template<unsigned DIM>
112 c_vector<double, DIM> WntConcentration<DIM>::GetWntGradient(CellPtr pCell)
113 {
114  if (mUseConstantWntValueForTesting) // to test a cell and cell-cycle models without a cell population
115  {
116  return zero_vector<double>(DIM);
117  }
118  assert(mpCellPopulation!=nullptr);
119  assert(mTypeSet);
120  assert(mLengthSet);
121 
122  c_vector<double, DIM> location_of_cell = mpCellPopulation->GetLocationOfCellCentre(pCell);
123 
124  return GetWntGradient(location_of_cell);
125 }
126 
127 template<unsigned DIM>
129 {
130  mpCellPopulation = &rCellPopulation;
131 }
132 
133 template<unsigned DIM>
135 {
136  return *mpCellPopulation;
137 }
138 
139 template<unsigned DIM>
141 {
142  return mCryptLength;
143 }
144 
145 template<unsigned DIM>
147 {
148  assert(cryptLength > 0.0);
149  if (mLengthSet==true)
150  {
151  EXCEPTION("Destroy has not been called");
152  }
153 
154  mCryptLength = cryptLength;
155  mLengthSet = true;
156 }
157 
158 template<unsigned DIM>
159 WntConcentrationType WntConcentration<DIM>::GetType()
160 {
161  return mWntType;
162 }
163 
164 template<unsigned DIM>
165 void WntConcentration<DIM>::SetType(WntConcentrationType type)
166 {
167  if (mTypeSet==true)
168  {
169  EXCEPTION("Destroy has not been called");
170  }
171  mWntType = type;
172  mTypeSet = true;
173 }
174 
175 template<unsigned DIM>
177 {
178  if (mWntType == NONE)
179  {
180  return 0.0;
181  }
182 
183  // Need to call SetCryptLength first
184  assert(mLengthSet);
185 
186  double wnt_level = -1.0; // Test this is changed before leaving method.
187 
188  // The first type of Wnt concentration to try
189  if (mWntType==LINEAR || mWntType==RADIAL)
190  {
191  if ((height >= -1e-9) && (height < mWntConcentrationParameter*GetCryptLength()))
192  {
193  wnt_level = 1.0 - height/(mWntConcentrationParameter*GetCryptLength());
194  }
195  else
196  {
197  wnt_level = 0.0;
198  }
199  }
200 
201  if (mWntType==EXPONENTIAL)
202  {
203  if ((height >= -1e-9) && (height < GetCryptLength()))
204  {
205  wnt_level = exp(-height/(GetCryptLength()*mWntConcentrationParameter));
206  }
207  else
208  {
209  wnt_level = 0.0;
210  }
211  }
212 
213  assert(wnt_level >= 0.0);
214 
215  return wnt_level;
216 }
217 
218 template<unsigned DIM>
219 c_vector<double, DIM> WntConcentration<DIM>::GetWntGradient(c_vector<double, DIM>& rLocation)
220 {
221  c_vector<double, DIM> wnt_gradient = zero_vector<double>(DIM);
222 
223  if (mWntType!=NONE)
224  {
225  if (mWntType==LINEAR)
226  {
227  if ((rLocation[DIM-1] >= -1e-9) && (rLocation[DIM-1] < mWntConcentrationParameter*GetCryptLength()))
228  {
229  wnt_gradient[DIM-1] = -1.0/(mWntConcentrationParameter*GetCryptLength());
230  }
231  }
232  else if (mWntType==RADIAL) // RADIAL Wnt concentration
233  {
234  double a = GetCryptProjectionParameterA();
235  double b = GetCryptProjectionParameterB();
236  double r = norm_2(rLocation);
237  double r_critical = pow(mWntConcentrationParameter*GetCryptLength()/a, 1.0/b);
238 
239  double dwdr = 0.0;
240 
241  if (r>=-1e-9 && r<r_critical)
242  {
243  dwdr = -mWntConcentrationParameter*GetCryptLength()*pow(r, b-1.0)/a;
244  }
245 
246  for (unsigned i=0; i<DIM; i++)
247  {
248  wnt_gradient[i] = rLocation[i]*dwdr/r;
249  }
250  }
251  else
252  {
253  EXCEPTION("No method to calculate gradient of this Wnt type");
254  }
255  }
256  return wnt_gradient;
257 }
258 
259 template<unsigned DIM>
261 {
262  bool result = false;
263  if (mTypeSet && mLengthSet && mpCellPopulation!=nullptr && mWntType!=NONE)
264  {
265  result = true;
266  }
267  return result;
268 }
269 
270 template<unsigned DIM>
272 {
273  if (value < 0)
274  {
275  EXCEPTION("WntConcentration<DIM>::SetConstantWntValueForTesting - Wnt value for testing should be non-negative.\n");
276  }
277  mConstantWntValueForTesting = value;
278  mUseConstantWntValueForTesting = true;
279  if (!mTypeSet)
280  {
281  mWntType = NONE;
282  }
283 }
284 
285 template<unsigned DIM>
287 {
288  return mWntConcentrationParameter;
289 }
290 
291 template<unsigned DIM>
292 void WntConcentration<DIM>::SetWntConcentrationParameter(double wntConcentrationParameter)
293 {
294  assert(wntConcentrationParameter > 0.0);
295  mWntConcentrationParameter = wntConcentrationParameter;
296 }
297 
298 template<unsigned DIM>
300 {
301  return mCryptProjectionParameterA;
302 }
303 
304 template<unsigned DIM>
306 {
307  return mCryptProjectionParameterB;
308 }
309 
310 template<unsigned DIM>
311 void WntConcentration<DIM>::SetCryptProjectionParameterA(double cryptProjectionParameterA)
312 {
313  assert(cryptProjectionParameterA >= 0.0);
314  mCryptProjectionParameterA = cryptProjectionParameterA;
315 }
316 
317 template<unsigned DIM>
318 void WntConcentration<DIM>::SetCryptProjectionParameterB(double cryptProjectionParameterB)
319 {
320  assert(cryptProjectionParameterB >= 0.0);
321  mCryptProjectionParameterB = cryptProjectionParameterB;
322 }
323 
324 // Explicit instantiation
325 template class WntConcentration<1>;
326 template class WntConcentration<2>;
327 template class WntConcentration<3>;
double GetWntLevel(double height)
static void Destroy()
double GetWntConcentrationParameter()
#define EXCEPTION(message)
Definition: Exception.hpp:143
double GetCryptProjectionParameterB()
WntConcentrationType GetType()
const double DOUBLE_UNSET
Definition: Exception.hpp:56
void SetType(WntConcentrationType type)
void SetCellPopulation(AbstractCellPopulation< DIM > &rCellPopulation)
virtual ~WntConcentration()
static WntConcentration * Instance()
c_vector< double, DIM > GetWntGradient(c_vector< double, DIM > &rLocation)
void SetCryptLength(double cryptLength)
void SetConstantWntValueForTesting(double value)
static WntConcentration * mpInstance
AbstractCellPopulation< DIM > & rGetCellPopulation()
void SetCryptProjectionParameterA(double cryptProjectionParameterA)
void SetCryptProjectionParameterB(double cryptProjectionParameterB)
double GetCryptProjectionParameterA()
void SetWntConcentrationParameter(double wntConcentrationParameter)