00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "NhsCellularMechanicsOdeSystem.hpp"
00029 #include "OdeSystemInformation.hpp"
00030 #include <cmath>
00031
00032
00033
00034
00035 void NhsCellularMechanicsOdeSystem::CalculateCalciumTrop50()
00036 {
00037 double one_plus_beta1_times_lam_minus_one = 1 + mBeta1*(mLambda-1);
00038
00039 mCalciumTrop50 = mCalciumTroponinMax * mCalcium50ref * one_plus_beta1_times_lam_minus_one;
00040 mCalciumTrop50 /= mCalcium50ref*one_plus_beta1_times_lam_minus_one + (1-one_plus_beta1_times_lam_minus_one/(2*mGamma))*mKrefoff/mKon;
00041 }
00042
00043
00044 double NhsCellularMechanicsOdeSystem::CalculateT0(double z)
00045 {
00046 double calcium_ratio_to_n = pow(mCalciumTrop50/mCalciumTroponinMax, mN);
00047
00048 double z_max = mAlpha0 - mK2*calcium_ratio_to_n;
00049 z_max /= mAlpha0 + (mAlphaR1 + mK1)*calcium_ratio_to_n;
00050
00051 return z * mTref * (1+mBeta0*(mLambda-1)) / z_max;
00052 }
00053
00054
00055
00056
00057
00058
00059
00060 NhsCellularMechanicsOdeSystem::NhsCellularMechanicsOdeSystem()
00061 : AbstractOdeSystem(5)
00062 {
00063 mpSystemInfo = OdeSystemInformation<NhsCellularMechanicsOdeSystem>::Instance();
00064 SetStateVariables(GetInitialConditions());
00065
00066 mLambda = 1.0;
00067 mDLambdaDt = 0.0;
00068 mCalciumI = 0.0;
00069
00070
00071 CalculateCalciumTrop50();
00072
00073 double zp_to_n_plus_K_to_n = pow(mZp,mNr) + pow(mKZ,mNr);
00074
00075 mK1 = mAlphaR2 * pow(mZp,mNr-1) * mNr * pow(mKZ,mNr);
00076 mK1 /= zp_to_n_plus_K_to_n * zp_to_n_plus_K_to_n;
00077
00078 mK2 = mAlphaR2 * pow(mZp,mNr)/zp_to_n_plus_K_to_n;
00079 mK2 *= 1 - mNr*pow(mKZ,mNr)/zp_to_n_plus_K_to_n;
00080 }
00081
00082 void NhsCellularMechanicsOdeSystem::SetLambdaAndDerivative(double lambda, double dlambdaDt)
00083 {
00084 assert(lambda>0.0);
00085 mLambda = lambda;
00086 mDLambdaDt = dlambdaDt;
00087
00088 CalculateCalciumTrop50();
00089 }
00090
00091 void NhsCellularMechanicsOdeSystem::SetIntracellularCalciumConcentration(double calciumI)
00092 {
00093 assert(calciumI > 0.0);
00094 mCalciumI = calciumI;
00095 }
00096
00097 #define COVERAGE_IGNORE // this is covered, but gcov is rubbish
00098 double NhsCellularMechanicsOdeSystem::GetCalciumTroponinValue()
00099 {
00100 return mStateVariables[0];
00101 }
00102 #undef COVERAGE_IGNORE
00103
00104 void NhsCellularMechanicsOdeSystem::EvaluateYDerivatives(double time,
00105 const std::vector<double> &rY,
00106 std::vector<double> &rDY)
00107 {
00108 const double& calcium_troponin = rY[0];
00109 const double& z = rY[1];
00110 const double& Q1 = rY[2];
00111 const double& Q2 = rY[3];
00112 const double& Q3 = rY[4];
00113
00114
00115 #define COVERAGE_IGNORE
00116 if(calcium_troponin < 0)
00117 {
00118 EXCEPTION("CalciumTrop concentration went negative");
00119 }
00120 if(z<0)
00121 {
00122 EXCEPTION("z went negative");
00123 }
00124 if(z>1)
00125 {
00126 EXCEPTION("z became greater than 1");
00127 }
00128 #undef COVERAGE_IGNORE
00129
00130
00131 double Q = Q1 + Q2 + Q3;
00132 double T0 = CalculateT0(z);
00133
00134 double Ta;
00135 if(Q>0)
00136 {
00137 Ta = T0*(1+(2+mA)*Q)/(1+Q);
00138 }
00139 else
00140 {
00141 Ta = T0*(1+mA*Q)/(1-Q);
00142 }
00143
00144 rDY[0] = mKon * mCalciumI * ( mCalciumTroponinMax - calcium_troponin)
00145 - mKrefoff * (1-Ta/(mGamma*mTref)) * calcium_troponin;
00146
00147 double ca_trop_to_ca_trop50_ratio_to_n = pow(calcium_troponin/mCalciumTrop50, mN);
00148
00149 rDY[1] = mAlpha0 * ca_trop_to_ca_trop50_ratio_to_n * (1-z)
00150 - mAlphaR1 * z
00151 - mAlphaR2 * pow(z,mNr) / (pow(z,mNr) + pow(mKZ,mNr));
00152
00153
00154 rDY[2] = mA1 * mDLambdaDt - mAlpha1 * Q1;
00155 rDY[3] = mA2 * mDLambdaDt - mAlpha2 * Q2;
00156 rDY[4] = mA3 * mDLambdaDt - mAlpha3 * Q3;
00157 }
00158
00159
00160 double NhsCellularMechanicsOdeSystem::GetActiveTension()
00161 {
00162 double T0 = CalculateT0(mStateVariables[1]);
00163 double Q = mStateVariables[2]+mStateVariables[3]+mStateVariables[4];
00164
00165 if(Q>0)
00166 {
00167 return T0*(1+(2+mA)*Q)/(1+Q);
00168 }
00169 else
00170 {
00171 return T0*(1+mA*Q)/(1-Q);
00172 }
00173 }
00174
00175 double NhsCellularMechanicsOdeSystem::GetLambda()
00176 {
00177 return mLambda;
00178 }
00179
00180
00181 template<>
00182 void OdeSystemInformation<NhsCellularMechanicsOdeSystem>::Initialise(void)
00183 {
00184 this->mVariableNames.push_back("CalciumTroponin");
00185 this->mVariableUnits.push_back("microMols");
00186 this->mInitialConditions.push_back(0);
00187
00188 this->mVariableNames.push_back("z");
00189 this->mVariableUnits.push_back("");
00190 this->mInitialConditions.push_back(0);
00191
00192 this->mVariableNames.push_back("Q1");
00193 this->mVariableUnits.push_back("");
00194 this->mInitialConditions.push_back(0);
00195
00196 this->mVariableNames.push_back("Q2");
00197 this->mVariableUnits.push_back("");
00198 this->mInitialConditions.push_back(0);
00199
00200 this->mVariableNames.push_back("Q3");
00201 this->mVariableUnits.push_back("");
00202 this->mInitialConditions.push_back(0);
00203
00204 this->mInitialised = true;
00205 }