TysonNovak2001OdeSystem.cpp

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