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 #include "NhsContractionModel.hpp" 00036 #include "OdeSystemInformation.hpp" 00037 #include "EulerIvpOdeSolver.hpp" 00038 #include "UblasCustomFunctions.hpp" 00039 00040 #include <cmath> 00041 00042 00043 00044 // 00045 // Model-scope constant parameters 00046 // 00047 const double NhsContractionModel::mKon = 100; 00048 const double NhsContractionModel::mKrefoff = 0.2; 00049 const double NhsContractionModel::mGamma = 2; 00050 const double NhsContractionModel::mCalciumTroponinMax = 0.07; 00051 const double NhsContractionModel::mAlphaR1 = 0.002; 00052 const double NhsContractionModel::mAlphaR2 = 0.0017; 00053 const double NhsContractionModel::mKZ = 0.15; 00054 const unsigned NhsContractionModel::mNr = 3u; 00055 const double NhsContractionModel::mBeta1 = -4; 00056 const double NhsContractionModel::mAlpha0 = 0.008; 00057 const unsigned NhsContractionModel::mN = 3u; 00058 const double NhsContractionModel::mZp = 0.85; 00059 const double NhsContractionModel::mCalcium50ref = 0.00105; 00060 const double NhsContractionModel::mTref = 56.2; 00061 const double NhsContractionModel::mBeta0 = 4.9; 00062 const double NhsContractionModel::mA = 0.35; 00063 const double NhsContractionModel::mA1 = -29; 00064 const double NhsContractionModel::mA2 = 138; 00065 const double NhsContractionModel::mA3 = 129; 00066 const double NhsContractionModel::mAlpha1 = 0.03; 00067 const double NhsContractionModel::mAlpha2 = 0.130; 00068 const double NhsContractionModel::mAlpha3 = 0.625; 00069 00070 00071 /* 00072 * ============================== PRIVATE FUNCTIONS ===================================== 00073 */ 00074 void NhsContractionModel::CalculateCalciumTrop50() 00075 { 00076 double Ca50ref_times_one_plus_beta1_times_lam_minus_one = mCalcium50ref * (1 + mBeta1*(mLambda-1)); 00077 double one_plus_beta0_times_lam_minus_one_over_two_gamma = (1 + mBeta0*(mLambda-1))/(2*mGamma); 00078 00079 mCalciumTrop50 = mCalciumTroponinMax * Ca50ref_times_one_plus_beta1_times_lam_minus_one; 00080 mCalciumTrop50 /= (Ca50ref_times_one_plus_beta1_times_lam_minus_one + (1-one_plus_beta0_times_lam_minus_one_over_two_gamma)*mKrefoff/mKon); 00081 } 00082 00083 00084 double NhsContractionModel::CalculateT0(double z) 00085 { 00086 double calcium_ratio_to_n = SmallPow(mCalciumTrop50/mCalciumTroponinMax, mN); 00087 00088 double z_max = mAlpha0 - mK2*calcium_ratio_to_n; 00089 z_max /= mAlpha0 + (mAlphaR1 + mK1)*calcium_ratio_to_n; 00090 00091 return z * mTref * (1+mBeta0*(mLambda-1)) / z_max; 00092 } 00093 00094 00095 00096 /* 00097 * ============================== PUBLIC FUNCTIONS ===================================== 00098 */ 00099 00100 NhsContractionModel::NhsContractionModel() 00101 : AbstractOdeBasedContractionModel(5) // five state variables 00102 { 00103 mpSystemInfo = OdeSystemInformation<NhsContractionModel>::Instance(); 00104 ResetToInitialConditions(); 00105 00106 mLambda = 1.0; 00107 mDLambdaDt = 0.0; 00108 mCalciumI = 0.0; 00109 00110 // Initialise mCalciumTrop50!! 00111 CalculateCalciumTrop50(); 00112 00113 double zp_to_n_plus_K_to_n = SmallPow(mZp,mNr) + SmallPow(mKZ,mNr); 00114 00115 mK1 = mAlphaR2 * SmallPow(mZp,mNr-1) * mNr * SmallPow(mKZ,mNr); 00116 mK1 /= zp_to_n_plus_K_to_n * zp_to_n_plus_K_to_n; 00117 00118 mK2 = mAlphaR2 * SmallPow(mZp,mNr)/zp_to_n_plus_K_to_n; 00119 mK2 *= 1 - mNr*SmallPow(mKZ,mNr)/zp_to_n_plus_K_to_n; 00120 } 00121 00122 void NhsContractionModel::SetStretchAndStretchRate(double lambda, double dlambdaDt) 00123 { 00124 assert(lambda>0.0); 00125 mLambda = lambda; 00126 mDLambdaDt = dlambdaDt; 00127 // lambda changed so update mCalciumTrop50!! 00128 CalculateCalciumTrop50(); 00129 } 00130 00131 void NhsContractionModel::SetInputParameters(ContractionModelInputParameters& rInputParameters) 00132 { 00133 assert(rInputParameters.intracellularCalciumConcentration != DOUBLE_UNSET); 00134 assert(rInputParameters.intracellularCalciumConcentration > 0.0); 00135 mCalciumI = rInputParameters.intracellularCalciumConcentration; 00136 } 00137 00138 void NhsContractionModel::SetIntracellularCalciumConcentration(double calciumConcentration) 00139 { 00140 assert(calciumConcentration > 0.0); 00141 mCalciumI = calciumConcentration; 00142 } 00143 00144 double NhsContractionModel::GetCalciumTroponinValue() 00145 { 00146 return mStateVariables[0]; 00147 } 00148 00149 void NhsContractionModel::EvaluateYDerivatives(double time, 00150 const std::vector<double> &rY, 00151 std::vector<double> &rDY) 00152 { 00154 00155 const double& calcium_troponin = rY[0]; 00156 const double& z = rY[1]; 00157 const double& Q1 = rY[2]; 00158 const double& Q2 = rY[3]; 00159 const double& Q3 = rY[4]; 00160 00161 // check the state vars are in the expected range 00162 #define COVERAGE_IGNORE 00163 if(calcium_troponin < 0) 00164 { 00165 EXCEPTION("CalciumTrop concentration went negative"); 00166 } 00167 if(z<0) 00168 { 00169 EXCEPTION("z went negative"); 00170 } 00171 if(z>1) 00172 { 00173 EXCEPTION("z became greater than 1"); 00174 } 00175 #undef COVERAGE_IGNORE 00176 00177 00178 double Q = Q1 + Q2 + Q3; 00179 double T0 = CalculateT0(z); 00180 00181 double Ta; 00182 if(Q>0) 00183 { 00184 Ta = T0*(1+(2+mA)*Q)/(1+Q); 00185 } 00186 else 00187 { 00188 Ta = T0*(1+mA*Q)/(1-Q); 00189 } 00190 00191 rDY[0] = mKon * mCalciumI * ( mCalciumTroponinMax - calcium_troponin) 00192 - mKrefoff * (1-Ta/(mGamma*mTref)) * calcium_troponin; 00193 00194 double ca_trop_to_ca_trop50_ratio_to_n = SmallPow(calcium_troponin/mCalciumTrop50, mN); 00195 00196 rDY[1] = mAlpha0 * ca_trop_to_ca_trop50_ratio_to_n * (1-z) 00197 - mAlphaR1 * z 00198 - mAlphaR2 * SmallPow(z,mNr) / (SmallPow(z,mNr) + SmallPow(mKZ,mNr)); 00199 00200 00201 rDY[2] = mA1 * mDLambdaDt - mAlpha1 * Q1; 00202 rDY[3] = mA2 * mDLambdaDt - mAlpha2 * Q2; 00203 rDY[4] = mA3 * mDLambdaDt - mAlpha3 * Q3; 00204 } 00205 00206 00207 double NhsContractionModel::GetActiveTension() 00208 { 00209 double T0 = CalculateT0(mStateVariables[1]); 00210 double Q = mStateVariables[2]+mStateVariables[3]+mStateVariables[4]; 00211 00212 if(Q>0) 00213 { 00214 return T0*(1+(2+mA)*Q)/(1+Q); 00215 } 00216 else 00217 { 00218 return T0*(1+mA*Q)/(1-Q); 00219 } 00220 } 00221 00222 template<> 00223 void OdeSystemInformation<NhsContractionModel>::Initialise(void) 00224 { 00225 this->mVariableNames.push_back("CalciumTroponin"); 00226 this->mVariableUnits.push_back("microMols"); 00227 this->mInitialConditions.push_back(0); 00228 00229 this->mVariableNames.push_back("z"); 00230 this->mVariableUnits.push_back(""); 00231 this->mInitialConditions.push_back(0); 00232 00233 this->mVariableNames.push_back("Q1"); 00234 this->mVariableUnits.push_back(""); 00235 this->mInitialConditions.push_back(0); 00236 00237 this->mVariableNames.push_back("Q2"); 00238 this->mVariableUnits.push_back(""); 00239 this->mInitialConditions.push_back(0); 00240 00241 this->mVariableNames.push_back("Q3"); 00242 this->mVariableUnits.push_back(""); 00243 this->mInitialConditions.push_back(0); 00244 00245 this->mInitialised = true; 00246 }