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