TysonNovak2001OdeSystem.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 #include "TysonNovak2001OdeSystem.hpp"
00029 #include "OdeSystemInformation.hpp"
00030 #include "UblasCustomFunctions.hpp"
00031 
00032 TysonNovak2001OdeSystem::TysonNovak2001OdeSystem()
00033         : AbstractOdeSystemWithAnalyticJacobian(6)
00034 {
00035     mpSystemInfo = OdeSystemInformation<TysonNovak2001OdeSystem>::Instance();
00036     
00037     Init();
00038 }
00039 
00040 TysonNovak2001OdeSystem::~TysonNovak2001OdeSystem()
00041 {
00042     // Do nothing
00043 }
00044 
00045 void TysonNovak2001OdeSystem::Init()
00046 {
00047     // Initialise model parameter values
00048     mK1 = 0.04;
00049     mK2d = 0.04;
00050     mK2dd = 1.0;
00051     mK2ddd = 1.0;
00052     mCycB_threshold = 0.1;
00053     mK3d = 1.0;
00054     mK3dd = 10.0;
00055     mK4d = 2.0;
00056     mK4 = 35;
00057     mJ3 = 0.04;
00058     mJ4 = 0.04;
00059     mK5d = 0.005;
00060     mK5dd = 0.2;
00061     mK6 = 0.1;
00062     mJ5 = 0.3;
00063     mN = 4u;
00064     mK7 = 1.0;
00065     mK8 = 0.5;
00066     mJ7 = 1e-3;
00067     mJ8 = 1e-3;
00068     mMad = 1.0;
00069     mK9 = 0.1;
00070     mK10 = 0.02;
00071     mK11 = 1.0;
00072     mK12d = 0.2;
00073     mK12dd = 50.0;
00074     mK12ddd = 100.0;
00075     mKeq = 1e3;
00076     mK13 = 1.0;
00077     mK14 = 1.0;
00078     mK15d = 1.5;
00079     mK15dd = 0.05;
00080     mK16d = 1.0;
00081     mK16dd = 3.0;
00082     mJ15 = 0.01;
00083     mJ16 = 0.01;
00084     mMu = 0.01;
00085     mMstar = 10.0;
00086 }
00087 
00088 void TysonNovak2001OdeSystem::EvaluateYDerivatives(double time, const std::vector<double>& rY, std::vector<double>& rDY)
00089 {
00090     double x1 = rY[0];
00091     double x2 = rY[1];
00092     double x3 = rY[2];
00093     double x4 = rY[3];
00094     double x5 = rY[4];
00095     double x6 = rY[5];
00096     
00097     double dx1 = 0.0;
00098     double dx2 = 0.0;
00099     double dx3 = 0.0;
00100     double dx4 = 0.0;
00101     double dx5 = 0.0;
00102     double dx6 = 0.0;
00103 
00104     double temp1 = 0.0;
00105     double temp2 = 0.0;
00106     double temp3 = 0.0;
00107     
00117     dx1 = mK1-(mK2d+mK2dd*x2)*x1;
00118     
00119     // The commented line below models the start transition, no cycling, without Cdc20A
00120 //    temp1 = ((mK3d)*(1.0-x2))/(mJ3+1.0-x2);
00121     
00122     temp1 = ((mK3d+mK3dd*x4)*(1.0-x2))/(mJ3+1.0-x2);
00123     temp2 = (mK4*x6*x1*x2)/(mJ4+x2);
00124     dx2 = temp1-temp2;
00125     
00126     temp1 = mK5dd*(SmallPow(x1*x6/mJ5,mN)/(1+SmallPow(x1*x6/mJ5,mN)));
00127     temp2 = mK6*x3;
00128     dx3 = mK5d + temp1 - temp2;
00129     
00130     temp1 = (mK7*x5*(x3-x4))/(mJ7+x3-x4);
00131     temp2 = (mK8*mMad*x4)/(mJ8+x4);
00132     temp3 = mK6*x4;
00133     dx4 = temp1 - temp2 - temp3;
00134     
00135     dx5 = mK9*x6*x1*(1.0-x5) - mK10*x5;
00136     
00137     dx6 = mMu*x6*(1.0-x6/mMstar);
00138     
00139     // Multiply by 60 beacuase the Tyson and Noval 2001 paper has time in minutes, not hours
00140     rDY[0] = dx1*60.0;
00141     rDY[1] = dx2*60.0;
00142     rDY[2] = dx3*60.0;
00143     rDY[3] = dx4*60.0;
00144     rDY[4] = dx5*60.0;
00145     rDY[5] = dx6*60.0;
00146 }
00147 
00148 void TysonNovak2001OdeSystem::AnalyticJacobian(const std::vector<double>& rSolutionGuess, double** jacobian, double time, double timeStep)
00149 {
00150     timeStep *= 60.0; // to scale Jacobian so in hours not minutes
00151     double x1 = rSolutionGuess[0];
00152     double x2 = rSolutionGuess[1];
00153     double x3 = rSolutionGuess[2];
00154     double x4 = rSolutionGuess[3];
00155     double x5 = rSolutionGuess[4];
00156     double x6 = rSolutionGuess[5];
00157     
00158     // f1
00159     double df1_dx1 = -mK2d - mK2dd*x2;
00160     double df1_dx2 = -mK2dd*x1;
00161     
00162     jacobian[0][0] =  1-timeStep*df1_dx1;
00163     jacobian[0][1] = -timeStep*df1_dx2;
00164     
00165     // f2
00166     double df2_dx1 = -mK4*x6*x2/(mJ4+x2);
00167     double df2_dx2 = -mJ3*(mK3d + mK3dd*x4)/(SmallPow((mJ3 + 1 - x2),2))
00168                      -mJ4*mK4*x6*x1/(SmallPow((mJ4+x2),2));
00169     double df2_dx4 =  mK3dd*(1-x2)/(mJ3+1-x2);
00170     double df2_dx6 = -mK4*x1*x2/(mJ4+x2);
00171     
00172     jacobian[1][0] = -timeStep*df2_dx1;
00173     jacobian[1][1] =  1-timeStep*df2_dx2;
00174     jacobian[1][3] = -timeStep*df2_dx4;
00175     jacobian[1][5] = -timeStep*df2_dx6;
00176     
00177     //f3
00178     double z = x1*x6/mJ5;
00179     double df3_dx1 = (mK5dd*x6/mJ5)*mN*SmallPow(z,mN-1)/(SmallPow((1-SmallPow(z,mN)),2));
00180     double df3_dx3 = -mK6;
00181     double df3_dx6 = (mK5dd*x1/mJ5)*mN*SmallPow(z,mN-1)/(SmallPow((1-SmallPow(z,mN)),2));
00182     
00183     jacobian[2][0] = -timeStep*df3_dx1;
00184     jacobian[2][2] = 1-timeStep*df3_dx3;
00185     jacobian[2][5] = -timeStep*df3_dx6;
00186     
00187     // f4
00188     double df4_dx3 =  mJ7*mK7*x5/(SmallPow(mJ7+x3-x4,2));
00189     double df4_dx4 = -mJ7*mK7*x5/(SmallPow(mJ7+x3-x4,2)) - mK6 - mJ8*mK8*mMad/(SmallPow(mJ8+x4,2));
00190     double df4_dx5 =  mK7*(x3-x4)/(mJ7+x3-x4);
00191     
00192     jacobian[3][2] = -timeStep*df4_dx3;
00193     jacobian[3][3] = 1-timeStep*df4_dx4;
00194     jacobian[3][4] = -timeStep*df4_dx5;
00195     
00196     // f5
00197     double df5_dx1 =  mK9*x6*(1-x5);
00198     double df5_dx5 = -mK10 - mK9*x6*x1;
00199     double df5_dx6 =  mK9*x1*(1-x5);
00200     
00201     jacobian[4][0] = -timeStep*df5_dx1;
00202     jacobian[4][4] = 1-timeStep*df5_dx5;
00203     jacobian[4][5] = -timeStep*df5_dx6;
00204     
00205     // f6
00206     double df6_dx6 = mMu - 2*mMu*x6/mMstar;
00207     
00208     jacobian[5][5] = 1-timeStep*df6_dx6;
00209 }
00210 
00211 bool TysonNovak2001OdeSystem::CalculateStoppingEvent(double time, const std::vector<double>& rY)
00212 {
00213     std::vector<double> dy(rY.size());
00214     EvaluateYDerivatives(time, rY, dy);
00215     
00216     // Only call this a stopping condition if the mass of the cell is over 0.6
00217     // (normally cycles from 0.5-1.0 ish!)
00218     return ( (rY[5] > 0.6 )&& (rY[0] < mCycB_threshold) && dy[0] < 0.0 );
00219 }
00220 
00221 double TysonNovak2001OdeSystem::CalculateRootFunction(double time, const std::vector<double>& rY)
00222 {
00223     std::vector<double> dy(rY.size());
00224     EvaluateYDerivatives(time, rY, dy);
00225 
00226     // Only call this a stopping condition if the mass of the cell is over 0.6
00227     // (normally cycles from 0.5-1.0 ish!)
00228     if (rY[5]<0.6)
00229     {
00230         return 1.0;
00231     }
00232 
00233     if (dy[0] >= 0.0)
00234     {
00235         return 1.0;
00236     }
00237     return rY[0]-mCycB_threshold;
00238 }
00239 
00240 template<>
00241 void OdeSystemInformation<TysonNovak2001OdeSystem>::Initialise()
00242 {
00243     /*
00244      * Initialise state variables.
00245      *
00246      * These initial conditions are the approximate steady state
00247      * solution values while the commented out conditions are taken
00248      * from the Tyson and Novak 2001 paper.
00249      */
00250     this->mVariableNames.push_back("CycB");
00251     this->mVariableUnits.push_back("nM");
00252 //    this->mInitialConditions.push_back(0.1);
00253     this->mInitialConditions.push_back(0.099999999999977);
00254 
00255     this->mVariableNames.push_back("Cdh1");
00256     this->mVariableUnits.push_back("nM");
00257 //    this->mInitialConditions.push_back(9.8770e-01);
00258     this->mInitialConditions.push_back(0.989026454281841);
00259 
00260     this->mVariableNames.push_back("Cdc20T");
00261     this->mVariableUnits.push_back("nM");
00262 //    this->mInitialConditions.push_back(1.5011e+00);
00263     this->mInitialConditions.push_back(1.547942029285891);
00264 
00265     this->mVariableNames.push_back("Cdc20A");
00266     this->mVariableUnits.push_back("nM");
00267 //    this->mInitialConditions.push_back(1.2924e+00);
00268     this->mInitialConditions.push_back(1.421110920135839);
00269 
00270     this->mVariableNames.push_back("IEP");
00271     this->mVariableUnits.push_back("nM");
00272 //    this->mInitialConditions.push_back(6.5405e-01);
00273     this->mInitialConditions.push_back(0.672838844290094);
00274 
00275     this->mVariableNames.push_back("mass");
00276     this->mVariableUnits.push_back("");
00277 //    this->mInitialConditions.push_back(4.7039e-01);
00278     this->mInitialConditions.push_back(0.970831277863956 / 2);
00279 
00280     this->mInitialised = true;
00281 }

Generated by  doxygen 1.6.2