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 00036 #include "TysonNovak2001OdeSystem.hpp" 00037 #include "OdeSystemInformation.hpp" 00038 #include "MathsCustomFunctions.hpp" 00039 00040 TysonNovak2001OdeSystem::TysonNovak2001OdeSystem(std::vector<double> stateVariables) 00041 : AbstractOdeSystemWithAnalyticJacobian(6) 00042 { 00043 mpSystemInfo = OdeSystemInformation<TysonNovak2001OdeSystem>::Instance(); 00044 00045 Init(); 00046 00047 if (stateVariables != std::vector<double>()) 00048 { 00049 SetStateVariables(stateVariables); 00050 } 00051 } 00052 00053 TysonNovak2001OdeSystem::~TysonNovak2001OdeSystem() 00054 { 00055 // Do nothing 00056 } 00057 00058 void TysonNovak2001OdeSystem::Init() 00059 { 00060 // Initialise model parameter values 00061 mK1 = 0.04; 00062 mK2d = 0.04; 00063 mK2dd = 1.0; 00064 mK2ddd = 1.0; 00065 mCycB_threshold = 0.1; 00066 mK3d = 1.0; 00067 mK3dd = 10.0; 00068 mK4d = 2.0; 00069 mK4 = 35; 00070 mJ3 = 0.04; 00071 mJ4 = 0.04; 00072 mK5d = 0.005; 00073 mK5dd = 0.2; 00074 mK6 = 0.1; 00075 mJ5 = 0.3; 00076 mN = 4u; 00077 mK7 = 1.0; 00078 mK8 = 0.5; 00079 mJ7 = 1e-3; 00080 mJ8 = 1e-3; 00081 mMad = 1.0; 00082 mK9 = 0.1; 00083 mK10 = 0.02; 00084 mK11 = 1.0; 00085 mK12d = 0.2; 00086 mK12dd = 50.0; 00087 mK12ddd = 100.0; 00088 mKeq = 1e3; 00089 mK13 = 1.0; 00090 mK14 = 1.0; 00091 mK15d = 1.5; 00092 mK15dd = 0.05; 00093 mK16d = 1.0; 00094 mK16dd = 3.0; 00095 mJ15 = 0.01; 00096 mJ16 = 0.01; 00097 mMu = 0.01; 00098 mMstar = 10.0; 00099 } 00100 00101 void TysonNovak2001OdeSystem::EvaluateYDerivatives(double time, const std::vector<double>& rY, std::vector<double>& rDY) 00102 { 00103 double x1 = rY[0]; 00104 double x2 = rY[1]; 00105 double x3 = rY[2]; 00106 double x4 = rY[3]; 00107 double x5 = rY[4]; 00108 double x6 = rY[5]; 00109 00110 double dx1 = 0.0; 00111 double dx2 = 0.0; 00112 double dx3 = 0.0; 00113 double dx4 = 0.0; 00114 double dx5 = 0.0; 00115 double dx6 = 0.0; 00116 00117 double temp1 = 0.0; 00118 double temp2 = 0.0; 00119 double temp3 = 0.0; 00120 00130 dx1 = mK1-(mK2d+mK2dd*x2)*x1; 00131 00132 // The commented line below models the start transition, no cycling, without Cdc20A 00133 // temp1 = ((mK3d)*(1.0-x2))/(mJ3+1.0-x2); 00134 00135 temp1 = ((mK3d+mK3dd*x4)*(1.0-x2))/(mJ3+1.0-x2); 00136 temp2 = (mK4*x6*x1*x2)/(mJ4+x2); 00137 dx2 = temp1-temp2; 00138 00139 temp1 = mK5dd*(SmallPow(x1*x6/mJ5,mN)/(1+SmallPow(x1*x6/mJ5,mN))); 00140 temp2 = mK6*x3; 00141 dx3 = mK5d + temp1 - temp2; 00142 00143 temp1 = (mK7*x5*(x3-x4))/(mJ7+x3-x4); 00144 temp2 = (mK8*mMad*x4)/(mJ8+x4); 00145 temp3 = mK6*x4; 00146 dx4 = temp1 - temp2 - temp3; 00147 00148 dx5 = mK9*x6*x1*(1.0-x5) - mK10*x5; 00149 00150 dx6 = mMu*x6*(1.0-x6/mMstar); 00151 00152 // Multiply by 60 beacuase the Tyson and Noval 2001 paper has time in minutes, not hours 00153 rDY[0] = dx1*60.0; 00154 rDY[1] = dx2*60.0; 00155 rDY[2] = dx3*60.0; 00156 rDY[3] = dx4*60.0; 00157 rDY[4] = dx5*60.0; 00158 rDY[5] = dx6*60.0; 00159 } 00160 00161 void TysonNovak2001OdeSystem::AnalyticJacobian(const std::vector<double>& rSolutionGuess, double** jacobian, double time, double timeStep) 00162 { 00163 timeStep *= 60.0; // to scale Jacobian so in hours not minutes 00164 double x1 = rSolutionGuess[0]; 00165 double x2 = rSolutionGuess[1]; 00166 double x3 = rSolutionGuess[2]; 00167 double x4 = rSolutionGuess[3]; 00168 double x5 = rSolutionGuess[4]; 00169 double x6 = rSolutionGuess[5]; 00170 00171 // f1 00172 double df1_dx1 = -mK2d - mK2dd*x2; 00173 double df1_dx2 = -mK2dd*x1; 00174 00175 jacobian[0][0] = 1-timeStep*df1_dx1; 00176 jacobian[0][1] = -timeStep*df1_dx2; 00177 00178 // f2 00179 double df2_dx1 = -mK4*x6*x2/(mJ4+x2); 00180 double df2_dx2 = -mJ3*(mK3d + mK3dd*x4)/(SmallPow((mJ3 + 1 - x2),2)) 00181 -mJ4*mK4*x6*x1/(SmallPow((mJ4+x2),2)); 00182 double df2_dx4 = mK3dd*(1-x2)/(mJ3+1-x2); 00183 double df2_dx6 = -mK4*x1*x2/(mJ4+x2); 00184 00185 jacobian[1][0] = -timeStep*df2_dx1; 00186 jacobian[1][1] = 1-timeStep*df2_dx2; 00187 jacobian[1][3] = -timeStep*df2_dx4; 00188 jacobian[1][5] = -timeStep*df2_dx6; 00189 00190 //f3 00191 double z = x1*x6/mJ5; 00192 double df3_dx1 = (mK5dd*x6/mJ5)*mN*SmallPow(z,mN-1)/(SmallPow((1-SmallPow(z,mN)),2)); 00193 double df3_dx3 = -mK6; 00194 double df3_dx6 = (mK5dd*x1/mJ5)*mN*SmallPow(z,mN-1)/(SmallPow((1-SmallPow(z,mN)),2)); 00195 00196 jacobian[2][0] = -timeStep*df3_dx1; 00197 jacobian[2][2] = 1-timeStep*df3_dx3; 00198 jacobian[2][5] = -timeStep*df3_dx6; 00199 00200 // f4 00201 double df4_dx3 = mJ7*mK7*x5/(SmallPow(mJ7+x3-x4,2)); 00202 double df4_dx4 = -mJ7*mK7*x5/(SmallPow(mJ7+x3-x4,2)) - mK6 - mJ8*mK8*mMad/(SmallPow(mJ8+x4,2)); 00203 double df4_dx5 = mK7*(x3-x4)/(mJ7+x3-x4); 00204 00205 jacobian[3][2] = -timeStep*df4_dx3; 00206 jacobian[3][3] = 1-timeStep*df4_dx4; 00207 jacobian[3][4] = -timeStep*df4_dx5; 00208 00209 // f5 00210 double df5_dx1 = mK9*x6*(1-x5); 00211 double df5_dx5 = -mK10 - mK9*x6*x1; 00212 double df5_dx6 = mK9*x1*(1-x5); 00213 00214 jacobian[4][0] = -timeStep*df5_dx1; 00215 jacobian[4][4] = 1-timeStep*df5_dx5; 00216 jacobian[4][5] = -timeStep*df5_dx6; 00217 00218 // f6 00219 double df6_dx6 = mMu - 2*mMu*x6/mMstar; 00220 00221 jacobian[5][5] = 1-timeStep*df6_dx6; 00222 } 00223 00224 bool TysonNovak2001OdeSystem::CalculateStoppingEvent(double time, const std::vector<double>& rY) 00225 { 00226 std::vector<double> dy(rY.size()); 00227 EvaluateYDerivatives(time, rY, dy); 00228 00229 // Only call this a stopping condition if the mass of the cell is over 0.6 00230 // (normally cycles from 0.5-1.0 ish!) 00231 return ( (rY[5] > 0.6 )&& (rY[0] < mCycB_threshold) && dy[0] < 0.0 ); 00232 } 00233 00234 double TysonNovak2001OdeSystem::CalculateRootFunction(double time, const std::vector<double>& rY) 00235 { 00236 std::vector<double> dy(rY.size()); 00237 EvaluateYDerivatives(time, rY, dy); 00238 00239 // Only call this a stopping condition if the mass of the cell is over 0.6 00240 // (normally cycles from 0.5-1.0 ish!) 00241 if (rY[5]<0.6) 00242 { 00243 return 1.0; 00244 } 00245 00246 if (dy[0] >= 0.0) 00247 { 00248 return 1.0; 00249 } 00250 return rY[0]-mCycB_threshold; 00251 } 00252 00253 template<> 00254 void OdeSystemInformation<TysonNovak2001OdeSystem>::Initialise() 00255 { 00256 /* 00257 * Initialise state variables. 00258 * 00259 * These initial conditions are the approximate steady state 00260 * solution values while the commented out conditions are taken 00261 * from the Tyson and Novak 2001 paper. 00262 */ 00263 this->mVariableNames.push_back("CycB"); 00264 this->mVariableUnits.push_back("nM"); 00265 // this->mInitialConditions.push_back(0.1); 00266 this->mInitialConditions.push_back(0.099999999999977); 00267 00268 this->mVariableNames.push_back("Cdh1"); 00269 this->mVariableUnits.push_back("nM"); 00270 // this->mInitialConditions.push_back(9.8770e-01); 00271 this->mInitialConditions.push_back(0.989026454281841); 00272 00273 this->mVariableNames.push_back("Cdc20T"); 00274 this->mVariableUnits.push_back("nM"); 00275 // this->mInitialConditions.push_back(1.5011e+00); 00276 this->mInitialConditions.push_back(1.547942029285891); 00277 00278 this->mVariableNames.push_back("Cdc20A"); 00279 this->mVariableUnits.push_back("nM"); 00280 // this->mInitialConditions.push_back(1.2924e+00); 00281 this->mInitialConditions.push_back(1.421110920135839); 00282 00283 this->mVariableNames.push_back("IEP"); 00284 this->mVariableUnits.push_back("nM"); 00285 // this->mInitialConditions.push_back(6.5405e-01); 00286 this->mInitialConditions.push_back(0.672838844290094); 00287 00288 this->mVariableNames.push_back("mass"); 00289 this->mVariableUnits.push_back(""); 00290 // this->mInitialConditions.push_back(4.7039e-01); 00291 this->mInitialConditions.push_back(0.970831277863956 / 2); 00292 00293 this->mInitialised = true; 00294 } 00295 00296 // Serialization for Boost >= 1.36 00297 #include "SerializationExportWrapperForCpp.hpp" 00298 CHASTE_CLASS_EXPORT(TysonNovak2001OdeSystem)