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 "DiFrancescoNoble1985OdeSystem.hpp"
00029 #include "OdeSystemInformation.hpp"
00030 #include <cmath>
00031 #include <cstdio>
00032
00033 #include "Exception.hpp"
00034
00035
00036
00037 DiFrancescoNoble1985OdeSystem::DiFrancescoNoble1985OdeSystem(AbstractIvpOdeSolver *pSolver,
00038 AbstractStimulusFunction *pIntracellularStimulus)
00039 : AbstractCardiacCell(pSolver, 16, 0, pIntracellularStimulus)
00040 {
00041 mpSystemInfo = OdeSystemInformation<DiFrancescoNoble1985OdeSystem>::Instance();
00042
00043
00044 Vcell= 3.141592654*pow(radius,2)*length;
00045 Vi=Vcell*(1.0-V_e_ratio);
00046 Vup=0.05*Vi;
00047 Vrel=0.02*Vi;
00048 Ve=Vi/(1.0-Vecs);
00049 RToNF=R*T/F;
00050
00051
00052 AbstractCardiacCell::Init();
00053 }
00054
00058 DiFrancescoNoble1985OdeSystem::~DiFrancescoNoble1985OdeSystem(void)
00059 {
00060 }
00061
00071 void DiFrancescoNoble1985OdeSystem::EvaluateYDerivatives(double time,
00072 const std::vector<double> &rY,
00073 std::vector<double> &rDY)
00074 {
00075 double Vm = rY[0];
00076 double y_gate = rY[1];
00077 double s_gate = rY[2];
00078 double m_gate = rY[3];
00079 double h_gate = rY[4];
00080 double d_gate= rY[5];
00081 double f_gate = rY[6];
00082 double f2_gate = rY[7];
00083 double p = rY[8];
00084 double Nai = rY[9];
00085 double Cai = rY[10];
00086 double Kc = rY[11];
00087 double Ki = rY[12];
00088 double x_gate = rY[13];
00089 double Ca_up = rY[14];
00090 double Ca_rel = rY[15];
00091 VerifyStateVariables();
00092
00094
00096 double Emh=RToNF*log((Nao+0.12*Kc)/(Nai+0.12*Ki));
00097 double E_na=RToNF*log(Nao/Nai);
00098 double E_k=RToNF*log(Kc/Ki);
00099 double E_ca=0.5*RToNF*log(Cao/Cai);
00100
00101 double i_fk=(Kc/(Kc+Kmf))*(g_fk*(Vm-E_k));
00102 double i_fna=(Kc/(Kc+Kmf))*g_fna*(Vm-E_na);
00103 double alpha_y=0.001*0.05*exp(-0.067*(Vm+52.0-10.0));
00104 double beta_y;
00105
00106 if(fabs(Vm+52.0-10.0)<=0.0001)
00107 {
00108 #define COVERAGE_IGNORE
00109 beta_y=2.5*0.001;
00110 #undef COVERAGE_IGNORE
00111 }
00112 else
00113 {
00114 beta_y=0.001*(Vm+52.0-10.0)/(1.0-exp(-0.2*(Vm+52.0-10.0)));
00115 }
00116 double y_gate_prime=alpha_y*(1.0-y_gate)-beta_y*y_gate;
00117
00118
00119 double I_K=i_kmax*(Ki-Kc*exp(-Vm/RToNF))/140.0;
00120 double alpha_x=0.001*0.5*exp(0.0826*(Vm+50.0))/(1.0+exp(0.057*(Vm+50.0)));
00121 double beta_x=0.001*1.3*exp(-0.06*(Vm+20.0))/(1.0+exp(-0.04*(Vm+20.0)));
00122 double x_gate_prime=alpha_x*(1.0-x_gate)-beta_x*x_gate;
00123
00124
00125 double alpha_s=0.001*0.033*exp(-Vm/17.0);
00126 double beta_s=0.001*33.0/(1.0+exp(-(Vm+10.0)/8.0));
00127 double s_gate_prime=alpha_s*(1.0-s_gate)-beta_s*s_gate;
00128
00129
00130 double alpha_m;
00131 if(fabs(Vm+41.0)<=0.00001)
00132 {
00133 #define COVERAGE_IGNORE
00134 alpha_m=2000*0.001;
00135 #undef COVERAGE_IGNORE
00136 }
00137 else
00138 {
00139 alpha_m=0.001*200.0*(Vm+41.0)/(1.0-exp(-0.1*(Vm+41.0)));
00140 }
00141
00142 double beta_m=0.001*8000*exp(-0.056*(Vm+66.0));
00143
00144 double m_gate_prime=alpha_m*(1.0-m_gate)-beta_m*m_gate;
00145
00146 double alpha_h=0.001*20*exp(-0.125*(Vm+75.0));
00147 double beta_h=0.001*2000.0/(320.0*exp(-0.1*(Vm+75.0))+1.0);
00148 double h_gate_prime=alpha_h*(1.0-h_gate)-beta_h*h_gate;
00149
00150
00151 double alpha_d;
00152 if(fabs(Vm+24.0-5.0)<=0.0001)
00153 {
00154 #define COVERAGE_IGNORE
00155 alpha_d=120*0.001;
00156 #undef COVERAGE_IGNORE
00157 }
00158 else
00159 {
00160 alpha_d=0.001*30*(Vm+24.0-5.0)/(1.0-exp(-(Vm+24.0-5.0)/4.0));
00161 }
00162
00163 double beta_d;
00164 if(fabs(Vm+24.0-5.0)<=0.0001)
00165 {
00166 #define COVERAGE_IGNORE
00167 beta_d=120*0.001;
00168 #undef COVERAGE_IGNORE
00169 }
00170 else
00171 {
00172 beta_d=0.001*12.0*(Vm+24.0-5.0)/(exp((Vm+24.0-5.0)/10.0)-1.0);
00173 }
00174 double d_gate_prime=alpha_d*(1.0-d_gate)-beta_d*d_gate;
00175
00176
00177 double alpha_f;
00178 if(fabs(Vm+34)<=0.0001)
00179 {
00180 #define COVERAGE_IGNORE
00181 alpha_f=25*0.001;
00182 #undef COVERAGE_IGNORE
00183 }
00184 else
00185 {
00186 alpha_f=0.001*6.25*(Vm+34.0)/(exp((Vm+34.0)/4.0)-1.0);
00187 }
00188 double beta_f=0.001*50.0/(1.0+exp(-(Vm+34.0)/4.0));
00189
00190 double f_gate_prime=alpha_f*(1.0-f_gate)-beta_f*f_gate;
00191
00192
00193 double alpha_f2=0.001*5.0;
00194 double beta_f2=0.001*Cai*alpha_f2/Kmf2;
00195 double f2_gate_prime=alpha_f2-(f2_gate*(alpha_f2+beta_f2));
00196
00197
00198 double alpha_p=0.001*(0.625*(Vm+34.0))/(exp((Vm+34.0)/4.0)-1.0);
00199 double beta_p=0.001*5.0/(1.0+exp(-(Vm+34.0)/4.0));
00200 double p_prime=alpha_p*(1.0-p)-beta_p*p;
00201
00202
00203
00204 double i_na=g_na*pow(m_gate,3)*h_gate*(Vm-Emh);
00205
00206
00207 double i_f=y_gate*(i_fk+i_fna);
00208
00209 double i_k=x_gate*I_K;
00210
00211 double i_k1=(g_k1*Kc/(Kc+Km1))*(Vm-E_k)/(1.0+exp((Vm-E_k+10)*2.0/RToNF));
00212
00213 double i_to=((((s_gate*g_to*Cai*(0.2+Kc/(Kmto+Kc)))/(Km_Ca+Cai))*(Vm+10.0))/(1.0-exp(-0.2*(Vm+10.0))))*((Ki*exp((Vm*0.5)/RToNF))-(Kc*exp(-0.5*Vm/RToNF)));
00214
00215 double i_na_b=g_na_b*(Vm-E_na);
00216
00217 double i_p=((I_P*Kc)/(KmK+Kc))*Nai/(Nai+KmNa);
00218
00219 double i_naca=(k_naca*((Cao*(exp((gamma*Vm*(n_naca-2))/(RToNF)))*(pow(Nai,n_naca)))-(Cai*(exp(((gamma-1.0)*(n_naca-2.0)*Vm)/(RToNF)))*(pow(Nao,n_naca)))))/((1.0+(d_naca*((Cai*pow(Nao,n_naca))+(Cao*pow(Nai,n_naca)))))*(1.0+(Cai/0.0069)));
00220
00221 double i_ca_b=g_ca_b*(Vm-E_ca);
00222
00223
00224 double i_sica=((4.0*P_si*(Vm-50.0))/(RToNF*(1.0-(exp((-2.0*(Vm-50.0))/RToNF)))))*((Cai*exp(100.0/RToNF))-(Cao*exp(-2.0*(Vm-50.0)/RToNF)))*d_gate*f_gate*f2_gate;
00225 double i_sik=((0.01*P_si*(Vm-50.0))/(RToNF*(1.0-(exp((-(Vm-50.0))/RToNF)))))*((Ki*exp(50.0/RToNF))-(Kc*exp(-(Vm-50.0)/RToNF)))*d_gate*f_gate*f2_gate;
00226 double i_sina=((0.01*P_si*(Vm-50.0))/(RToNF*(1.0-(exp((-(Vm-50.0))/RToNF)))))*((Nai*exp(50.0/RToNF))-(Nao*exp(-(Vm-50.0)/RToNF)))*d_gate*f_gate*f2_gate;
00227 double i_si=i_sik+i_sica+i_sina;
00228
00229
00230 double Nai_prime= -0.001*(i_na+i_na_b+i_fna+i_sina+3*i_p+(n_naca*i_naca)/(n_naca-2.0))/(Vi*F);
00231
00232
00233 double i_up=(2*F*Vi/(tau_up*Ca_up_max))*Cai*(Ca_up_max-Ca_up);
00234 double i_tr=(2*F*Vrel/tau_rep)*p*(Ca_up-Ca_rel);
00235 double i_rel=(2*F*Vrel/tau_rel)*Ca_rel*(pow(Cai,rCa))/(pow(Cai,rCa)+pow(KmCa,rCa));
00236
00237 double Ca_up_prime=0.001*(i_up-i_tr)/(2*Vup*F);
00238 double Ca_rel_prime=0.001*(i_tr-i_rel)/(2*Vrel*F);
00239 double Cai_prime=-0.001*(i_sica+i_ca_b+i_up-i_rel-2*(i_naca/(n_naca-2.0)))/(2*Vi*F);
00240
00241
00242 double i_mk=(i_k1+i_k+i_fk+i_sik+i_to-2*i_p);
00243 double Kc_prime=i_mk*0.001/(F*Ve)-pf*(Kc-Kb);
00244 double Ki_prime=(-i_mk*0.001/(Vi*F));
00245
00246
00247 double i_stim = GetStimulus(time);
00248
00249
00250 double Vm_prime = (-1.0/membrane_C)*(i_f+
00251 i_k+
00252 i_k1+
00253 i_to+
00254 i_na_b+
00255 i_p+
00256 i_naca+
00257 i_ca_b+
00258 i_na+
00259 i_si+
00260 i_stim);
00261
00262 if (mSetVoltageDerivativeToZero)
00263 {
00264 Vm_prime = 0;
00265 }
00266
00267 rDY[0] = Vm_prime;
00268 rDY[1] = y_gate_prime;
00269 rDY[2] = s_gate_prime;
00270 rDY[3] = m_gate_prime;
00271 rDY[4] = h_gate_prime;
00272 rDY[5] = d_gate_prime;
00273 rDY[6] = f_gate_prime;
00274 rDY[7] = f2_gate_prime;
00275 rDY[8] = p_prime;
00276 rDY[9] = Nai_prime;
00277 rDY[10]= Cai_prime;
00278 rDY[11] = Kc_prime;
00279 rDY[12] = Ki_prime;
00280 rDY[13] = x_gate_prime;
00281 rDY[14] = Ca_up_prime;
00282 rDY[15] = Ca_rel_prime;
00283 }
00284
00285
00286 double DiFrancescoNoble1985OdeSystem::GetIIonic()
00287 {
00288
00289 double Vm = mStateVariables[0];
00290 double y_gate = mStateVariables[1];
00291 double s_gate = mStateVariables[2];
00292 double m_gate = mStateVariables[3];
00293 double h_gate = mStateVariables[4];
00294 double d_gate= mStateVariables[5];
00295 double f_gate = mStateVariables[6];
00296 double f2_gate = mStateVariables[7];
00297
00298 double Nai = mStateVariables[9];
00299 double Cai = mStateVariables[10];
00300 double Kc = mStateVariables[11];
00301 double Ki = mStateVariables[12];
00302 double x_gate = mStateVariables[13];
00303
00304
00305
00306
00307
00308
00309 double Emh=RToNF*log((Nao+0.12*Kc)/(Nai+0.12*Ki));
00310 double E_na=RToNF*log(Nao/Nai);
00311 double E_k=RToNF*log(Kc/Ki);
00312 double E_ca=0.5*RToNF*log(Cao/Cai);
00313
00314
00315 double i_na=g_na*pow(m_gate,3)*h_gate*(Vm-Emh);
00316
00317 double i_fk=(Kc/(Kc+Kmf))*(g_fk*(Vm-E_k));
00318 double i_fna=(Kc/(Kc+Kmf))*g_fna*(Vm-E_na);
00319 double i_f=y_gate*(i_fk+i_fna);
00320
00321 double I_K=i_kmax*(Ki-Kc*exp(-Vm/RToNF))/140.0;
00322 double i_k=x_gate*I_K;
00323
00324 double i_k1=(g_k1*Kc/(Kc+Km1))*(Vm-E_k)/(1.0+exp((Vm-E_k+10)*2.0/RToNF));
00325
00326 double i_to=((((s_gate*g_to*Cai*(0.2+Kc/(Kmto+Kc)))/(Km_Ca+Cai))*(Vm+10.0))/(1.0-exp(-0.2*(Vm+10.0))))*((Ki*exp((Vm*0.5)/RToNF))-(Kc*exp(-0.5*Vm/RToNF)));
00327
00328 double i_na_b=g_na_b*(Vm-E_na);
00329
00330 double i_p=((I_P*Kc)/(KmK+Kc))*Nai/(Nai+KmNa);
00331
00332 double i_naca=(k_naca*((Cao*(exp((gamma*Vm*(n_naca-2))/(RToNF)))*(pow(Nai,n_naca)))-(Cai*(exp(((gamma-1.0)*(n_naca-2.0)*Vm)/(RToNF)))*(pow(Nao,n_naca)))))/((1.0+(d_naca*((Cai*pow(Nao,n_naca))+(Cao*pow(Nai,n_naca)))))*(1.0+(Cai/0.0069)));
00333
00334 double i_ca_b=g_ca_b*(Vm-E_ca);
00335
00336 double i_sica=((4.0*P_si*(Vm-50.0))/(RToNF*(1.0-(exp((-2.0*(Vm-50.0))/RToNF)))))*((Cai*exp(100.0/RToNF))-(Cao*exp(-2.0*(Vm-50.0)/RToNF)))*d_gate*f_gate*f2_gate;
00337 double i_sik=((0.01*P_si*(Vm-50.0))/(RToNF*(1.0-(exp((-(Vm-50.0))/RToNF)))))*((Ki*exp(50.0/RToNF))-(Kc*exp(-(Vm-50.0)/RToNF)))*d_gate*f_gate*f2_gate;
00338 double i_sina=((0.01*P_si*(Vm-50.0))/(RToNF*(1.0-(exp((-(Vm-50.0))/RToNF)))))*((Nai*exp(50.0/RToNF))-(Nao*exp(-(Vm-50.0)/RToNF)))*d_gate*f_gate*f2_gate;
00339 double i_si=i_sik+i_sica+i_sina;
00340
00341 double i_ionic = (i_f+
00342 i_k+
00343 i_k1+
00344 i_to+
00345 i_na_b+
00346 i_p+
00347 i_naca+
00348 i_ca_b+
00349 i_na+
00350 i_si);
00351
00352 assert(!isnan(i_ionic));
00353
00354 double i_ionic_in_microA_per_cm2=i_ionic*pow(10,-3)/0.075;
00355 return i_ionic_in_microA_per_cm2;
00356
00357
00358
00359
00360
00361
00362
00363 }
00364
00365 void DiFrancescoNoble1985OdeSystem::VerifyStateVariables()
00366 {
00367
00368 const std::vector<double>& rY = rGetStateVariables();
00369
00370 const double Vm = rY[0];
00371 const double y_gate = rY[1];
00372 const double r_gate = rY[2];
00373 const double m_gate = rY[3];
00374 const double h_gate = rY[4];
00375 const double d_gate= rY[5];
00376 const double f_gate = rY[6];
00377 const double f2_gate = rY[7];
00378 const double p = rY[8];
00379 const double Nai = rY[9];
00380 const double Cai = rY[10];
00381 const double Kc = rY[11];
00382 const double Ki = rY[12];
00383 const double x_gate = rY[13];
00384 const double Ca_up = rY[14];
00385 const double Ca_rel = rY[15];
00386 #define COVERAGE_IGNORE
00387 if (!(200>=Vm && Vm>=-200))
00388 {
00389 EXCEPTION(DumpState("Vm is really out of range!"));
00390 }
00391 if (!(0.0<=y_gate && y_gate<=1.0))
00392 {
00393 EXCEPTION(DumpState("y gate has gone out of range. Check model parameters, for example spatial stepsize"));
00394 }
00395 if (!(0.0<=r_gate && r_gate<=1.0))
00396 {
00397 EXCEPTION(DumpState("r gate has gone out of range. Check model parameters, for example spatial stepsize"));
00398 }
00399 if (!(0.0<=m_gate && m_gate<=1.0))
00400 {
00401 EXCEPTION(DumpState("m gate has gone out of range. Check model parameters, for example spatial stepsize"));
00402 }
00403 if (!(0.0<=h_gate && h_gate<=1.0))
00404 {
00405 EXCEPTION(DumpState("h gate has gone out of range. Check model parameters, for example spatial stepsize"));
00406 }
00407 if (!(0.0<=d_gate && d_gate<=1.0))
00408 {
00409 EXCEPTION(DumpState("d gate has gone out of range. Check model parameters, for example spatial stepsize"));
00410 }
00411 if (!(0.0<=f_gate && f_gate<=1.0))
00412 {
00413 EXCEPTION(DumpState("f gate for the plateau current has gone out of range. Check model parameters, for example spatial stepsize"));
00414 }
00415 if (!(0.0<=f2_gate && f2_gate<=1.0))
00416 {
00417 EXCEPTION(DumpState("f2 gate has gone out of range. Check model parameters, for example spatial stepsize"));
00418 }
00419 if (!(0.0<=p && p<=1.0))
00420 {
00421 EXCEPTION(DumpState("p gate has gone out of range. Check model parameters, for example spatial stepsize"));
00422 }
00423 if (!(Nai>0.0))
00424 {
00425 EXCEPTION(DumpState("intarcellular Na concentration is negative!"));
00426 }
00427 if (!(Cai>0.0))
00428 {
00429 EXCEPTION(DumpState("intarcellular Ca concentration is negative!"));
00430 }
00431 if (!(Kc>0.0))
00432 {
00433 EXCEPTION(DumpState("extracellular K concentration is negative!"));
00434 }
00435 if (!(Ki>0.0))
00436 {
00437 EXCEPTION(DumpState("intarcellular K concentration is negative!"));
00438 }
00439 if (!(0.0<=x_gate && x_gate<=1.0))
00440 {
00441 EXCEPTION(DumpState("x gate has gone out of range. Check model parameters, for example spatial stepsize"));
00442 }
00443 if (!(Ca_up>0.0))
00444 {
00445 EXCEPTION(DumpState("Ca_up concentration is negative!"));
00446 }
00447 if (!(Ca_rel>0.0))
00448 {
00449 EXCEPTION(DumpState("Ca_rel concentration is negative!"));
00450 }
00451 #undef COVERAGE_IGNORE
00452
00453 }
00454
00455 template<>
00456 void OdeSystemInformation<DiFrancescoNoble1985OdeSystem>::Initialise(void)
00457 {
00458 this->mVariableNames.push_back("V");
00459 this->mVariableUnits.push_back("mV");
00460 this->mInitialConditions.push_back(-87.01);
00461
00462 this->mVariableNames.push_back("y_gate");
00463 this->mVariableUnits.push_back("");
00464 this->mInitialConditions.push_back(0.2);
00465
00466 this->mVariableNames.push_back("s_gate");
00467 this->mVariableUnits.push_back("");
00468 this->mInitialConditions.push_back(1.0);
00469
00470 this->mVariableNames.push_back("m_gate");
00471 this->mVariableUnits.push_back("");
00472 this->mInitialConditions.push_back(0.01);
00473
00474 this->mVariableNames.push_back("h_gate");
00475 this->mVariableUnits.push_back("");
00476 this->mInitialConditions.push_back(0.8);
00477
00478 this->mVariableNames.push_back("d_gate");
00479 this->mVariableUnits.push_back("");
00480 this->mInitialConditions.push_back(0.005);
00481
00482 this->mVariableNames.push_back("f_gate");
00483 this->mVariableUnits.push_back("");
00484 this->mInitialConditions.push_back(1.0);
00485
00486 this->mVariableNames.push_back("f2_gate");
00487 this->mVariableUnits.push_back("");
00488 this->mInitialConditions.push_back(1.0);
00489
00490 this->mVariableNames.push_back("p");
00491 this->mVariableUnits.push_back("");
00492 this->mInitialConditions.push_back(1.0);
00493
00494 this->mVariableNames.push_back("Nai");
00495 this->mVariableUnits.push_back("");
00496 this->mInitialConditions.push_back(8.0);
00497
00498 this->mVariableNames.push_back("Cai");
00499 this->mVariableUnits.push_back("");
00500 this->mInitialConditions.push_back(0.00005);
00501
00502 this->mVariableNames.push_back("Kc");
00503 this->mVariableUnits.push_back("");
00504 this->mInitialConditions.push_back(4.0);
00505
00506 this->mVariableNames.push_back("Ki");
00507 this->mVariableUnits.push_back("");
00508 this->mInitialConditions.push_back(140.0);
00509
00510 this->mVariableNames.push_back("x_gate");
00511 this->mVariableUnits.push_back("");
00512 this->mInitialConditions.push_back(0.01);
00513
00514 this->mVariableNames.push_back("Ca_up");
00515 this->mVariableUnits.push_back("");
00516 this->mInitialConditions.push_back(2.0);
00517
00518 this->mVariableNames.push_back("Ca_rel");
00519 this->mVariableUnits.push_back("");
00520 this->mInitialConditions.push_back(1.0);
00521
00522 this->mInitialised = true;
00523 }