00001 #ifndef _Cellluo_rudy_1991FromCellMLOpt_
00002 #define _Cellluo_rudy_1991FromCellMLOpt_
00003
00015
00016 #include <boost/serialization/access.hpp>
00017 #include <boost/serialization/base_object.hpp>
00018 #include <cmath>
00019 #include <cassert>
00020 #include "AbstractCardiacCell.hpp"
00021 #include "Exception.hpp"
00022 #include "OdeSystemInformation.hpp"
00023 #include "AbstractStimulusFunction.hpp"
00024
00025
00026 #include <boost/serialization/export.hpp>
00027
00028 class Cellluo_rudy_1991FromCellMLOpt_LookupTables
00029 {
00030 public:
00031 static Cellluo_rudy_1991FromCellMLOpt_LookupTables* Instance()
00032 {
00033 if (mpInstance == NULL)
00034 {
00035 mpInstance = new Cellluo_rudy_1991FromCellMLOpt_LookupTables;
00036 }
00037 return mpInstance;
00038 }
00039
00040
00041
00042 double* _lookup_0_row(unsigned i, double factor)
00043 {
00044 for (unsigned j=0; j<16; j++)
00045 {
00046 double y1 = _lookup_table_0[i][j];
00047 double y2 = _lookup_table_0[i+1][j];
00048 _lookup_table_0_row[j] = y1 + (y2-y1)*factor;
00049 }
00050 return _lookup_table_0_row;
00051 }
00052
00053
00054 protected:
00055 Cellluo_rudy_1991FromCellMLOpt_LookupTables(const Cellluo_rudy_1991FromCellMLOpt_LookupTables&);
00056 Cellluo_rudy_1991FromCellMLOpt_LookupTables& operator= (const Cellluo_rudy_1991FromCellMLOpt_LookupTables&);
00057 Cellluo_rudy_1991FromCellMLOpt_LookupTables()
00058 {
00059 assert(mpInstance == NULL);
00060 for (int i=0 ; i<16001; i++)
00061 {
00062 double var_membrane__V = -100.0001 + i*0.01;
00063 _lookup_table_0[i][0] = (0.32 * (var_membrane__V + 47.13)) / (1.0 - exp( -0.1 * (var_membrane__V + 47.13)));
00064 }
00065
00066 for (int i=0 ; i<16001; i++)
00067 {
00068 double var_membrane__V = -100.0001 + i*0.01;
00069 _lookup_table_0[i][1] = 0.08 * exp((-var_membrane__V) * 0.0909090909091);
00070 }
00071
00072 for (int i=0 ; i<16001; i++)
00073 {
00074 double var_membrane__V = -100.0001 + i*0.01;
00075 _lookup_table_0[i][2] = (var_membrane__V < -40.0) ? (0.135 * exp((80.0 + var_membrane__V) * -0.147058823529)) : 0.0;
00076 }
00077
00078 for (int i=0 ; i<16001; i++)
00079 {
00080 double var_membrane__V = -100.0001 + i*0.01;
00081 _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))));
00082 }
00083
00084 for (int i=0 ; i<16001; i++)
00085 {
00086 double var_membrane__V = -100.0001 + i*0.01;
00087 _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;
00088 }
00089
00090 for (int i=0 ; i<16001; i++)
00091 {
00092 double var_membrane__V = -100.0001 + i*0.01;
00093 _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))));
00094 }
00095
00096 for (int i=0 ; i<16001; i++)
00097 {
00098 double var_membrane__V = -100.0001 + i*0.01;
00099 _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)));
00100 }
00101
00102 for (int i=0 ; i<16001; i++)
00103 {
00104 double var_membrane__V = -100.0001 + i*0.01;
00105 _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)));
00106 }
00107
00108 for (int i=0 ; i<16001; i++)
00109 {
00110 double var_membrane__V = -100.0001 + i*0.01;
00111 _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)));
00112 }
00113
00114 for (int i=0 ; i<16001; i++)
00115 {
00116 double var_membrane__V = -100.0001 + i*0.01;
00117 _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)));
00118 }
00119
00120 for (int i=0 ; i<16001; i++)
00121 {
00122 double var_membrane__V = -100.0001 + i*0.01;
00123 _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;
00124 }
00125
00126 for (int i=0 ; i<16001; i++)
00127 {
00128 double var_membrane__V = -100.0001 + i*0.01;
00129 _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)));
00130 }
00131
00132 for (int i=0 ; i<16001; i++)
00133 {
00134 double var_membrane__V = -100.0001 + i*0.01;
00135 _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)));
00136 }
00137
00138 for (int i=0 ; i<16001; i++)
00139 {
00140 double var_membrane__V = -100.0001 + i*0.01;
00141 _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)));
00142 }
00143
00144 for (int i=0 ; i<16001; i++)
00145 {
00146 double var_membrane__V = -100.0001 + i*0.01;
00147 _lookup_table_0[i][14] = 1.02 / (1.0 + exp(0.2385 * ((var_membrane__V - -87.8929017138) - 59.215)));
00148 }
00149
00150 for (int i=0 ; i<16001; i++)
00151 {
00152 double var_membrane__V = -100.0001 + i*0.01;
00153 _lookup_table_0[i][15] = 0.0183 * (1.0 / (1.0 + exp((7.488 - var_membrane__V) * 0.167224080268))) * (var_membrane__V - -87.8929017138);
00154 }
00155
00156 }
00157
00158 private:
00160 static Cellluo_rudy_1991FromCellMLOpt_LookupTables *mpInstance;
00161
00162
00163 double _lookup_table_0_row[16];
00164
00165
00166 double _lookup_table_0[16001][16];
00167
00168 };
00169
00170 Cellluo_rudy_1991FromCellMLOpt_LookupTables* Cellluo_rudy_1991FromCellMLOpt_LookupTables::mpInstance = NULL;
00171
00172 class Cellluo_rudy_1991FromCellMLOpt : public AbstractCardiacCell
00173 {
00174 friend class boost::serialization::access;
00175 template<class Archive>
00176 void serialize(Archive & archive, const unsigned int version)
00177 {
00178 archive & boost::serialization::base_object<AbstractCardiacCell>(*this);
00179 }
00180
00181
00182
00183
00184 double var_membrane__I_stim;
00185 double var_membrane__i_Na;
00186 double var_membrane__i_si;
00187 double var_membrane__i_K;
00188 double var_membrane__i_K1;
00189 double var_membrane__i_Kp;
00190 double var_membrane__i_b;
00191 public:
00192 double Get_membrane__I_stim()
00193 {
00194 return var_membrane__I_stim;
00195 }
00196
00197 double Get_membrane__i_Na()
00198 {
00199 return var_membrane__i_Na;
00200 }
00201
00202 double Get_membrane__i_si()
00203 {
00204 return var_membrane__i_si;
00205 }
00206
00207 double Get_membrane__i_K()
00208 {
00209 return var_membrane__i_K;
00210 }
00211
00212 double Get_membrane__i_K1()
00213 {
00214 return var_membrane__i_K1;
00215 }
00216
00217 double Get_membrane__i_Kp()
00218 {
00219 return var_membrane__i_Kp;
00220 }
00221
00222 double Get_membrane__i_b()
00223 {
00224 return var_membrane__i_b;
00225 }
00226
00227 Cellluo_rudy_1991FromCellMLOpt(boost::shared_ptr<AbstractIvpOdeSolver> pSolver,
00228 boost::shared_ptr<AbstractStimulusFunction> pIntracellularStimulus)
00229 : AbstractCardiacCell(pSolver, 8, 0, pIntracellularStimulus)
00230 {
00231
00232
00233 mpSystemInfo = OdeSystemInformation<Cellluo_rudy_1991FromCellMLOpt>::Instance();
00234 Init();
00235
00236 }
00237
00238 ~Cellluo_rudy_1991FromCellMLOpt(void)
00239 {
00240 }
00241
00242 void VerifyGatingVariables()
00243 {}
00244
00245 double GetIIonic()
00246 {
00247 std::vector<double>& rY = rGetStateVariables();
00248 double var_membrane__V = rY[0];
00249
00250 double var_fast_sodium_current_m_gate__m = rY[1];
00251
00252 double var_fast_sodium_current_h_gate__h = rY[2];
00253
00254 double var_fast_sodium_current_j_gate__j = rY[3];
00255
00256 double var_slow_inward_current_d_gate__d = rY[4];
00257
00258 double var_slow_inward_current_f_gate__f = rY[5];
00259
00260 double var_time_dependent_potassium_current_X_gate__X = rY[6];
00261
00262 double var_intracellular_calcium_concentration__Cai = rY[7];
00263
00264
00265
00266 if (var_membrane__V>59.9999 || var_membrane__V<-100.0001)
00267 {
00268 #define COVERAGE_IGNORE
00269 EXCEPTION(DumpState("V outside lookup table range", rY));
00270 #undef COVERAGE_IGNORE
00271 }
00272
00273 double _offset_0 = var_membrane__V - -100.0001;
00274 double _offset_0_over_table_step = _offset_0 * 100.0;
00275 unsigned _table_index_0 = (unsigned)(_offset_0_over_table_step);
00276 double _factor_0 = _offset_0_over_table_step - _table_index_0;
00277 double* _lt_0_row = Cellluo_rudy_1991FromCellMLOpt_LookupTables::Instance()->_lookup_0_row(_table_index_0, _factor_0);
00278
00279 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);
00280 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))));
00281 var_membrane__i_si = var_slow_inward_current__i_si;
00282 var_membrane__i_K = 0.282 * var_time_dependent_potassium_current_X_gate__X * _lt_0_row[10] * (var_membrane__V - -77.5675843853);
00283 const double var_time_independent_potassium_current_K1_gate__alpha_K1 = _lt_0_row[14];
00284 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);
00285 var_membrane__i_Kp = _lt_0_row[15];
00286 var_membrane__i_b = 0.03921 * (var_membrane__V - -59.87);
00287
00288 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);
00289 }
00290
00291 void EvaluateYDerivatives(
00292 double var_environment__time,
00293 const std::vector<double> &rY,
00294 std::vector<double> &rDY)
00295 {
00296
00297
00298 var_environment__time *= 1.0;
00299 double var_membrane__V = rY[0];
00300
00301 double var_fast_sodium_current_m_gate__m = rY[1];
00302
00303 double var_fast_sodium_current_h_gate__h = rY[2];
00304
00305 double var_fast_sodium_current_j_gate__j = rY[3];
00306
00307 double var_slow_inward_current_d_gate__d = rY[4];
00308
00309 double var_slow_inward_current_f_gate__f = rY[5];
00310
00311 double var_time_dependent_potassium_current_X_gate__X = rY[6];
00312
00313 double var_intracellular_calcium_concentration__Cai = rY[7];
00314
00315
00316
00317
00318 if (var_membrane__V>59.9999 || var_membrane__V<-100.0001)
00319 {
00320 #define COVERAGE_IGNORE
00321 EXCEPTION(DumpState("V outside lookup table range", rY));
00322 #undef COVERAGE_IGNORE
00323 }
00324
00325 double _offset_0 = var_membrane__V - -100.0001;
00326 double _offset_0_over_table_step = _offset_0 * 100.0;
00327 unsigned _table_index_0 = (unsigned)(_offset_0_over_table_step);
00328 double _factor_0 = _offset_0_over_table_step - _table_index_0;
00329 double* _lt_0_row = Cellluo_rudy_1991FromCellMLOpt_LookupTables::Instance()->_lookup_0_row(_table_index_0, _factor_0);
00330
00331
00332 double var_membrane__I_stim = GetStimulus((1.0/1)*var_environment__time);
00333 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);
00334 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))));
00335 var_membrane__i_si = var_slow_inward_current__i_si;
00336 var_membrane__i_K = 0.282 * var_time_dependent_potassium_current_X_gate__X * _lt_0_row[10] * (var_membrane__V - -77.5675843853);
00337 const double var_time_independent_potassium_current_K1_gate__alpha_K1 = _lt_0_row[14];
00338 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);
00339 var_membrane__i_Kp = _lt_0_row[15];
00340 var_membrane__i_b = 0.03921 * (var_membrane__V - -59.87);
00341
00342 double d_dt_membrane__V;
00343 if (mSetVoltageDerivativeToZero)
00344 {
00345 d_dt_membrane__V = 0.0;
00346 }
00347 else
00348 {
00349 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);
00350 }
00351
00352 const double d_dt_fast_sodium_current_m_gate__m = (_lt_0_row[0] * (1.0 - var_fast_sodium_current_m_gate__m)) - (_lt_0_row[1] * var_fast_sodium_current_m_gate__m);
00353 const double d_dt_fast_sodium_current_h_gate__h = (_lt_0_row[2] * (1.0 - var_fast_sodium_current_h_gate__h)) - (_lt_0_row[3] * var_fast_sodium_current_h_gate__h);
00354 const double d_dt_fast_sodium_current_j_gate__j = (_lt_0_row[4] * (1.0 - var_fast_sodium_current_j_gate__j)) - (_lt_0_row[5] * var_fast_sodium_current_j_gate__j);
00355 const double d_dt_slow_inward_current_d_gate__d = (_lt_0_row[6] * (1.0 - var_slow_inward_current_d_gate__d)) - (_lt_0_row[7] * var_slow_inward_current_d_gate__d);
00356 const double d_dt_slow_inward_current_f_gate__f = (_lt_0_row[8] * (1.0 - var_slow_inward_current_f_gate__f)) - (_lt_0_row[9] * var_slow_inward_current_f_gate__f);
00357 const double d_dt_time_dependent_potassium_current_X_gate__X = (_lt_0_row[11] * (1.0 - var_time_dependent_potassium_current_X_gate__X)) - (_lt_0_row[12] * var_time_dependent_potassium_current_X_gate__X);
00358 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));
00359
00360 rDY[0] = 1.0*d_dt_membrane__V;
00361 rDY[1] = 1.0*d_dt_fast_sodium_current_m_gate__m;
00362 rDY[2] = 1.0*d_dt_fast_sodium_current_h_gate__h;
00363 rDY[3] = 1.0*d_dt_fast_sodium_current_j_gate__j;
00364 rDY[4] = 1.0*d_dt_slow_inward_current_d_gate__d;
00365 rDY[5] = 1.0*d_dt_slow_inward_current_f_gate__f;
00366 rDY[6] = 1.0*d_dt_time_dependent_potassium_current_X_gate__X;
00367 rDY[7] = 1.0*d_dt_intracellular_calcium_concentration__Cai;
00368 }
00369
00370 };
00371
00372
00373 template<>
00374 void OdeSystemInformation<Cellluo_rudy_1991FromCellMLOpt>::Initialise(void)
00375 {
00376
00377
00378 this->mVariableNames.push_back("membrane__V");
00379 this->mVariableUnits.push_back("millivolt");
00380 this->mInitialConditions.push_back(-83.853);
00381
00382 this->mVariableNames.push_back("fast_sodium_current_m_gate__m");
00383 this->mVariableUnits.push_back("dimensionless");
00384 this->mInitialConditions.push_back(0.00187018);
00385
00386 this->mVariableNames.push_back("fast_sodium_current_h_gate__h");
00387 this->mVariableUnits.push_back("dimensionless");
00388 this->mInitialConditions.push_back(0.9804713);
00389
00390 this->mVariableNames.push_back("fast_sodium_current_j_gate__j");
00391 this->mVariableUnits.push_back("dimensionless");
00392 this->mInitialConditions.push_back(0.98767124);
00393
00394 this->mVariableNames.push_back("slow_inward_current_d_gate__d");
00395 this->mVariableUnits.push_back("dimensionless");
00396 this->mInitialConditions.push_back(0.00316354);
00397
00398 this->mVariableNames.push_back("slow_inward_current_f_gate__f");
00399 this->mVariableUnits.push_back("dimensionless");
00400 this->mInitialConditions.push_back(0.99427859);
00401
00402 this->mVariableNames.push_back("time_dependent_potassium_current_X_gate__X");
00403 this->mVariableUnits.push_back("dimensionless");
00404 this->mInitialConditions.push_back(0.16647703);
00405
00406 this->mVariableNames.push_back("intracellular_calcium_concentration__Cai");
00407 this->mVariableUnits.push_back("millimolar");
00408 this->mInitialConditions.push_back(0.0002);
00409
00410 this->mInitialised = true;
00411 }
00412
00413
00414 BOOST_CLASS_EXPORT(Cellluo_rudy_1991FromCellMLOpt)
00415 namespace boost
00416 {
00417 namespace serialization
00418 {
00419 template<class Archive>
00420 inline void save_construct_data(
00421 Archive & ar, const Cellluo_rudy_1991FromCellMLOpt * t, const unsigned int fileVersion)
00422 {
00423 const boost::shared_ptr<AbstractIvpOdeSolver> p_solver = t->GetSolver();
00424 const boost::shared_ptr<AbstractStimulusFunction> p_stimulus = t->GetStimulusFunction();
00425 ar << p_solver;
00426 ar << p_stimulus;
00427 }
00428
00429 template<class Archive>
00430 inline void load_construct_data(
00431 Archive & ar, Cellluo_rudy_1991FromCellMLOpt * t, const unsigned int fileVersion)
00432 {
00433 boost::shared_ptr<AbstractIvpOdeSolver> p_solver;
00434 boost::shared_ptr<AbstractStimulusFunction> p_stimulus;
00435 ar >> p_solver;
00436 ar >> p_stimulus;
00437 ::new(t)Cellluo_rudy_1991FromCellMLOpt(p_solver, p_stimulus);
00438 }
00439
00440 }
00441
00442 }
00443
00444 #endif