Chaste Commit::1fd4e48e3990e67db148bc1bc4cf6991a0049d0c
WntConcentration.cpp
1/*
2
3Copyright (c) 2005-2024, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, 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
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35#include "WntConcentration.hpp"
36
38template<unsigned DIM>
40
41template<unsigned DIM>
43{
44 if (mpInstance == nullptr)
45 {
46 mpInstance = new WntConcentration;
47 }
48 return mpInstance;
49}
50
51template<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
68template<unsigned DIM>
72
73template<unsigned DIM>
75{
76 if (mpInstance)
77 {
78 delete mpInstance;
79 mpInstance = nullptr;
80 }
81}
82
83template<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
111template<unsigned DIM>
112c_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
127template<unsigned DIM>
129{
130 mpCellPopulation = &rCellPopulation;
131}
132
133template<unsigned DIM>
138
139template<unsigned DIM>
141{
142 return mCryptLength;
143}
144
145template<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
158template<unsigned DIM>
159WntConcentrationType WntConcentration<DIM>::GetType()
160{
161 return mWntType;
162}
163
164template<unsigned DIM>
165void 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
175template<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
218template<unsigned DIM>
219c_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
259template<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
270template<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
285template<unsigned DIM>
287{
288 return mWntConcentrationParameter;
289}
290
291template<unsigned DIM>
292void WntConcentration<DIM>::SetWntConcentrationParameter(double wntConcentrationParameter)
293{
294 assert(wntConcentrationParameter > 0.0);
295 mWntConcentrationParameter = wntConcentrationParameter;
296}
297
298template<unsigned DIM>
300{
301 return mCryptProjectionParameterA;
302}
303
304template<unsigned DIM>
306{
307 return mCryptProjectionParameterB;
308}
309
310template<unsigned DIM>
311void WntConcentration<DIM>::SetCryptProjectionParameterA(double cryptProjectionParameterA)
312{
313 assert(cryptProjectionParameterA >= 0.0);
314 mCryptProjectionParameterA = cryptProjectionParameterA;
315}
316
317template<unsigned DIM>
318void WntConcentration<DIM>::SetCryptProjectionParameterB(double cryptProjectionParameterB)
319{
320 assert(cryptProjectionParameterB >= 0.0);
321 mCryptProjectionParameterB = cryptProjectionParameterB;
322}
323
324// Explicit instantiation
325template class WntConcentration<1>;
326template class WntConcentration<2>;
327template class WntConcentration<3>;
const double DOUBLE_UNSET
Definition Exception.hpp:57
#define EXCEPTION(message)
static WntConcentration * Instance()
static void Destroy()
void SetWntConcentrationParameter(double wntConcentrationParameter)
AbstractCellPopulation< DIM > & rGetCellPopulation()
double GetCryptProjectionParameterB()
void SetType(WntConcentrationType type)
c_vector< double, DIM > GetWntGradient(c_vector< double, DIM > &rLocation)
void SetCellPopulation(AbstractCellPopulation< DIM > &rCellPopulation)
static WntConcentration * mpInstance
double GetCryptProjectionParameterA()
void SetCryptProjectionParameterB(double cryptProjectionParameterB)
WntConcentrationType GetType()
double GetWntConcentrationParameter()
void SetCryptLength(double cryptLength)
void SetCryptProjectionParameterA(double cryptProjectionParameterA)
double GetWntLevel(double height)
void SetConstantWntValueForTesting(double value)