CEPS  24.01
Cardiac ElectroPhysiology Simulator
BR77.cpp
Go to the documentation of this file.
1 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2  This file is part of CEPS.
3 
4  CEPS is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  CEPS is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with CEPS (see file LICENSE at root of project).
16  If not, see <https://www.gnu.org/licenses/>.
17 
18 
19  Copyright 2019-2024 Inria, Universite de Bordeaux
20 
21  Authors, in alphabetical order:
22 
23  Pierre-Elliott BECUE, Florian CARO, Yves COUDIERE(*), Andjela DAVIDOVIC,
24  Charlie DOUANLA-LONTSI, Marc FUENTES, Mehdi JUHOOR, Michael LEGUEBE(*),
25  Pauline MIGERDITICHAN, Valentin PANNETIER(*), Nejib ZEMZEMI.
26  * : currently active authors
27 
28 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
30 #include "ode/ionicModels/BR77.hpp"
32 
34  Unknown* u,
35  AbstractPdeProblem* pb,
36  const CepsSet<CepsAttribute>& attrs,
37  InputParameters* params
38 ):
39  AbstractIonicModel(u,attrs)
40 {
41 
43  "Passed pointer to cardiac problem is null"
44  );
45 
46  m_name = "Beeler-Reuter 1977";
47  m_nStateVars = 7;
48  m_stateVarNames = {"m [adim]",
49  "h [adim]",
50  "j [adim]",
51  "CaI [concentration units]",
52  "d [adim]",
53  "f [adim]",
54  "x1 [adim]"};
55 
56  // ================================================================================
57  // Default parameters
58  m_constants = ceps::newArray<CepsReal>(2);
59  m_paperCm = 1.e-2;
60  m_paperStim = 0.5;
61  m_constants[_gS ] = 9.e-4;
62  m_constants[_ENa] = 5.e+1;
63 
64  // Create entries in the function dictionary
66  dico->add("br77gNa" ,"CONSTANT 4.e-2");
67  dico->add("br77gNaCa","CONSTANT 3.e-5");
68 
69  // ================================================================================
70  // Parameters from text inputs, if any
71  if (ceps::isValidPtr(params))
72  setupWithParameters(params,dico,pb);
73 
74  // ================================================================================
75  // Initialize scalar fields for gNa and gNaCa
78 
79  m_gNa = ceps::getNew<ScalarField<DegreeOfFreedom>>(dico->getScalar("br77gNa" ),&dofs,true);
80  m_gNaCa = ceps::getNew<ScalarField<DegreeOfFreedom>>(dico->getScalar("br77gNaCa"),&dofs,true);
81 
82  // Restrict support if the model is defined on selected attributes
83  if (not m_attributes.empty())
84  {
86  selec.setAttributes(m_attributes.begin(),m_attributes.end());
87  m_gNa ->computeSupport(&selec);
88  m_gNaCa->computeSupport(&selec);
89  }
90 
91 }
92 
93 void
95 {
96  *v = -84.624;
97  y[_m ] = 0.011;
98  y[_h ] = 0.988;
99  y[_j ] = 0.975;
100  y[_CaI] = 1.e-4;
101  y[_d ] = 3.e-3;
102  y[_f ] = 0.994;
103  y[_x1 ] = 1.e-4;
104 }
105 
106 void
108  CepsReal t,
109  CepsReal* y,
110  CepsReal* vm,
111  CepsReal* dtyLin,
112  CepsReal* dtyNLin,
113  CepsReal* dtv,
114  DegreeOfFreedom* dof
115 ) const
116 {
117 
118  CepsReal* cst = m_constants;
119  CepsReal v = *vm;
120 
121  // Gate variables
122  CepsReal alpha;
123  CepsReal beta;
124 
125  alpha = -(v+47.)/std::expm1(-0.1*(v+47.));
126  beta = 40*std::exp(-0.056*(v+72.));
127  dtyLin [_m] = -alpha-beta;
128  dtyNLin[_m] = alpha;
129 
130  alpha = 0.126*std::exp(-0.25*(v+77.));
131  beta = 1.7*sigmoid(v,-22.5,-1./0.082);
132  dtyLin [_h] = -alpha-beta;
133  dtyNLin[_h] = alpha;
134 
135  // The sigmoids version refer to the original paper and can also be found in Myokit.
136  // In comments, the cellML version, with divisions
137 
138  alpha = 0.055*std::exp(-0.25*(v+78))*sigmoid(v,-78,-1./0.2); // /(1+std::exp(-0.2*(v+78)));
139  beta = 0.3 *sigmoid(v,-32,-1./0.1); // /(1+std::exp(-0.1*(v+32)));
140  dtyLin [_j] = -alpha-beta;
141  dtyNLin[_j] = alpha;
142 
143  alpha = 0.095*std::exp(-(v-5. )/100.)*sigmoid(v,+ 5,-1./0.072); // /(1+std::exp(-(v-5. )/13.89));
144  beta = 0.07 *std::exp(-(v+44.)/ 59.)*sigmoid(v,-44,+1./0.05 ); // /(1+std::exp( (v+44.)/20. ));
145  dtyLin [_d] = -alpha-beta;
146  dtyNLin[_d] = alpha;
147 
148  alpha = 0.012 *std::exp(-(v+28.)/125.)*sigmoid(v,-28,+1./0.15); // /(1+std::exp( (v+28.)/6.67));
149  beta = 0.0065*std::exp(-(v+30.)/50. )*sigmoid(v,-30,-1./0.2 ); // /(1+std::exp(-(v+30.)/5. ));
150  dtyLin [_f] = -alpha-beta;
151  dtyNLin[_f] = alpha;
152 
153  alpha = 0.0005*std::exp( (v+50.)/12.10)*sigmoid(v,-50, 1./0.057); // /(1+std::exp( (v+50.)/17.5));
154  beta = 0.0013*std::exp(-(v+20.)/16.67)*sigmoid(v,-20,-1./0.04 ); // /(1+std::exp(-(v+20.)/25.0));
155  dtyLin [_x1] = -alpha-beta;
156  dtyNLin[_x1] = alpha;
157 
158  // Last state variable caI
159  CepsReal Es = -82.3-13.0287*std::log(y[_CaI]*0.001);
160  CepsReal iS = cst[_gS]*y[_d]*y[_f]*(v-Es);
161  dtyNLin[_CaI] = 7.e-6 -0.01*iS;
162  dtyLin [_CaI] = -0.07;
163 
164  // Fetch Ionic current
165  CepsReal gNa = m_gNa ->getValue(dof,t);
166  CepsReal gNaCa = m_gNaCa->getValue(dof,t);
167 
168  CepsReal iNa = this->getINa(y,gNaCa,gNa,v);
169  CepsReal iX1 = y[_x1] *0.008*std::expm1(0.04*(v+77)) / std::exp(0.04*(v+35.));
170  CepsReal tmp = std::exp(0.04*(v+53.));
171  CepsReal iK1 = 0.0035*(4.*std::expm1(0.04*(v+85.))/(tmp*tmp+tmp)
172  + 0.2/0.04*uOverExpm1u(-0.04*(v+23.)));
173 
174  CepsReal cm = getCmInternal(t,dof);
175  CepsReal iStim = getStimulation(dof,t);
176  CepsReal iion = -(iNa+iS+iK1+iX1);
177  #ifdef DEBUG
178  ceps::checkNanOrInf(iion,
179  "Ionic current on DoF " + CepsString(dof->getGlobalIndex() + " at time" + CepsString(t))
180  );
181  #endif
182 
183  *dtv= iion + iStim;
184  *dtv /= cm;
185 
186 }
187 
188 CepsReal
190 {
191  return i/100.;
192 }
193 
194 CepsReal
196 {
197  return 100*cm;
198 }
199 
200 CepsReal
202 {
203  return 0.01*cm;
204 }
205 
206 void
208 {
209  m_constants[_gS ] = params->getReal("BR77 gS" ,m_constants[_gS ]);
210  m_constants[_ENa] = params->getReal("BR77 ENa",m_constants[_ENa]);
211 
212  for (CepsString key: {"BR77gNa","BR77gNaCa"})
213  if (params->hasKey(key))
214  {
215  dico->deleteScalar(key);
216  dico->add(key,params->getString(key),pb->getGeometry());
217  }
218 
219 }
220 
221 CepsReal
223 {
224  return (gNa*std::pow(y[_m],3.)*y[_h]*y[_j]+gNaCa)*(v-m_constants[_ENa]);
225 }
226 
227 // ==========================================================================
228 
230  Unknown* u,
231  AbstractPdeProblem* pb,
232  const CepsSet<CepsAttribute>& attrs,
233  InputParameters* params
234 ):
235  BR77(u,pb,attrs,params)
236 {
237 
238  m_name = "Beeler-Reuter 1977 Modified";
239 
240  // ================================================================================
241  // Default parameters
242  delete[] m_constants;
243  m_constants = ceps::newArray<CepsReal>(4);
244  m_constants[_gS ] = 9.e-4;
245  m_constants[_ENa] = 5.e+1;
246  m_constants[_vA ] = -85*5;
247  m_constants[_vB ] = 30+5*115;
248 
249  // ================================================================================
250  // Parameters from text inputs, if any
252  if (ceps::isValidPtr(params))
253  setupWithParameters(params,dico,pb);
254 
255 }
256 
257 void
259 {
260  BR77::setupWithParameters(params,dico,pb);
261  m_constants[_vA] = params->getReal("BR77 a" ,m_constants[_vA]);
262  m_constants[_vB] = params->getReal("BR77 b" ,m_constants[_vB]);
263 }
264 
265 CepsReal
267 {
268 
269  CepsReal iNa;
270  CepsReal a = m_constants[_vA];
271  CepsReal b = m_constants[_vB];
272 
273  CepsReal iNaA = BR77::getINa(y,gNaCa,gNa,a);
274  CepsReal iNaB = BR77::getINa(y,gNaCa,gNa,b);
275 
276  if (ceps::greaterThan(v,b) and not ceps::equals(iNaB,0.))
277  {
278  CepsReal kB = -1/iNaB*(gNa*std::pow(y[_m],3.)*y[_h]*y[_j]+gNaCa);
279  iNa = iNaB*(1+std::tanh(kB*(v-b)));
280  }
281  else if (ceps::lesserThan(v,a) and not ceps::equals(iNaA,0.))
282  {
283  CepsReal kA = 1/iNaA*(gNa*std::pow(y[_m],3.)*y[_h]*y[_j]+gNaCa);
284  iNa = iNaA*(1-std::tanh(kA*(v-a)));
285  }
286  else
287  iNa = BR77::getINa(y,gNaCa,gNa,v);
288 
289  return iNa;
290 }
#define CEPS_ABORT_IF(condition, message)
Stops the execution with a message if condition is true. If testing is enabled, only throws a runtime...
std::basic_string< CepsChar > CepsString
C++ format string.
Definition: CepsTypes.hpp:128
std::set< _Type, _Compare, _Alloc > CepsSet
C++ set.
Definition: CepsTypes.hpp:209
std::vector< _Type, _Alloc > CepsVector
C++ vector.
Definition: CepsTypes.hpp:155
float CepsReal
Need single precision floating point.
Definition: CepsTypes.hpp:100
Abstract Class for all numerical method (FE, FD, FV etc)
const CepsMap< CepsUnknownIndex, CepsVector< DegreeOfFreedom * > > & getDegreesOfFreedomForUnknown()
Dofs sorted by unknown.
Represents a ionic model for a group of cells, i.e. multiple systems of ODEs.
CepsReal m_paperStim
Original stim amplitude.
CepsUInt m_nStateVars
Dimensionality of the ODE system, -1 for vm.
CepsReal * m_constants
Constant parameters of the model, from inputs.
CepsReal getStimulation(DegreeOfFreedom *x, CepsReal t) const
Get the sum of all stimulations at time t and dof x.
CepsReal uOverExpm1u(CepsReal u) const
Functions u/(1-exp(u)) that returns 2 (from expansion around 0)
CepsVector< CepsString > m_stateVarNames
Names of state variables.
CepsReal getCmInternal(CepsReal t, DegreeOfFreedom *dof) const
Get either the value of cm on dof, or the default value from the paper.
Unknown * m_unknown
Pointer on unknown on which the model applies.
CepsReal m_paperCm
Original value of Cm.
CepsReal sigmoid(CepsReal x, CepsReal c, CepsReal k) const
Function often used in rates evaluations.
CepsString m_name
A label for display.
Base class for creating PDEs to solve.
FunctionDictionary * getFunctionDictionary() const
Get functions manager.
AbstractDiscretization * getSpatialDiscretization() const
Link to the spatial discretization (FE, FV, etc)
Geometry * getGeometry() const
Link to geometry on which the pb is defined.
static constexpr const CepsInt _vB
Maximum voltage above which current is bounded.
Definition: BR77.hpp:152
virtual CepsReal getINa(CepsReal *y, CepsReal gNaCa, CepsReal gNa, CepsReal v) const override
Returns the bounded current I_Na BR current.
Definition: BR77.cpp:266
BR77Modified(Unknown *u, AbstractPdeProblem *pb, const CepsSet< CepsAttribute > &attrs={}, InputParameters *params=nullptr)
Constructor (sets constants)
Definition: BR77.cpp:229
void setupWithParameters(InputParameters *p, FunctionDictionary *dico, AbstractPdeProblem *pb)
Sets the constants and the space dependant parameters from text inputs.
Definition: BR77.cpp:258
static constexpr const CepsInt _vA
Minimum voltage below which current is bounded.
Definition: BR77.hpp:151
Beeler Reuter (1977) ionic model.
Definition: BR77.hpp:50
static constexpr const CepsInt _ENa
Index alias.
Definition: BR77.hpp:111
void computeRates(CepsReal t, CepsReal *y, CepsReal *v, CepsReal *dtyL, CepsReal *dtyNL, CepsReal *dtv, DegreeOfFreedom *dof) const override
Get the linear and non linear part of the evolution function f. Also computes the ionic current.
Definition: BR77.cpp:107
static constexpr const CepsInt _CaI
Index alias.
Definition: BR77.hpp:117
ScalarField< DegreeOfFreedom > * m_gNa
This parameter may vary with space.
Definition: BR77.hpp:106
static constexpr const CepsInt _f
Index alias.
Definition: BR77.hpp:119
void setupWithParameters(InputParameters *p, FunctionDictionary *dico, AbstractPdeProblem *pb)
Sets the constants and the space dependant parameters from text inputs.
Definition: BR77.cpp:207
CepsReal convertCmFromCepsUnit(const CepsReal &cm) const final
Convert capacitance from ceps units (uF/cm2) to ionic model units. Does nothing by default.
Definition: BR77.cpp:201
CepsReal convertCurrentFromCepsUnit(const CepsReal &v) const final
Convert from muA per cm2 to muA per mm2.
Definition: BR77.cpp:189
BR77(Unknown *u, AbstractPdeProblem *pb, const CepsSet< CepsAttribute > &attrs={}, InputParameters *params=nullptr)
Constructor (sets constants)
Definition: BR77.cpp:33
void getInitialCondition(CepsReal *v, CepsReal *y) const final
Sets initial values of state variables and transmembrane voltage for a single point....
Definition: BR77.cpp:94
virtual CepsReal getINa(CepsReal *y, CepsReal gNaCa, CepsReal gNa, CepsReal v) const
Returns the iNa current.
Definition: BR77.cpp:222
static constexpr const CepsInt _m
Index alias.
Definition: BR77.hpp:114
CepsReal convertCmToCepsUnit(const CepsReal &cm) const final
Convert capacitance from ionic model units to ceps units (uF/cm2). Does nothing by default.
Definition: BR77.cpp:195
static constexpr const CepsInt _h
Index alias.
Definition: BR77.hpp:115
ScalarField< DegreeOfFreedom > * m_gNaCa
This parameter may vary with space.
Definition: BR77.hpp:107
static constexpr const CepsInt _j
Index alias.
Definition: BR77.hpp:116
static constexpr const CepsInt _d
Index alias.
Definition: BR77.hpp:118
static constexpr const CepsInt _x1
Index alias.
Definition: BR77.hpp:120
static constexpr const CepsInt _gS
Index alias.
Definition: BR77.hpp:110
A degree of freedom for any kind of problem The dof can be associated to a geometrical element or not...
FunctionDictionary that holds functions which can be used to define source terms, boundary conditions...
void add(const CepsString &label, const CepsString &params, Geometry *geom=nullptr)
Add an object from parameters.
void deleteScalar(const CepsString &label)
Delete a single scalar entry. Be careful if the functor was created outside dictionary.
const ScalarEntry getScalar(const CepsString &label) const
Get a single scalar entry, const version.
Reads and stores simulation configuration.
CepsBool hasKey(const keyType &key) const
Tells if key exists in input file.
CepsString getString(const keyType &key) const
Reads a CepsString from configuration.
CepsReal getReal(const keyType &key) const
Reads a floating point value from configuration.
A class used to defined an unknown of a PDE problem The unknown can be defined on a specific region,...
Definition: Unknown.hpp:45
CepsSet< CepsAttribute > m_attributes
The attributes held by the entity.
void setAttributes(const CepsVector< CepsAttribute > &attributes)
Sets the attributes of the entity.
const CepsGlobalIndex & getGlobalIndex() const
Get the index
CepsBool isValidPtr(_Type *ptr)
Tells if pointer is not null.
Definition: CepsMemory.hpp:61
CepsBool greaterThan(CepsReal a, CepsReal b, CepsReal epsilon=FLOATING_POINT_EPSILON)
Greater than comparison with epsilon tolerance.
Definition: Precision.hpp:98
CepsBool isNullPtr(_Type *ptr)
Tells if passed pointer is null.
Definition: CepsMemory.hpp:45
void checkNanOrInf(CepsReal v, CepsString message="")
Stops if value is NaN or infty.
CepsBool lesserThan(CepsReal a, CepsReal b, CepsReal epsilon=FLOATING_POINT_EPSILON)
Lesser than comparison with epsilon tolerance.
Definition: Precision.hpp:111
CepsBool equals(CepsReal a, CepsReal b, CepsReal error=1.0)
CepsReal equality up to machine precision.
Definition: Precision.hpp:54