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
00033 #include "Exception.hpp"
00034
00038 LuoRudyIModel1991OdeSystem::LuoRudyIModel1991OdeSystem(AbstractIvpOdeSolver *pSolver,
00039 AbstractStimulusFunction *pIntracellularStimulus)
00040 : AbstractCardiacCell(pSolver, 8, 4, pIntracellularStimulus)
00041 {
00042 mpSystemInfo = OdeSystemInformation<LuoRudyIModel1991OdeSystem>::Instance();
00043
00044
00045 fast_sodium_current_E_Na = ((membrane_R * membrane_T) / membrane_F) *
00046 log(ionic_concentrations_Nao / ionic_concentrations_Nai);
00047
00048 AbstractCardiacCell::Init();
00049 }
00050
00054 LuoRudyIModel1991OdeSystem::~LuoRudyIModel1991OdeSystem(void)
00055 {
00056 }
00057
00058 double LuoRudyIModel1991OdeSystem::GetIntracellularCalciumConcentration()
00059 {
00060 return mStateVariables[3];
00061 }
00062
00072 void LuoRudyIModel1991OdeSystem::EvaluateYDerivatives(double time,
00073 const std::vector<double> &rY,
00074 std::vector<double> &rDY)
00075 {
00076 double fast_sodium_current_h_gate_h = rY[0];
00077 double fast_sodium_current_j_gate_j = rY[1];
00078 double fast_sodium_current_m_gate_m = rY[2];
00079 double intracellular_calcium_concentration_Cai = rY[3];
00080 double membrane_V = rY[4];
00081 double slow_inward_current_d_gate_d = rY[5];
00082 double slow_inward_current_f_gate_f = rY[6];
00083 double time_dependent_potassium_current_X_gate_X = rY[7];
00084
00085 double background_current_i_b = background_current_g_b*(membrane_V-background_current_E_b);
00086
00087 double fast_sodium_current_h_gate_alpha_h;
00088
00089 if (membrane_V < -40.0)
00090 {
00091 fast_sodium_current_h_gate_alpha_h = 0.135*exp((80.0+membrane_V)/-6.8);
00092 }
00093 else
00094 {
00095 fast_sodium_current_h_gate_alpha_h = 0.0;
00096 }
00097
00098 double fast_sodium_current_h_gate_beta_h;
00099
00100 if (membrane_V < -40.0)
00101 {
00102 fast_sodium_current_h_gate_beta_h = 3.56*exp(0.079*membrane_V)+3.1e5*exp(0.35*membrane_V);
00103 }
00104 else
00105 {
00106 fast_sodium_current_h_gate_beta_h = 1.0/(0.13*(1.0+exp((membrane_V+10.66)/-11.1)));
00107 }
00108
00109 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;
00110
00111 double fast_sodium_current_j_gate_alpha_j;
00112
00113 if (membrane_V < -40.0)
00114 {
00115 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)));
00116 }
00117 else
00118 {
00119 fast_sodium_current_j_gate_alpha_j = 0.0;
00120 }
00121
00122 double fast_sodium_current_j_gate_beta_j;
00123
00124 if (membrane_V < -40.0)
00125 {
00126 fast_sodium_current_j_gate_beta_j = 0.1212*exp(-0.01052*membrane_V)/(1.0+exp(-0.1378*(membrane_V+40.14)));
00127 }
00128 else
00129 {
00130 fast_sodium_current_j_gate_beta_j = 0.3*exp(-2.535e-7*membrane_V)/(1.0+exp(-0.1*(membrane_V+32.0)));
00131 }
00132
00133 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;
00134 double fast_sodium_current_m_gate_alpha_m = 0.32*(membrane_V+47.13)/(1.0-exp(-0.1*(membrane_V+47.13)));
00135 double fast_sodium_current_m_gate_beta_m = 0.08*exp(-membrane_V/11.0);
00136 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;
00137 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);
00138
00139 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)));
00140 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)));
00141 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;
00142
00143 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)));
00144 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)));
00145 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;
00146
00147 double slow_inward_current_E_si = 7.7-13.0287*log(intracellular_calcium_concentration_Cai);
00148 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);
00149 double intracellular_calcium_concentration_Cai_prime = -1e-4*slow_inward_current_i_si+0.07*(1e-4-intracellular_calcium_concentration_Cai);
00150 double time_dependent_potassium_current_g_K = 0.282*sqrt(ionic_concentrations_Ko/5.4);
00151
00152 double time_dependent_potassium_current_Xi_gate_Xi;
00153
00154 if (membrane_V > -100.0)
00155 {
00156 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)));
00157 }
00158 else
00159 {
00160 #define COVERAGE_IGNORE
00161 time_dependent_potassium_current_Xi_gate_Xi = 1.0;
00162 #undef COVERAGE_IGNORE
00163 }
00164
00165 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)));
00166 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)));
00167 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;
00168
00169 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));
00170 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);
00171 double time_independent_potassium_current_g_K1 = 0.6047*sqrt(ionic_concentrations_Ko/5.4);
00172 double time_independent_potassium_current_E_K1 =((membrane_R*membrane_T)/membrane_F)*log(ionic_concentrations_Ko/ionic_concentrations_Ki);
00173 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)));
00174 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)));
00175 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);
00176 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);
00177 double plateau_potassium_current_Kp = 1.0/(1.0+exp((7.488-membrane_V)/5.98));
00178 double plateau_potassium_current_E_Kp = time_independent_potassium_current_E_K1;
00179 double plateau_potassium_current_i_Kp = plateau_potassium_current_g_Kp*plateau_potassium_current_Kp*(membrane_V-plateau_potassium_current_E_Kp);
00180 double i_stim = GetStimulus(time);
00181
00182
00183 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);
00184
00185 if (mSetVoltageDerivativeToZero)
00186 {
00187 membrane_V_prime = 0;
00188 }
00189
00190 rDY[0] = fast_sodium_current_h_gate_h_prime;
00191 rDY[1] = fast_sodium_current_j_gate_j_prime;
00192 rDY[2] = fast_sodium_current_m_gate_m_prime;
00193 rDY[3] = intracellular_calcium_concentration_Cai_prime;
00194 rDY[4] = membrane_V_prime;
00195 rDY[5] = slow_inward_current_d_gate_d_prime;
00196 rDY[6] = slow_inward_current_f_gate_f_prime;
00197 rDY[7] = time_dependent_potassium_current_X_gate_X_prime;
00198 }
00199
00200
00201 double LuoRudyIModel1991OdeSystem::GetIIonic()
00202 {
00203 double fast_sodium_current_h_gate_h = mStateVariables[0];
00204 double fast_sodium_current_j_gate_j = mStateVariables[1];
00205 double fast_sodium_current_m_gate_m = mStateVariables[2];
00206 double intracellular_calcium_concentration_Cai = mStateVariables[3];
00207 double membrane_V = mStateVariables[4];
00208 double slow_inward_current_d_gate_d = mStateVariables[5];
00209 double slow_inward_current_f_gate_f = mStateVariables[6];
00210 double time_dependent_potassium_current_X_gate_X = mStateVariables[7];
00211
00212
00213
00214
00215 double background_current_i_b = background_current_g_b*(membrane_V-background_current_E_b);
00216
00217 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);
00218
00219 double slow_inward_current_E_si = 7.7-13.0287*log(intracellular_calcium_concentration_Cai);
00220 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);
00221
00222 double time_dependent_potassium_current_g_K = 0.282*sqrt(ionic_concentrations_Ko/5.4);
00223 double time_dependent_potassium_current_Xi_gate_Xi;
00224
00225
00226
00227 if (membrane_V > -100.0)
00228 {
00229 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)));
00230 }
00231 else
00232 {
00233 #define COVERAGE_IGNORE
00234 time_dependent_potassium_current_Xi_gate_Xi = 1.0;
00235 #undef COVERAGE_IGNORE
00236 }
00237 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));
00238 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);
00239
00240 double time_independent_potassium_current_g_K1 = 0.6047*sqrt(ionic_concentrations_Ko/5.4);
00241 double time_independent_potassium_current_E_K1 =((membrane_R*membrane_T)/membrane_F)*log(ionic_concentrations_Ko/ionic_concentrations_Ki);
00242 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)));
00243 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)));
00244 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);
00245 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);
00246
00247 double plateau_potassium_current_Kp = 1.0/(1.0+exp((7.488-membrane_V)/5.98));
00248 double plateau_potassium_current_E_Kp = time_independent_potassium_current_E_K1;
00249 double plateau_potassium_current_i_Kp = plateau_potassium_current_g_Kp*plateau_potassium_current_Kp*(membrane_V-plateau_potassium_current_E_Kp);
00250
00251 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;
00252
00253 assert(!isnan(i_ionic));
00254 return i_ionic;
00255 }
00256
00257 void LuoRudyIModel1991OdeSystem::VerifyStateVariables()
00258 {
00259 const std::vector<double>& rY = rGetStateVariables();
00260
00261 const double fast_sodium_current_h_gate_h = rY[0];
00262 const double fast_sodium_current_j_gate_j = rY[1];
00263 const double fast_sodium_current_m_gate_m = rY[2];
00264 const double intracellular_calcium_concentration_Cai = rY[3];
00265 const double slow_inward_current_d_gate_d = rY[5];
00266 const double slow_inward_current_f_gate_f = rY[6];
00267 const double time_dependent_potassium_current_X_gate_X = rY[7];
00268
00269 #define COVERAGE_IGNORE
00270 if (!(0.0<=fast_sodium_current_h_gate_h && fast_sodium_current_h_gate_h<=1.0))
00271 {
00272 EXCEPTION(DumpState("h gate for fast sodium current has gone out of range. Check model parameters, for example spatial stepsize"));
00273 }
00274
00275 if (!(0.0<=fast_sodium_current_j_gate_j && fast_sodium_current_j_gate_j<=1.0))
00276 {
00277 EXCEPTION(DumpState("j gate for fast sodium current has gone out of range. Check model parameters, for example spatial stepsize"));
00278 }
00279
00280 if (!(0.0<=fast_sodium_current_m_gate_m && fast_sodium_current_m_gate_m<=1.0))
00281 {
00282 EXCEPTION(DumpState("m gate for fast sodium current has gone out of range. Check model parameters, for example spatial stepsize"));
00283 }
00284
00285 if (!(0.0<intracellular_calcium_concentration_Cai))
00286 {
00287 EXCEPTION(DumpState("intracellular_calcium_concentration_Cai has become non-positive, ie gone out of range. Check model parameters, for example spatial stepsize"));
00288 }
00289
00290 if (!(0.0<=slow_inward_current_d_gate_d && slow_inward_current_d_gate_d<=1.0))
00291 {
00292 EXCEPTION(DumpState("d gate for slow inward current has gone out of range. Check model parameters, for example spatial stepsize"));
00293 }
00294
00295 if (!(0.0<=slow_inward_current_f_gate_f && slow_inward_current_f_gate_f<=1.0))
00296 {
00297 EXCEPTION(DumpState("f gate for slow inward current has gone out of range. Check model parameters, for example spatial stepsize"));
00298 }
00299
00300 if (!(0.0<=time_dependent_potassium_current_X_gate_X && time_dependent_potassium_current_X_gate_X<=1.0))
00301 {
00302 EXCEPTION(DumpState("X gate for time dependent potassium current has gone out of range. Check model parameters, for example spatial stepsize"));
00303 }
00304 #undef COVERAGE_IGNORE
00305 }
00306
00307
00308
00309
00310 template<>
00311 void OdeSystemInformation<LuoRudyIModel1991OdeSystem>::Initialise(void)
00312 {
00313
00314 this->mVariableNames.push_back("h");
00315 this->mVariableUnits.push_back("");
00316 this->mInitialConditions.push_back(0.9804713);
00317
00318 this->mVariableNames.push_back("j");
00319 this->mVariableUnits.push_back("");
00320 this->mInitialConditions.push_back(0.98767124);
00321
00322 this->mVariableNames.push_back("m");
00323 this->mVariableUnits.push_back("");
00324 this->mInitialConditions.push_back(0.00187018);
00325
00326 this->mVariableNames.push_back("CaI");
00327 this->mVariableUnits.push_back("mMol");
00328 this->mInitialConditions.push_back(0.0002);
00329
00330 this->mVariableNames.push_back("V");
00331 this->mVariableUnits.push_back("mV");
00332 this->mInitialConditions.push_back(-83.853);
00333
00334 this->mVariableNames.push_back("d");
00335 this->mVariableUnits.push_back("");
00336 this->mInitialConditions.push_back(0.00316354);
00337
00338 this->mVariableNames.push_back("f");
00339 this->mVariableUnits.push_back("");
00340 this->mInitialConditions.push_back(0.99427859);
00341
00342 this->mVariableNames.push_back("x");
00343 this->mVariableUnits.push_back("");
00344 this->mInitialConditions.push_back(0.16647703);
00345
00346 this->mInitialised = true;
00347 }