luo_rudy_1991BackwardEuler.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "luo_rudy_1991BackwardEuler.hpp"
00014 #include <cmath>
00015 #include <cassert>
00016 #include "CardiacNewtonSolver.hpp"
00017 #include "Exception.hpp"
00018 #include "OdeSystemInformation.hpp"
00019
00020 class CML_luo_rudy_1991_pe_lut_be_LookupTables
00021 {
00022 public:
00023 static CML_luo_rudy_1991_pe_lut_be_LookupTables* Instance()
00024 {
00025 if (mpInstance == NULL)
00026 {
00027 mpInstance = new CML_luo_rudy_1991_pe_lut_be_LookupTables;
00028 }
00029 return mpInstance;
00030 }
00031
00032
00033
00034 double* _lookup_0_row(unsigned i, double factor)
00035 {
00036 for (unsigned j=0; j<16; j++)
00037 {
00038 double y1 = _lookup_table_0[i][j];
00039 double y2 = _lookup_table_0[i+1][j];
00040 _lookup_table_0_row[j] = y1 + (y2-y1)*factor;
00041 }
00042 return _lookup_table_0_row;
00043 }
00044
00045
00046 protected:
00047 CML_luo_rudy_1991_pe_lut_be_LookupTables(const CML_luo_rudy_1991_pe_lut_be_LookupTables&);
00048 CML_luo_rudy_1991_pe_lut_be_LookupTables& operator= (const CML_luo_rudy_1991_pe_lut_be_LookupTables&);
00049 CML_luo_rudy_1991_pe_lut_be_LookupTables()
00050 {
00051 assert(mpInstance == NULL);
00052 for (int i=0 ; i<16001; i++)
00053 {
00054 double var_membrane__V = -100.0001 + i*0.01;
00055 _lookup_table_0[i][0] = (0.32 * (var_membrane__V + 47.13)) / (1.0 - exp( -0.1 * (var_membrane__V + 47.13)));
00056 }
00057
00058 for (int i=0 ; i<16001; i++)
00059 {
00060 double var_membrane__V = -100.0001 + i*0.01;
00061 _lookup_table_0[i][1] = 0.08 * exp((-var_membrane__V) * 0.0909090909091);
00062 }
00063
00064 for (int i=0 ; i<16001; i++)
00065 {
00066 double var_membrane__V = -100.0001 + i*0.01;
00067 _lookup_table_0[i][2] = (var_membrane__V < -40.0) ? (0.135 * exp((80.0 + var_membrane__V) * -0.147058823529)) : 0.0;
00068 }
00069
00070 for (int i=0 ; i<16001; i++)
00071 {
00072 double var_membrane__V = -100.0001 + i*0.01;
00073 _lookup_table_0[i][3] = (var_membrane__V < -40.0) ? ((3.56 * exp(0.079 * var_membrane__V)) + (310000.0 * exp(0.35 * var_membrane__V))) : (1.0 / (0.13 * (1.0 + exp((var_membrane__V + 10.66) * -0.0900900900901))));
00074 }
00075
00076 for (int i=0 ; i<16001; i++)
00077 {
00078 double var_membrane__V = -100.0001 + i*0.01;
00079 _lookup_table_0[i][4] = (var_membrane__V < -40.0) ? (((( -127140.0 * exp(0.2444 * var_membrane__V)) - (3.474e-05 * exp( -0.04391 * var_membrane__V))) * (var_membrane__V + 37.78)) / (1.0 + exp(0.311 * (var_membrane__V + 79.23)))) : 0.0;
00080 }
00081
00082 for (int i=0 ; i<16001; i++)
00083 {
00084 double var_membrane__V = -100.0001 + i*0.01;
00085 _lookup_table_0[i][5] = (var_membrane__V < -40.0) ? ((0.1212 * exp( -0.01052 * var_membrane__V)) / (1.0 + exp( -0.1378 * (var_membrane__V + 40.14)))) : ((0.3 * exp( -2.535e-07 * var_membrane__V)) / (1.0 + exp( -0.1 * (var_membrane__V + 32.0))));
00086 }
00087
00088 for (int i=0 ; i<16001; i++)
00089 {
00090 double var_membrane__V = -100.0001 + i*0.01;
00091 _lookup_table_0[i][6] = (0.095 * exp( -0.01 * (var_membrane__V - 5.0))) / (1.0 + exp( -0.072 * (var_membrane__V - 5.0)));
00092 }
00093
00094 for (int i=0 ; i<16001; i++)
00095 {
00096 double var_membrane__V = -100.0001 + i*0.01;
00097 _lookup_table_0[i][7] = (0.07 * exp( -0.017 * (var_membrane__V + 44.0))) / (1.0 + exp(0.05 * (var_membrane__V + 44.0)));
00098 }
00099
00100 for (int i=0 ; i<16001; i++)
00101 {
00102 double var_membrane__V = -100.0001 + i*0.01;
00103 _lookup_table_0[i][8] = (0.012 * exp( -0.008 * (var_membrane__V + 28.0))) / (1.0 + exp(0.15 * (var_membrane__V + 28.0)));
00104 }
00105
00106 for (int i=0 ; i<16001; i++)
00107 {
00108 double var_membrane__V = -100.0001 + i*0.01;
00109 _lookup_table_0[i][9] = (0.0065 * exp( -0.02 * (var_membrane__V + 30.0))) / (1.0 + exp( -0.2 * (var_membrane__V + 30.0)));
00110 }
00111
00112 for (int i=0 ; i<16001; i++)
00113 {
00114 double var_membrane__V = -100.0001 + i*0.01;
00115 _lookup_table_0[i][10] = (var_membrane__V > -100.0) ? ((2.837 * (exp(0.04 * (var_membrane__V + 77.0)) - 1.0)) / ((var_membrane__V + 77.0) * exp(0.04 * (var_membrane__V + 35.0)))) : 1.0;
00116 }
00117
00118 for (int i=0 ; i<16001; i++)
00119 {
00120 double var_membrane__V = -100.0001 + i*0.01;
00121 _lookup_table_0[i][11] = (0.0005 * exp(0.083 * (var_membrane__V + 50.0))) / (1.0 + exp(0.057 * (var_membrane__V + 50.0)));
00122 }
00123
00124 for (int i=0 ; i<16001; i++)
00125 {
00126 double var_membrane__V = -100.0001 + i*0.01;
00127 _lookup_table_0[i][12] = (0.0013 * exp( -0.06 * (var_membrane__V + 20.0))) / (1.0 + exp( -0.04 * (var_membrane__V + 20.0)));
00128 }
00129
00130 for (int i=0 ; i<16001; i++)
00131 {
00132 double var_membrane__V = -100.0001 + i*0.01;
00133 _lookup_table_0[i][13] = ((0.49124 * exp(0.08032 * ((var_membrane__V + 5.476) - -87.8929017138))) + (1.0 * exp(0.06175 * (var_membrane__V - 506.417098286)))) / (1.0 + exp( -0.5143 * ((var_membrane__V - -87.8929017138) + 4.753)));
00134 }
00135
00136 for (int i=0 ; i<16001; i++)
00137 {
00138 double var_membrane__V = -100.0001 + i*0.01;
00139 _lookup_table_0[i][14] = 1.02 / (1.0 + exp(0.2385 * ((var_membrane__V - -87.8929017138) - 59.215)));
00140 }
00141
00142 for (int i=0 ; i<16001; i++)
00143 {
00144 double var_membrane__V = -100.0001 + i*0.01;
00145 _lookup_table_0[i][15] = 0.0183 * (1.0 / (1.0 + exp((7.488 - var_membrane__V) * 0.167224080268))) * (var_membrane__V - -87.8929017138);
00146 }
00147
00148 }
00149
00150 private:
00152 static CML_luo_rudy_1991_pe_lut_be_LookupTables *mpInstance;
00153
00154
00155 double _lookup_table_0_row[16];
00156
00157
00158 double _lookup_table_0[16001][16];
00159
00160 };
00161
00162 CML_luo_rudy_1991_pe_lut_be_LookupTables* CML_luo_rudy_1991_pe_lut_be_LookupTables::mpInstance = NULL;
00163
00164 double CML_luo_rudy_1991_pe_lut_be::Get_membrane__I_stim()
00165 {
00166 return var_membrane__I_stim;
00167 }
00168
00169 double CML_luo_rudy_1991_pe_lut_be::Get_membrane__i_Na()
00170 {
00171 return var_membrane__i_Na;
00172 }
00173
00174 double CML_luo_rudy_1991_pe_lut_be::Get_membrane__i_si()
00175 {
00176 return var_membrane__i_si;
00177 }
00178
00179 double CML_luo_rudy_1991_pe_lut_be::Get_membrane__i_K()
00180 {
00181 return var_membrane__i_K;
00182 }
00183
00184 double CML_luo_rudy_1991_pe_lut_be::Get_membrane__i_K1()
00185 {
00186 return var_membrane__i_K1;
00187 }
00188
00189 double CML_luo_rudy_1991_pe_lut_be::Get_membrane__i_Kp()
00190 {
00191 return var_membrane__i_Kp;
00192 }
00193
00194 double CML_luo_rudy_1991_pe_lut_be::Get_membrane__i_b()
00195 {
00196 return var_membrane__i_b;
00197 }
00198
00199 CML_luo_rudy_1991_pe_lut_be::CML_luo_rudy_1991_pe_lut_be(boost::shared_ptr<AbstractIvpOdeSolver> , boost::shared_ptr<AbstractStimulusFunction> pIntracellularStimulus)
00200 : AbstractBackwardEulerCardiacCell<1>(
00201 8,
00202 0,
00203 pIntracellularStimulus)
00204 {
00205
00206
00207 mpSystemInfo = OdeSystemInformation<CML_luo_rudy_1991_pe_lut_be>::Instance();
00208 Init();
00209
00210 }
00211
00212 CML_luo_rudy_1991_pe_lut_be::~CML_luo_rudy_1991_pe_lut_be()
00213 {
00214 }
00215
00216 void CML_luo_rudy_1991_pe_lut_be::VerifyStateVariables()
00217 {}
00218
00219 double CML_luo_rudy_1991_pe_lut_be::GetIIonic()
00220 {
00221 std::vector<double>& rY = rGetStateVariables();
00222 double var_membrane__V = rY[0];
00223
00224 double var_fast_sodium_current_m_gate__m = rY[1];
00225
00226 double var_fast_sodium_current_h_gate__h = rY[2];
00227
00228 double var_fast_sodium_current_j_gate__j = rY[3];
00229
00230 double var_slow_inward_current_d_gate__d = rY[4];
00231
00232 double var_slow_inward_current_f_gate__f = rY[5];
00233
00234 double var_time_dependent_potassium_current_X_gate__X = rY[6];
00235
00236 double var_intracellular_calcium_concentration__Cai = rY[7];
00237
00238
00239
00240 if (var_membrane__V>59.9999 || var_membrane__V<-100.0001)
00241 {
00242 #define COVERAGE_IGNORE
00243 EXCEPTION(DumpState("V outside lookup table range", rY));
00244 #undef COVERAGE_IGNORE
00245 }
00246
00247 double _offset_0 = var_membrane__V - -100.0001;
00248 double _offset_0_over_table_step = _offset_0 * 100.0;
00249 _table_index_0 = (unsigned)(_offset_0_over_table_step);
00250 _factor_0 = _offset_0_over_table_step - _table_index_0;
00251 _lt_0_row = CML_luo_rudy_1991_pe_lut_be_LookupTables::Instance()->_lookup_0_row(_table_index_0, _factor_0);
00252
00253 var_membrane__i_Na = 23.0 * pow(var_fast_sodium_current_m_gate__m, 3.0) * var_fast_sodium_current_h_gate__h * var_fast_sodium_current_j_gate__j * (var_membrane__V - 54.7944639351);
00254 const double var_slow_inward_current__i_si = 0.09 * var_slow_inward_current_d_gate__d * var_slow_inward_current_f_gate__f * (var_membrane__V - (7.7 - (13.0287 * log(var_intracellular_calcium_concentration__Cai * 1.0))));
00255 var_membrane__i_si = var_slow_inward_current__i_si;
00256 var_membrane__i_K = 0.282 * var_time_dependent_potassium_current_X_gate__X * _lt_0_row[10] * (var_membrane__V - -77.5675843853);
00257 const double var_time_independent_potassium_current_K1_gate__alpha_K1 = _lt_0_row[14];
00258 var_membrane__i_K1 = 0.6047 * (var_time_independent_potassium_current_K1_gate__alpha_K1 / (var_time_independent_potassium_current_K1_gate__alpha_K1 + _lt_0_row[13])) * (var_membrane__V - -87.8929017138);
00259 var_membrane__i_Kp = _lt_0_row[15];
00260 var_membrane__i_b = 0.03921 * (var_membrane__V - -59.87);
00261
00262 return (var_membrane__i_Na+var_membrane__i_si+var_membrane__i_K+var_membrane__i_K1+var_membrane__i_Kp+var_membrane__i_b);
00263 }
00264
00265 void CML_luo_rudy_1991_pe_lut_be::ComputeResidual(double var_environment__time, const double rCurrentGuess[1], double rResidual[1])
00266 {
00267 std::vector<double>& rY = rGetStateVariables();
00268 double var_membrane__V = rY[0];
00269
00270 double var_slow_inward_current_d_gate__d = rY[4];
00271
00272 double var_slow_inward_current_f_gate__f = rY[5];
00273
00274
00275 double var_intracellular_calcium_concentration__Cai = rCurrentGuess[0];
00276
00277 const double var_slow_inward_current__i_si = 0.09 * var_slow_inward_current_d_gate__d * var_slow_inward_current_f_gate__f * (var_membrane__V - (7.7 - (13.0287 * log(var_intracellular_calcium_concentration__Cai * 1.0))));
00278 const double d_dt_intracellular_calcium_concentration__Cai = ( -0.0001 * var_slow_inward_current__i_si) + (0.07 * (0.0001 - var_intracellular_calcium_concentration__Cai));
00279
00280 rResidual[0] = rCurrentGuess[0] - rY[7] - mDt*1.0*d_dt_intracellular_calcium_concentration__Cai;
00281 }
00282
00283 void CML_luo_rudy_1991_pe_lut_be::ComputeJacobian(double var_environment__time, const double rCurrentGuess[1], double rJacobian[1][1])
00284 {
00285 std::vector<double>& rY = rGetStateVariables();
00286 double var_slow_inward_current_d_gate__d = rY[4];
00287
00288 double var_slow_inward_current_f_gate__f = rY[5];
00289
00290
00291 double var_intracellular_calcium_concentration__Cai = rCurrentGuess[0];
00292
00293 const double dt = 1.0 * mDt;
00294
00295
00296 rJacobian[0][0] = 1.0 - (dt * (((((-0.0001172583) * var_slow_inward_current_d_gate__d) * var_slow_inward_current_f_gate__f) / var_intracellular_calcium_concentration__Cai) - 0.07));
00297 }
00298
00299 void CML_luo_rudy_1991_pe_lut_be::UpdateTransmembranePotential(double var_environment__time)
00300 {
00301
00302 var_environment__time *= 1.0;
00303 std::vector<double>& rY = rGetStateVariables();
00304 double var_membrane__V = rY[0];
00305
00306 double var_fast_sodium_current_m_gate__m = rY[1];
00307
00308 double var_fast_sodium_current_h_gate__h = rY[2];
00309
00310 double var_fast_sodium_current_j_gate__j = rY[3];
00311
00312 double var_slow_inward_current_d_gate__d = rY[4];
00313
00314 double var_slow_inward_current_f_gate__f = rY[5];
00315
00316 double var_time_dependent_potassium_current_X_gate__X = rY[6];
00317
00318 double var_intracellular_calcium_concentration__Cai = rY[7];
00319
00320
00321
00322 if (var_membrane__V>59.9999 || var_membrane__V<-100.0001)
00323 {
00324 #define COVERAGE_IGNORE
00325 EXCEPTION(DumpState("V outside lookup table range", rY));
00326 #undef COVERAGE_IGNORE
00327 }
00328
00329 double _offset_0 = var_membrane__V - -100.0001;
00330 double _offset_0_over_table_step = _offset_0 * 100.0;
00331 _table_index_0 = (unsigned)(_offset_0_over_table_step);
00332 _factor_0 = _offset_0_over_table_step - _table_index_0;
00333 _lt_0_row = CML_luo_rudy_1991_pe_lut_be_LookupTables::Instance()->_lookup_0_row(_table_index_0, _factor_0);
00334
00335 var_membrane__I_stim = GetStimulus((1.0/1)*var_environment__time);
00336 var_membrane__i_Na = 23.0 * pow(var_fast_sodium_current_m_gate__m, 3.0) * var_fast_sodium_current_h_gate__h * var_fast_sodium_current_j_gate__j * (var_membrane__V - 54.7944639351);
00337 const double var_slow_inward_current__i_si = 0.09 * var_slow_inward_current_d_gate__d * var_slow_inward_current_f_gate__f * (var_membrane__V - (7.7 - (13.0287 * log(var_intracellular_calcium_concentration__Cai * 1.0))));
00338 var_membrane__i_si = var_slow_inward_current__i_si;
00339 var_membrane__i_K = 0.282 * var_time_dependent_potassium_current_X_gate__X * _lt_0_row[10] * (var_membrane__V - -77.5675843853);
00340 const double var_time_independent_potassium_current_K1_gate__alpha_K1 = _lt_0_row[14];
00341 var_membrane__i_K1 = 0.6047 * (var_time_independent_potassium_current_K1_gate__alpha_K1 / (var_time_independent_potassium_current_K1_gate__alpha_K1 + _lt_0_row[13])) * (var_membrane__V - -87.8929017138);
00342 var_membrane__i_Kp = _lt_0_row[15];
00343 var_membrane__i_b = 0.03921 * (var_membrane__V - -59.87);
00344 const double d_dt_membrane__V = -1.0 * (var_membrane__I_stim + var_membrane__i_Na + var_membrane__i_si + var_membrane__i_K + var_membrane__i_K1 + var_membrane__i_Kp + var_membrane__i_b);
00345
00346 rY[0] += mDt * 1.0*d_dt_membrane__V;
00347 }
00348
00349 void CML_luo_rudy_1991_pe_lut_be::ComputeOneStepExceptVoltage(double var_environment__time)
00350 {
00351
00352 var_environment__time *= 1.0;
00353 std::vector<double>& rY = rGetStateVariables();
00354 double var_membrane__V = rY[0];
00355
00356
00357
00358 if (var_membrane__V>59.9999 || var_membrane__V<-100.0001)
00359 {
00360 #define COVERAGE_IGNORE
00361 EXCEPTION(DumpState("V outside lookup table range", rY));
00362 #undef COVERAGE_IGNORE
00363 }
00364
00365 double _offset_0 = var_membrane__V - -100.0001;
00366 double _offset_0_over_table_step = _offset_0 * 100.0;
00367 _table_index_0 = (unsigned)(_offset_0_over_table_step);
00368 _factor_0 = _offset_0_over_table_step - _table_index_0;
00369 _lt_0_row = CML_luo_rudy_1991_pe_lut_be_LookupTables::Instance()->_lookup_0_row(_table_index_0, _factor_0);
00370
00371
00372 const double _g_0 = _lt_0_row[2] * 1.0;
00373 const double _h_0 = (_lt_0_row[2] * (-1.0)) - (_lt_0_row[3] * 1.0);
00374 const double _g_1 = _lt_0_row[4] * 1.0;
00375 const double _h_1 = (_lt_0_row[4] * (-1.0)) - (_lt_0_row[5] * 1.0);
00376 const double _g_2 = _lt_0_row[0] * 1.0;
00377 const double _h_2 = (_lt_0_row[0] * (-1.0)) - (_lt_0_row[1] * 1.0);
00378 const double _g_3 = _lt_0_row[6] * 1.0;
00379 const double _h_3 = (_lt_0_row[6] * (-1.0)) - (_lt_0_row[7] * 1.0);
00380 const double _g_4 = _lt_0_row[8] * 1.0;
00381 const double _h_4 = (_lt_0_row[8] * (-1.0)) - (_lt_0_row[9] * 1.0);
00382 const double _g_5 = _lt_0_row[11] * 1.0;
00383 const double _h_5 = (_lt_0_row[11] * (-1.0)) - (_lt_0_row[12] * 1.0);
00384
00385 const double dt = mDt*1.0;
00386 rY[1] = (rY[1] + _g_2*dt) / (1 - _h_2*dt);
00387 rY[2] = (rY[2] + _g_0*dt) / (1 - _h_0*dt);
00388 rY[3] = (rY[3] + _g_1*dt) / (1 - _h_1*dt);
00389 rY[4] = (rY[4] + _g_3*dt) / (1 - _h_3*dt);
00390 rY[5] = (rY[5] + _g_4*dt) / (1 - _h_4*dt);
00391 rY[6] = (rY[6] + _g_5*dt) / (1 - _h_5*dt);
00392
00393 double _guess[1] = {rY[7]};
00394 CardiacNewtonSolver<1> *_solver = CardiacNewtonSolver<1>::Instance();
00395 _solver->Solve(*this, var_environment__time, _guess);
00396 rY[7] = _guess[0];
00397 }
00398
00399 template<>
00400 void OdeSystemInformation<CML_luo_rudy_1991_pe_lut_be>::Initialise(void)
00401 {
00402
00403
00404 this->mVariableNames.push_back("membrane__V");
00405 this->mVariableUnits.push_back("millivolt");
00406 this->mInitialConditions.push_back(-83.853);
00407
00408 this->mVariableNames.push_back("fast_sodium_current_m_gate__m");
00409 this->mVariableUnits.push_back("dimensionless");
00410 this->mInitialConditions.push_back(0.00187018);
00411
00412 this->mVariableNames.push_back("fast_sodium_current_h_gate__h");
00413 this->mVariableUnits.push_back("dimensionless");
00414 this->mInitialConditions.push_back(0.9804713);
00415
00416 this->mVariableNames.push_back("fast_sodium_current_j_gate__j");
00417 this->mVariableUnits.push_back("dimensionless");
00418 this->mInitialConditions.push_back(0.98767124);
00419
00420 this->mVariableNames.push_back("slow_inward_current_d_gate__d");
00421 this->mVariableUnits.push_back("dimensionless");
00422 this->mInitialConditions.push_back(0.00316354);
00423
00424 this->mVariableNames.push_back("slow_inward_current_f_gate__f");
00425 this->mVariableUnits.push_back("dimensionless");
00426 this->mInitialConditions.push_back(0.99427859);
00427
00428 this->mVariableNames.push_back("time_dependent_potassium_current_X_gate__X");
00429 this->mVariableUnits.push_back("dimensionless");
00430 this->mInitialConditions.push_back(0.16647703);
00431
00432 this->mVariableNames.push_back("intracellular_calcium_concentration__Cai");
00433 this->mVariableUnits.push_back("millimolar");
00434 this->mInitialConditions.push_back(0.0002);
00435
00436 this->mInitialised = true;
00437 }
00438
00439
00440
00441 #include "SerializationExportWrapperForCpp.hpp"
00442 CHASTE_CLASS_EXPORT(CML_luo_rudy_1991_pe_lut_be)