KASKADE 7 development version
membraneModels.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2013-2016 Zuse Institute Berlin */
7/* Copyright (C) 2013-2013 U Milan */
8/* */
9/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
10/* see $KASKADE/academic.txt */
11/* */
12/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14#ifndef MEMBRANEMODELS_HH
15#define MEMBRANEMODELS_HH
16
17#include <dune/common/config.h>
18#include <dune/common/fvector.hh>
19#include <dune/common/fmatrix.hh>
20
21
22namespace Kaskade {
23
55 template <class Derived, int n>
57 {
61 static int const nGating = n;
62
67
72
79
86 MembraneModelBase(std::string const& name): nm(name) {}
87
88 //MembraneModelBase(std::string const& name, double uFix, Gating const& vFix): nm(name), fix(uFix,vFix) {}
89
93 std::string const& name() const { return nm; }
94
98 std::pair<double,Gating> const& restState() const { return fix; }
99
109 double current_du(double u, Gating const& v, double h=1e-5) const
110 {
111 double fuv = static_cast<Derived const&>(*this).current(u-h,v);
112 double fuiv = static_cast<Derived const&>(*this).current(u+h,v);
113
114 return (fuiv-fuv)/(2*h);
115 }
116
126 Gating current_dv(double u, Gating const& v) const
127 {
128 double f = static_cast<Derived const&>(*this).current(u,v);
129 Gating fv_uv,dir;
130 for (int i=0; i<nGating; ++i)
131 {
132 dir = 0;
133 dir[i] = 1e-5;
134 fv_uv[i] = (static_cast<Derived const&>(*this).current(u,v+dir)-f)/1e-5;
135 }
136 return fv_uv;
137 }
138
146 Gating gatingRhs_du(double u, Gating const& v) const
147 {
148 Gating guA = static_cast<Derived const&>(*this).gatingRhs(u-1e-5,v);
149 Gating guB = static_cast<Derived const&>(*this).gatingRhs(u+1e-5,v);
150 return (guB-guA)/2e-5;
151 }
152
158 GatingJacobian gatingRhs_dv(double u, Gating const& v) const
159 {
160 GatingJacobian gv_uv;
161 Gating col, dir, guv = static_cast<Derived const&>(*this).gatingRhs(u,v);
162 for (int i=0; i<nGating; ++i){
163 dir = 0;
164 dir[i]=1e-5;
165 col = (static_cast<Derived const&>(*this).gatingRhs(u,v+dir)-guv)/1e-5;
166 for (int j=0; j<nGating; ++j) gv_uv[j][i] = col[j];
167 }
168 return gv_uv;
169 }
170
171 protected:
181 void setRestState(double uFix, Gating const& vFix)
182 {
185
186 // Get the initial value for Newton's method
187 State x, dx;
188 x[0] = uFix; for (int i=0; i<nGating; ++i) x[i+1] = vFix[i];
189 std::cout << "x_init = " << x << std::endl;
190
191 State F; F = 0;
192 DState DF; DF = 0;
193
194 // perform a few ordinary (or simplified?) Newton iterations for the system [current,gatingRhs] = 0.
195
196 double uFix0 = uFix;
197 Gating vFix0(vFix);
198
199 double normF = 0, dxNorm = 0;
200 int steps = 0;
201
202 do
203 {
204 steps++;
205
206 double c = static_cast<Derived const&>(*this).current(uFix0,vFix0);
207
208 Gating g = static_cast<Derived const&>(*this).gatingRhs(uFix0,vFix0);
209
210 F[0] = c; for (int i=0; i<nGating; ++i) F[i+1] = g[i];
211 normF = F.infinity_norm();
212
213 double current_u = current_du(uFix0, vFix0);
214 Gating current_v = static_cast<Derived const&>(*this).current_dv(uFix0, vFix0);
215 Gating gatingRHS_u = static_cast<Derived const&>(*this).gatingRhs_du(uFix0, vFix0);
216 GatingJacobian gatingRHS_v = gatingRhs_dv(uFix0, vFix0);
217
218
219 DF[0][0] = current_u;
220 for (int i=0; i<nGating; ++i) DF[0][i+1] = -current_v[i];
221 for (int i=0; i<nGating; ++i) DF[i+1][0] = gatingRHS_u[i];
222 for (int i=0; i<nGating; ++i)
223 for (int j=0; j<nGating; ++j)
224 DF[i+1][j+1] = gatingRHS_v[i][j];
225
226
227 // solve DF*dx = -F, dx = x(j+1) - x(j)
228 DF.solve(dx,-F);
229
230 double d = 0.1;
231 uFix0 += d*dx[0];
232 for (int i=0; i<nGating; ++i)
233 vFix0[i] += d*dx[i+1];
234
235 dxNorm = dx.infinity_norm();
236 } while ( (normF > 1e-6) || (dxNorm > 1e-4) );
237
238 std::cout << " Newton steps = " << steps << std::endl;
239
240 // store the value
241 fix.first = uFix0;
242 for (int i=0; i<nGating; ++i)
243 fix.second[i] = vFix0[i];
244
245 std::cout << "fixpoint = " << fix.first << " " << fix.second << std::endl;
246
247 }
248
249
250 private:
251 std::string nm;
252 std::pair<double,Gating> fix;
253 };
254
255 //----------------------------------------------------------------------------------------
256
257
280 struct AlievPanfilov: public MembraneModelBase<AlievPanfilov,1>
281 {
285 static int const nGating = 1;
286
289
294
300 double current(double u, Gating const& v) const;
301
307 double current_du(double u, Gating const& v) const;
308
314 Gating current_dv(double u, Gating const& v) const;
315
321 Gating gatingRhs(double u, Gating const& v, double Istim=0) const;
322
328 Gating gatingRhs_du(double u, Gating const& v) const;
329
335 GatingJacobian gatingRhs_dv(double u, Gating const& v) const;
336
337 private:
338 double a, eps0, k, mu1, mu2;
339 };
340
341 //-----------------------------------------------------------------------------------------------------
342
378 struct PhysiologicalAlievPanfilov: public MembraneModelBase<PhysiologicalAlievPanfilov,1>
379 {
383 static int const nGating = 1;
384
387
394 PhysiologicalAlievPanfilov(double Cm = 1e-2/16);
395
401 double current(double u, Gating const& v) const;
402
408 double current_du(double u, Gating const& v) const;
409
415 Gating current_dv(double u, Gating const& v) const;
416
422 Gating gatingRhs(double u, Gating const& v, double Istim=0) const;
423
429 Gating gatingRhs_du(double u, Gating const& v) const;
430
436 GatingJacobian gatingRhs_dv(double u, Gating const& v) const;
437
438 private:
439 AlievPanfilov ap;
440 double Cm, s;
441 };
442
443 //-----------------------------------------------------------------------------------------------------
444
453 class FentonKarma: public MembraneModelBase<FentonKarma,2>
454 {
455 public:
459 static int const nGating = 2;
460
471 , GP
472 };
473
476
481 FentonKarma(ParameterSet p, double Cm = 1e-2);
482
488 double current(double u, Gating const& v) const;
489
495 double current_du(double u, Gating const& v) const;
496
502 Gating current_dv(double u, Gating const& v) const;
503
509 Gating gatingRhs(double u, Gating const& v, double Istim=0) const;
510
516 Gating gatingRhs_du(double u, Gating const& v) const;
517
523 GatingJacobian gatingRhs_dv(double u, Gating const& v) const;
524
525 private:
526 // A smoothed Heaviside function. The original Fenton-Karma model is partially formulated
527 // in terms of the discontinuous Heaviside function, which is in general a bad idea for numerical
528 // computations.
529 double h(double x) const;
530
531 double u0 = -0.085; // resting voltage
532 double ufi = 0.015; // maximum voltage
533 double k = 10; // scaling factor for tanh-based smooth Heaviside approximation as in article
534 double K = 3; // additional scaling factor for approximating non-smooth Heaviside
535 double Cm, gfi, taur, tausi, tau0, tauvplus, tauv1minus, tauv2minus, tauwplus, tauwminus, uc, uv, usic, taud;
536 };
537
538 //-----------------------------------------------------------------------------------------------------
539
546 struct TenTusscher16: public MembraneModelBase<TenTusscher16,16>
547 {
552
558 double current(double u, Gating const& v) const;
559
565 double current_du(double u, Gating const& v, double h=1e-5) const;
566
572 Gating current_dv(double u, Gating const& v) const;
573
579 Gating gatingRhs(double u, Gating const& v, double Istim=0) const;
580
586 Gating gatingRhs_du(double u, Gating const& v) const;
587
593 GatingJacobian gatingRhs_dv(double u, Gating const& v) const;
594 };
595
596
597
604 struct TenTusscher18: public MembraneModelBase<TenTusscher18,18>
605 {
610
616 double current(double u, Gating const& v) const;
617
623 double current_du(double u, Gating const& v, double h=1e-5) const;
624
630 Gating current_dv(double u, Gating const& v) const;
631
637 Gating gatingRhs(double u, Gating const& v, double Istim=0) const;
638 double gatingRhs1(double u, Gating const& v, int vId, double Istim=0) const;
639
645 Gating gatingRhs_du(double u, Gating const& v) const;
646
652 GatingJacobian gatingRhs_dv(double u, Gating const& v) const;
653 };
654
655
656
657 //-----------------------------------------------------------------------------------------------------
658
671 template <class Derived, int n, int m>
673 {
677 static int const nState = n;
678
682 static int const nTrigger = m;
683
688
693
698
703
708
714 ActiveStressModelBase(std::string const& name, State const& fix_): nm(name), fix(fix_) {}
715
719 std::string const& name() const { return nm; }
720
724 State const& restState() const { return fix; }
725
731 StateJacobian state_ds(State const& s, Trigger const& t) const
732 {
733 auto const& me = static_cast<Derived const&>(*this);
734 StateJacobian ds;
735 State r = me.state(s,t), dr, h;
736 for (int i=0; i<nState; ++i)
737 {
738 h = s;
739 h[i] += 1e-5;
740 dr = (me.state(h,t)-r)/1e-5;
741 for (int j=0; j<nState; ++j)
742 ds[j][i] = dr[j];
743 }
744 return ds;
745 }
746
752 StateTriggerJacobian state_dt(State const& s, Trigger const& t) const
753 {
754 auto const& me = static_cast<Derived const&>(*this);
756 State r = me.state(s,t), dr;
757 Trigger h;
758 for (int i=0; i<nTrigger; ++i)
759 {
760 h = t;
761 h[i] += 1e-5;
762 dr = (me.state(s,h)-r)/1e-5;
763 for (int j=0; j<nState; ++j)
764 ds[j][i] = dr[j];
765 }
766 return ds;
767 }
768
774 State stress_ds(State const& s) const
775 {
776 auto const& me = static_cast<Derived const&>(*this);
777 State da, h;
778 double r = me.stress(s);
779 for (int i=0; i<nState; ++i)
780 {
781 h = s;
782 h[i] += 1e-5;
783 da[i] = (me.stress(h)-r)/1e-5;
784 }
785 return da;
786 }
787
788 private:
789 std::string nm;
790 State fix;
791 };
792
796 class XXstress: public ActiveStressModelBase<XXstress,1,1>
797 {
798 public:
800
801 double stress(State const& s) const
802 {
803 return s[0];
804 }
805
806 State state(State const& s, Trigger const& t) const
807 {
808 double e0 = .5;
809 double kta = 47.9;
810// double un = t/120;
811 double un = t;
812 return e0 * (kta*un-s) / (1+exp(-100*(un-.05)));
813 }
814 };
815
816
817}
818
819#endif
The 3-variable Fenton-Karma membrane model.
ParameterSet
Different parameter sets provided.
@ MBR
modified Beeler-Reuter
@ BR
Beeler-Reuter model.
@ MLRI
modified Luo-Rudy I
@ GP
guinea pig model
Dune::FieldVector< double, nGating > Gating
Dune::FieldMatrix< double, nGating, nGating > GatingJacobian
FentonKarma(ParameterSet p, double Cm=1e-2)
Constructor.
Gating gatingRhs_du(double u, Gating const &v) const
The derivative of the right hand side for the evolution of gating variables w.r.t....
GatingJacobian gatingRhs_dv(double u, Gating const &v) const
The derivative of the right hand side for the evolution of gating variables w.r.t....
static int const nGating
number of gating variables
Gating gatingRhs(double u, Gating const &v, double Istim=0) const
The right hand side for the evolution of gating variables.
double current_du(double u, Gating const &v) const
The transmembrane ion current derivative w.r.t. the transmembrane voltage.
double current(double u, Gating const &v) const
The transmembrane ion current.
Gating current_dv(double u, Gating const &v) const
The transmembrane ion current derivative w.r.t. the gating variables.
Active stress generation from XX.
double stress(State const &s) const
State state(State const &s, Trigger const &t) const
Convenience base class for active stress generation models providing numerical differentiation.
StateJacobian state_ds(State const &s, Trigger const &t) const
The deriviative of internal state dynamics wrt state variables.
Dune::FieldMatrix< double, nState, nTrigger > StateTriggerJacobian
Matrix type for the derivative of the state dynamics wrt the triggers.
StateTriggerJacobian state_dt(State const &s, Trigger const &t) const
The deriviative of internal state dynamics wrt trigger variables.
Dune::FieldVector< double, nState > State
Vector type holding the internal variables.
std::string const & name() const
Human-readable name of the active stress model.
State const & restState() const
Value of the resting state fixed point.
static int const nTrigger
Number of trigger variables.
static int const nState
Number of internal state variables.
State stress_ds(State const &s) const
The derivative of stress wrt state variables.
ActiveStressModelBase()
Default constructor.
ActiveStressModelBase(std::string const &name, State const &fix_)
Constructor specifying the model data.
Dune::FieldMatrix< double, nState, nState > StateJacobian
Matrix type for the Jacobian of the State dynamics.
Dune::FieldVector< double, nTrigger > Trigger
Vector type holding trigger variables.
Phenomenological model by Aliev and Panfilov.
double current_du(double u, Gating const &v) const
The transmembrane ion current derivative w.r.t. the transmembrane voltage.
double current(double u, Gating const &v) const
The transmembrane ion current.
Gating gatingRhs_du(double u, Gating const &v) const
The derivative of the right hand side for the evolution of gating variables w.r.t....
GatingJacobian gatingRhs_dv(double u, Gating const &v) const
The derivative of the right hand side for the evolution of gating variables w.r.t....
static int const nGating
number of gating variables
Dune::FieldVector< double, nGating > Gating
AlievPanfilov()
Default constructor.
Gating current_dv(double u, Gating const &v) const
The transmembrane ion current derivative w.r.t. the gating variables.
Dune::FieldMatrix< double, nGating, nGating > GatingJacobian
Gating gatingRhs(double u, Gating const &v, double Istim=0) const
The right hand side for the evolution of gating variables.
Convenience base class for membrane models providing numerical differentiation.
MembraneModelBase(std::string const &name)
Constructor specifying the model data.
double current_du(double u, Gating const &v, double h=1e-5) const
The transmembrane ion current derivative w.r.t. the transmembrane voltage.
Dune::FieldVector< double, nGating > Gating
Vector type holding gating variables.
Gating gatingRhs_du(double u, Gating const &v) const
The derivative of the right hand side for the evolution of gating variables w.r.t....
Dune::FieldMatrix< double, nGating, nGating > GatingJacobian
Matrix type for the Jacobian of the gating dynamics.
Gating current_dv(double u, Gating const &v) const
The transmembrane ion current derivative w.r.t. the gating variables.
static int const nGating
Number of gating variables.
MembraneModelBase()
Default constructor.
GatingJacobian gatingRhs_dv(double u, Gating const &v) const
The derivative of the right hand side for the evolution of gating variables w.r.t....
void setRestState(double uFix, Gating const &vFix)
Accepts an (approximate) resting state.
std::string const & name() const
Human-readable name of the membrane model.
std::pair< double, Gating > const & restState() const
Value of the resting state fixed point.
Phenomenological model based on Aliev and Panfilov, scaled to physiological values.
Dune::FieldVector< double, nGating > Gating
double current(double u, Gating const &v) const
The transmembrane ion current.
GatingJacobian gatingRhs_dv(double u, Gating const &v) const
The derivative of the right hand side for the evolution of gating variables w.r.t....
static int const nGating
number of gating variables
Gating gatingRhs_du(double u, Gating const &v) const
The derivative of the right hand side for the evolution of gating variables w.r.t....
Gating gatingRhs(double u, Gating const &v, double Istim=0) const
The right hand side for the evolution of gating variables.
Dune::FieldMatrix< double, nGating, nGating > GatingJacobian
PhysiologicalAlievPanfilov(double Cm=1e-2/16)
Constructor.
Gating current_dv(double u, Gating const &v) const
The transmembrane ion current derivative w.r.t. the gating variables.
double current_du(double u, Gating const &v) const
The transmembrane ion current derivative w.r.t. the transmembrane voltage.
Physiologcial model by tenTusscher et al.
double current_du(double u, Gating const &v, double h=1e-5) const
The transmembrane ion current derivative w.r.t. the transmembrane voltage.
Gating gatingRhs(double u, Gating const &v, double Istim=0) const
The right hand side for the evolution of gating variables.
Gating current_dv(double u, Gating const &v) const
The transmembrane ion current derivative w.r.t. the gating variables.
GatingJacobian gatingRhs_dv(double u, Gating const &v) const
The derivative of the right hand side for the evolution of gating variables w.r.t....
Gating gatingRhs_du(double u, Gating const &v) const
The derivative of the right hand side for the evolution of gating variables w.r.t....
double current(double u, Gating const &v) const
The transmembrane ion current.
TenTusscher16()
Default constructor.
Physiologcial model by tenTusscher et al. (2006)
Gating gatingRhs_du(double u, Gating const &v) const
The derivative of the right hand side for the evolution of gating variables w.r.t....
GatingJacobian gatingRhs_dv(double u, Gating const &v) const
The derivative of the right hand side for the evolution of gating variables w.r.t....
Gating current_dv(double u, Gating const &v) const
The transmembrane ion current derivative w.r.t. the gating variables.
double gatingRhs1(double u, Gating const &v, int vId, double Istim=0) const
double current(double u, Gating const &v) const
The transmembrane ion current.
Gating gatingRhs(double u, Gating const &v, double Istim=0) const
The right hand side for the evolution of gating variables.
double current_du(double u, Gating const &v, double h=1e-5) const
The transmembrane ion current derivative w.r.t. the transmembrane voltage.
TenTusscher18()
Default constructor.