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 "LuoRudyIModel1991OdeSystem.hpp"
00029 #include "OdeSystemInformation.hpp"
00030 #include <cmath>
00031
00032 #include "Exception.hpp"
00033
00034
00035
00036
00037
00038 const double LuoRudyIModel1991OdeSystem::membrane_C = 1.0;
00039 const double LuoRudyIModel1991OdeSystem::membrane_F = 96484.6;
00040 const double LuoRudyIModel1991OdeSystem::membrane_R = 8314;
00041 const double LuoRudyIModel1991OdeSystem::membrane_T = 310.0;
00042 const double LuoRudyIModel1991OdeSystem::background_current_E_b = -59.87;
00043 const double LuoRudyIModel1991OdeSystem::background_current_g_b = 0.03921;
00044 const double LuoRudyIModel1991OdeSystem::fast_sodium_current_g_Na = 23.0;
00045 const double LuoRudyIModel1991OdeSystem::ionic_concentrations_Ki = 145.0;
00046 const double LuoRudyIModel1991OdeSystem::ionic_concentrations_Ko = 5.4;
00047 const double LuoRudyIModel1991OdeSystem::ionic_concentrations_Nai = 18.0;
00048 const double LuoRudyIModel1991OdeSystem::ionic_concentrations_Nao = 140.0;
00049 const double LuoRudyIModel1991OdeSystem::plateau_potassium_current_g_Kp = 0.0183;
00050 const double LuoRudyIModel1991OdeSystem::time_dependent_potassium_current_PR_NaK = 0.01833;
00051
00052
00053
00057 LuoRudyIModel1991OdeSystem::LuoRudyIModel1991OdeSystem(
00058 boost::shared_ptr<AbstractIvpOdeSolver> pSolver,
00059 boost::shared_ptr<AbstractStimulusFunction> pIntracellularStimulus)
00060 : AbstractCardiacCell(pSolver, 8, 4, pIntracellularStimulus)
00061 {
00062 mpSystemInfo = OdeSystemInformation<LuoRudyIModel1991OdeSystem>::Instance();
00063
00064
00065 fast_sodium_current_E_Na = ((membrane_R * membrane_T) / membrane_F) *
00066 log(ionic_concentrations_Nao / ionic_concentrations_Nai);
00067
00068 Init();
00069 }
00070
00074 LuoRudyIModel1991OdeSystem::~LuoRudyIModel1991OdeSystem(void)
00075 {
00076 }
00077
00078 double LuoRudyIModel1991OdeSystem::GetIntracellularCalciumConcentration()
00079 {
00080 return mStateVariables[3];
00081 }
00082
00092 void LuoRudyIModel1991OdeSystem::EvaluateYDerivatives(double time,
00093 const std::vector<double> &rY,
00094 std::vector<double> &rDY)
00095 {
00096 double fast_sodium_current_h_gate_h = rY[0];
00097 double fast_sodium_current_j_gate_j = rY[1];
00098 double fast_sodium_current_m_gate_m = rY[2];
00099 double intracellular_calcium_concentration_Cai = rY[3];
00100 double membrane_V = rY[4];
00101 double slow_inward_current_d_gate_d = rY[5];
00102 double slow_inward_current_f_gate_f = rY[6];
00103 double time_dependent_potassium_current_X_gate_X = rY[7];
00104
00105 double background_current_i_b = background_current_g_b*(membrane_V-background_current_E_b);
00106
00107 double fast_sodium_current_h_gate_alpha_h;
00108
00109 if (membrane_V < -40.0)
00110 {
00111 fast_sodium_current_h_gate_alpha_h = 0.135*exp((80.0+membrane_V)/-6.8);
00112 }
00113 else
00114 {
00115 fast_sodium_current_h_gate_alpha_h = 0.0;
00116 }
00117
00118 double fast_sodium_current_h_gate_beta_h;
00119
00120 if (membrane_V < -40.0)
00121 {
00122 fast_sodium_current_h_gate_beta_h = 3.56*exp(0.079*membrane_V)+3.1e5*exp(0.35*membrane_V);
00123 }
00124 else
00125 {
00126 fast_sodium_current_h_gate_beta_h = 1.0/(0.13*(1.0+exp((membrane_V+10.66)/-11.1)));
00127 }
00128
00129 double fast_sodium_current_h_gate_h_prime = fast_sodium_current_h_gate_alpha_h*(1.0-fast_sodium_current_h_gate_h)-fast_sodium_current_h_gate_beta_h*fast_sodium_current_h_gate_h;
00130
00131 double fast_sodium_current_j_gate_alpha_j;
00132
00133 if (membrane_V < -40.0)
00134 {
00135 fast_sodium_current_j_gate_alpha_j = (-1.2714e5*exp(0.2444*membrane_V)-3.474e-5*exp(-0.04391*membrane_V))*(membrane_V+37.78)/(1.0+exp(0.311*(membrane_V+79.23)));
00136 }
00137 else
00138 {
00139 fast_sodium_current_j_gate_alpha_j = 0.0;
00140 }
00141
00142 double fast_sodium_current_j_gate_beta_j;
00143
00144 if (membrane_V < -40.0)
00145 {
00146 fast_sodium_current_j_gate_beta_j = 0.1212*exp(-0.01052*membrane_V)/(1.0+exp(-0.1378*(membrane_V+40.14)));
00147 }
00148 else
00149 {
00150 fast_sodium_current_j_gate_beta_j = 0.3*exp(-2.535e-7*membrane_V)/(1.0+exp(-0.1*(membrane_V+32.0)));
00151 }
00152
00153 double fast_sodium_current_j_gate_j_prime = fast_sodium_current_j_gate_alpha_j*(1.0-fast_sodium_current_j_gate_j)-fast_sodium_current_j_gate_beta_j*fast_sodium_current_j_gate_j;
00154 double fast_sodium_current_m_gate_alpha_m = 0.32*(membrane_V+47.13)/(1.0-exp(-0.1*(membrane_V+47.13)));
00155 double fast_sodium_current_m_gate_beta_m = 0.08*exp(-membrane_V/11.0);
00156 double fast_sodium_current_m_gate_m_prime = fast_sodium_current_m_gate_alpha_m*(1.0-fast_sodium_current_m_gate_m)-fast_sodium_current_m_gate_beta_m*fast_sodium_current_m_gate_m;
00157 double fast_sodium_current_i_Na = fast_sodium_current_g_Na*pow(fast_sodium_current_m_gate_m, 3.0)*fast_sodium_current_h_gate_h*fast_sodium_current_j_gate_j*(membrane_V-fast_sodium_current_E_Na);
00158
00159 double slow_inward_current_d_gate_alpha_d = 0.095*exp(-0.01*(membrane_V-5.0))/(1.0+exp(-0.072*(membrane_V-5.0)));
00160 double slow_inward_current_d_gate_beta_d = 0.07*exp(-0.017*(membrane_V+44.0))/(1.0+exp(0.05*(membrane_V+44.0)));
00161 double slow_inward_current_d_gate_d_prime = slow_inward_current_d_gate_alpha_d*(1.0-slow_inward_current_d_gate_d)-slow_inward_current_d_gate_beta_d*slow_inward_current_d_gate_d;
00162
00163 double slow_inward_current_f_gate_alpha_f = 0.012*exp(-0.008*(membrane_V+28.0))/(1.0+exp(0.15*(membrane_V+28.0)));
00164 double slow_inward_current_f_gate_beta_f = 0.0065*exp(-0.02*(membrane_V+30.0))/(1.0+exp(-0.2*(membrane_V+30.0)));
00165 double slow_inward_current_f_gate_f_prime = slow_inward_current_f_gate_alpha_f*(1.0-slow_inward_current_f_gate_f)-slow_inward_current_f_gate_beta_f*slow_inward_current_f_gate_f;
00166
00167 double slow_inward_current_E_si = 7.7-13.0287*log(intracellular_calcium_concentration_Cai);
00168 double slow_inward_current_i_si = 0.09*slow_inward_current_d_gate_d*slow_inward_current_f_gate_f*(membrane_V-slow_inward_current_E_si);
00169 double intracellular_calcium_concentration_Cai_prime = -1e-4*slow_inward_current_i_si+0.07*(1e-4-intracellular_calcium_concentration_Cai);
00170 double time_dependent_potassium_current_g_K = 0.282*sqrt(ionic_concentrations_Ko/5.4);
00171
00172 double time_dependent_potassium_current_Xi_gate_Xi;
00173
00174 if (membrane_V > -100.0)
00175 {
00176 time_dependent_potassium_current_Xi_gate_Xi = 2.837*(exp(0.04*(membrane_V+77.0))-1.0)/((membrane_V+77.0)*exp(0.04*(membrane_V+35.0)));
00177 }
00178 else
00179 {
00180 #define COVERAGE_IGNORE
00181 time_dependent_potassium_current_Xi_gate_Xi = 1.0;
00182 #undef COVERAGE_IGNORE
00183 }
00184
00185 double time_dependent_potassium_current_X_gate_alpha_X = 0.0005*exp(0.083*(membrane_V+50.0))/(1.0+exp(0.057*(membrane_V+50.0)));
00186 double time_dependent_potassium_current_X_gate_beta_X = 0.0013*exp(-0.06*(membrane_V+20.0))/(1.0+exp(-0.04*(membrane_V+20.0)));
00187 double time_dependent_potassium_current_X_gate_X_prime = time_dependent_potassium_current_X_gate_alpha_X*(1.0-time_dependent_potassium_current_X_gate_X)-time_dependent_potassium_current_X_gate_beta_X*time_dependent_potassium_current_X_gate_X;
00188
00189 double time_dependent_potassium_current_E_K = ((membrane_R*membrane_T)/membrane_F)*log((ionic_concentrations_Ko+time_dependent_potassium_current_PR_NaK*ionic_concentrations_Nao)/(ionic_concentrations_Ki+time_dependent_potassium_current_PR_NaK*ionic_concentrations_Nai));
00190 double time_dependent_potassium_current_i_K = time_dependent_potassium_current_g_K*time_dependent_potassium_current_X_gate_X*time_dependent_potassium_current_Xi_gate_Xi*(membrane_V-time_dependent_potassium_current_E_K);
00191 double time_independent_potassium_current_g_K1 = 0.6047*sqrt(ionic_concentrations_Ko/5.4);
00192 double time_independent_potassium_current_E_K1 =((membrane_R*membrane_T)/membrane_F)*log(ionic_concentrations_Ko/ionic_concentrations_Ki);
00193 double time_independent_potassium_current_K1_gate_alpha_K1 = 1.02/(1.0+exp(0.2385*(membrane_V-time_independent_potassium_current_E_K1-59.215)));
00194 double time_independent_potassium_current_K1_gate_beta_K1 = (0.49124*exp(0.08032*(membrane_V+5.476-time_independent_potassium_current_E_K1))+exp(0.06175*(membrane_V-(time_independent_potassium_current_E_K1+594.31))))/(1.0+exp(-0.5143*(membrane_V-time_independent_potassium_current_E_K1+4.753)));
00195 double time_independent_potassium_current_K1_gate_K1_infinity = time_independent_potassium_current_K1_gate_alpha_K1/(time_independent_potassium_current_K1_gate_alpha_K1+time_independent_potassium_current_K1_gate_beta_K1);
00196 double time_independent_potassium_current_i_K1 = time_independent_potassium_current_g_K1*time_independent_potassium_current_K1_gate_K1_infinity*(membrane_V-time_independent_potassium_current_E_K1);
00197 double plateau_potassium_current_Kp = 1.0/(1.0+exp((7.488-membrane_V)/5.98));
00198 double plateau_potassium_current_E_Kp = time_independent_potassium_current_E_K1;
00199 double plateau_potassium_current_i_Kp = plateau_potassium_current_g_Kp*plateau_potassium_current_Kp*(membrane_V-plateau_potassium_current_E_Kp);
00200 double i_stim = GetStimulus(time);
00201
00202
00203 double membrane_V_prime = (-1.0/membrane_C)*(fast_sodium_current_i_Na+slow_inward_current_i_si+time_dependent_potassium_current_i_K+time_independent_potassium_current_i_K1+plateau_potassium_current_i_Kp+background_current_i_b + i_stim);
00204
00205 if (mSetVoltageDerivativeToZero)
00206 {
00207 membrane_V_prime = 0;
00208 }
00209
00210 rDY[0] = fast_sodium_current_h_gate_h_prime;
00211 rDY[1] = fast_sodium_current_j_gate_j_prime;
00212 rDY[2] = fast_sodium_current_m_gate_m_prime;
00213 rDY[3] = intracellular_calcium_concentration_Cai_prime;
00214 rDY[4] = membrane_V_prime;
00215 rDY[5] = slow_inward_current_d_gate_d_prime;
00216 rDY[6] = slow_inward_current_f_gate_f_prime;
00217 rDY[7] = time_dependent_potassium_current_X_gate_X_prime;
00218 }
00219
00220
00221 double LuoRudyIModel1991OdeSystem::GetIIonic()
00222 {
00223 double fast_sodium_current_h_gate_h = mStateVariables[0];
00224 double fast_sodium_current_j_gate_j = mStateVariables[1];
00225 double fast_sodium_current_m_gate_m = mStateVariables[2];
00226 double intracellular_calcium_concentration_Cai = mStateVariables[3];
00227 double membrane_V = mStateVariables[4];
00228 double slow_inward_current_d_gate_d = mStateVariables[5];
00229 double slow_inward_current_f_gate_f = mStateVariables[6];
00230 double time_dependent_potassium_current_X_gate_X = mStateVariables[7];
00231
00232
00233
00234
00235 double background_current_i_b = background_current_g_b*(membrane_V-background_current_E_b);
00236
00237 double fast_sodium_current_i_Na = fast_sodium_current_g_Na*pow(fast_sodium_current_m_gate_m, 3.0)*fast_sodium_current_h_gate_h*fast_sodium_current_j_gate_j*(membrane_V-fast_sodium_current_E_Na);
00238
00239 double slow_inward_current_E_si = 7.7-13.0287*log(intracellular_calcium_concentration_Cai);
00240 double slow_inward_current_i_si = 0.09*slow_inward_current_d_gate_d*slow_inward_current_f_gate_f*(membrane_V-slow_inward_current_E_si);
00241
00242 double time_dependent_potassium_current_g_K = 0.282*sqrt(ionic_concentrations_Ko/5.4);
00243 double time_dependent_potassium_current_Xi_gate_Xi;
00244
00245
00246
00247 if (membrane_V > -100.0)
00248 {
00249 time_dependent_potassium_current_Xi_gate_Xi = 2.837*(exp(0.04*(membrane_V+77.0))-1.0)/((membrane_V+77.0)*exp(0.04*(membrane_V+35.0)));
00250 }
00251 else
00252 {
00253 #define COVERAGE_IGNORE
00254 time_dependent_potassium_current_Xi_gate_Xi = 1.0;
00255 #undef COVERAGE_IGNORE
00256 }
00257 double time_dependent_potassium_current_E_K = ((membrane_R*membrane_T)/membrane_F)*log((ionic_concentrations_Ko+time_dependent_potassium_current_PR_NaK*ionic_concentrations_Nao)/(ionic_concentrations_Ki+time_dependent_potassium_current_PR_NaK*ionic_concentrations_Nai));
00258 double time_dependent_potassium_current_i_K = time_dependent_potassium_current_g_K*time_dependent_potassium_current_X_gate_X*time_dependent_potassium_current_Xi_gate_Xi*(membrane_V-time_dependent_potassium_current_E_K);
00259
00260 double time_independent_potassium_current_g_K1 = 0.6047*sqrt(ionic_concentrations_Ko/5.4);
00261 double time_independent_potassium_current_E_K1 =((membrane_R*membrane_T)/membrane_F)*log(ionic_concentrations_Ko/ionic_concentrations_Ki);
00262 double time_independent_potassium_current_K1_gate_alpha_K1 = 1.02/(1.0+exp(0.2385*(membrane_V-time_independent_potassium_current_E_K1-59.215)));
00263 double time_independent_potassium_current_K1_gate_beta_K1 = (0.49124*exp(0.08032*(membrane_V+5.476-time_independent_potassium_current_E_K1))+exp(0.06175*(membrane_V-(time_independent_potassium_current_E_K1+594.31))))/(1.0+exp(-0.5143*(membrane_V-time_independent_potassium_current_E_K1+4.753)));
00264 double time_independent_potassium_current_K1_gate_K1_infinity = time_independent_potassium_current_K1_gate_alpha_K1/(time_independent_potassium_current_K1_gate_alpha_K1+time_independent_potassium_current_K1_gate_beta_K1);
00265 double time_independent_potassium_current_i_K1 = time_independent_potassium_current_g_K1*time_independent_potassium_current_K1_gate_K1_infinity*(membrane_V-time_independent_potassium_current_E_K1);
00266
00267 double plateau_potassium_current_Kp = 1.0/(1.0+exp((7.488-membrane_V)/5.98));
00268 double plateau_potassium_current_E_Kp = time_independent_potassium_current_E_K1;
00269 double plateau_potassium_current_i_Kp = plateau_potassium_current_g_Kp*plateau_potassium_current_Kp*(membrane_V-plateau_potassium_current_E_Kp);
00270
00271 double i_ionic = fast_sodium_current_i_Na+slow_inward_current_i_si+time_dependent_potassium_current_i_K+time_independent_potassium_current_i_K1+plateau_potassium_current_i_Kp+background_current_i_b;
00272
00273 assert(!std::isnan(i_ionic));
00274 return i_ionic;
00275 }
00276
00277 void LuoRudyIModel1991OdeSystem::VerifyStateVariables()
00278 {
00279 const std::vector<double>& rY = rGetStateVariables();
00280
00281 const double fast_sodium_current_h_gate_h = rY[0];
00282 const double fast_sodium_current_j_gate_j = rY[1];
00283 const double fast_sodium_current_m_gate_m = rY[2];
00284 const double intracellular_calcium_concentration_Cai = rY[3];
00285 const double slow_inward_current_d_gate_d = rY[5];
00286 const double slow_inward_current_f_gate_f = rY[6];
00287 const double time_dependent_potassium_current_X_gate_X = rY[7];
00288
00289 #define COVERAGE_IGNORE
00290 if (!(0.0<=fast_sodium_current_h_gate_h && fast_sodium_current_h_gate_h<=1.0))
00291 {
00292 EXCEPTION(DumpState("h gate for fast sodium current has gone out of range. Check model parameters, for example spatial stepsize"));
00293 }
00294
00295 if (!(0.0<=fast_sodium_current_j_gate_j && fast_sodium_current_j_gate_j<=1.0))
00296 {
00297 EXCEPTION(DumpState("j gate for fast sodium current has gone out of range. Check model parameters, for example spatial stepsize"));
00298 }
00299
00300 if (!(0.0<=fast_sodium_current_m_gate_m && fast_sodium_current_m_gate_m<=1.0))
00301 {
00302 EXCEPTION(DumpState("m gate for fast sodium current has gone out of range. Check model parameters, for example spatial stepsize"));
00303 }
00304
00305 if (!(0.0<intracellular_calcium_concentration_Cai))
00306 {
00307 EXCEPTION(DumpState("intracellular_calcium_concentration_Cai has become non-positive, ie gone out of range. Check model parameters, for example spatial stepsize"));
00308 }
00309
00310 if (!(0.0<=slow_inward_current_d_gate_d && slow_inward_current_d_gate_d<=1.0))
00311 {
00312 EXCEPTION(DumpState("d gate for slow inward current has gone out of range. Check model parameters, for example spatial stepsize"));
00313 }
00314
00315 if (!(0.0<=slow_inward_current_f_gate_f && slow_inward_current_f_gate_f<=1.0))
00316 {
00317 EXCEPTION(DumpState("f gate for slow inward current has gone out of range. Check model parameters, for example spatial stepsize"));
00318 }
00319
00320 if (!(0.0<=time_dependent_potassium_current_X_gate_X && time_dependent_potassium_current_X_gate_X<=1.0))
00321 {
00322 EXCEPTION(DumpState("X gate for time dependent potassium current has gone out of range. Check model parameters, for example spatial stepsize"));
00323 }
00324 #undef COVERAGE_IGNORE
00325 }
00326
00327
00328
00329
00330 template<>
00331 void OdeSystemInformation<LuoRudyIModel1991OdeSystem>::Initialise(void)
00332 {
00333
00334 this->mVariableNames.push_back("h");
00335 this->mVariableUnits.push_back("");
00336 this->mInitialConditions.push_back(0.9804713);
00337
00338 this->mVariableNames.push_back("j");
00339 this->mVariableUnits.push_back("");
00340 this->mInitialConditions.push_back(0.98767124);
00341
00342 this->mVariableNames.push_back("m");
00343 this->mVariableUnits.push_back("");
00344 this->mInitialConditions.push_back(0.00187018);
00345
00346 this->mVariableNames.push_back("CaI");
00347 this->mVariableUnits.push_back("mMol");
00348 this->mInitialConditions.push_back(0.0002);
00349
00350 this->mVariableNames.push_back("V");
00351 this->mVariableUnits.push_back("mV");
00352 this->mInitialConditions.push_back(-83.853);
00353
00354 this->mVariableNames.push_back("d");
00355 this->mVariableUnits.push_back("");
00356 this->mInitialConditions.push_back(0.00316354);
00357
00358 this->mVariableNames.push_back("f");
00359 this->mVariableUnits.push_back("");
00360 this->mInitialConditions.push_back(0.99427859);
00361
00362 this->mVariableNames.push_back("x");
00363 this->mVariableUnits.push_back("");
00364 this->mInitialConditions.push_back(0.16647703);
00365
00366 this->mInitialised = true;
00367 }