CEPS  24.01
Cardiac ElectroPhysiology Simulator
CardiacProblem.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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
32 
33 // -----------------------------------------------------------------------------------------------
34 // PUBLIC
35 
38  HeatProblem (g,params),
39  m_CmOptions (""),
40  m_AmOptions ("CONSTANT 1000"),
41  m_ionOptions (""),
42  m_fibersOptions (""),
43  m_sigmaIOptions ("CONSTANT 0.4 0.2 0.2"),
44  m_sigmaEOptions ("CONSTANT 0.4 0.2 0.2"),
45  m_volFracOptions (""),
46  m_volFracItpFileI (""),
47  m_volFracItpFileE (""),
48  m_stimOptions (""),
49  m_bcStimOptions (""),
50  m_tissueAttributes ({-1}),
51  m_Cm (nullptr),
52  m_Am (nullptr),
53  m_ionicModels ({}),
54  m_sigmaI (nullptr),
55  m_sigmaE (nullptr),
56  m_volFrac (nullptr)
57 {
58  if (ceps::isValidPtr(params))
60 }
61 
64 {
67  for (auto ionM: m_ionicModels)
68  ceps::destroyObject(ionM);
72 }
73 
74 void
76 {
77  vm->zero();
78  for (auto model: m_ionicModels)
79  model->getLinkedSolver()->fillPdeVm(vm);
80 }
81 
84 {
85  return m_ionicModels;
86 }
87 
90 {
91  return m_Am;
92 }
93 
96 {
97  return m_Cm;
98 }
99 
102 {
103  return m_sigmaI;
104 }
105 
108 {
109  return m_sigmaE;
110 }
111 
114 {
115  return m_tissueAttributes;
116 }
117 
118 
119 // -------------------------------------------------------------------------------------------------
120 // Protected
121 
122 void
124 {
125  this->defineUnknowns();
127 
129  CEPS_SAYS("Setting up elements of the cardiac problem");
131  initializeCm();
132  initializeAm();
133  this->initializeConductivities();
134 
135  this->defineSourceTerms();
136  this->defineBoundaryConditions();
137  this->defineAnalyticSolution();
138 }
139 
140 void
142 {
143 
144  CepsSet<CepsInt> attrs = ceps::toInts(params->getString("tissue attributes",""));
145  if (not attrs.empty())
146  {
147  m_tissueAttributes.clear();
148  m_tissueAttributes.insert(attrs.begin(),attrs.end());
149  }
150 
152  m_ionOptions = params->getString("ionic model");
153 
154  if (params->hasKey("membrane capacitance"))
155  m_CmOptions = params->getString("membrane capacitance",m_CmOptions);
156  else
157  m_CmOptions = params->getString("cm",m_CmOptions);
158 
159  if (params->hasKey("membrane surface"))
160  m_AmOptions = params->getString("membrane surface",m_AmOptions);
161  else
162  m_AmOptions = params->getString("am",m_AmOptions);
163 
164  m_fibersOptions = params->getString("fibers",m_fibersOptions);
165 
166  if (params->hasKey("sigma i"))
167  m_sigmaIOptions = params->getString("sigma i",m_sigmaIOptions);
168  else
169  m_sigmaIOptions = params->getString("intracellular conductivity",m_sigmaIOptions);
170  if (params->hasKey("sigma e"))
171  m_sigmaEOptions = params->getString("sigma e",m_sigmaEOptions);
172  else
173  m_sigmaEOptions = params->getString("extracellular conductivity",m_sigmaEOptions);
174 
175  m_volFracOptions = params->getString("volume fraction",m_volFracOptions);
176  m_volFracItpFileI = params->getString("volume fraction map intracellular",m_volFracItpFileI);
177  m_volFracItpFileE = params->getString("volume fraction map extracellular",m_volFracItpFileE);
178 
179  m_stimOptions = params->getString("stimulation" ,m_stimOptions );
180  m_bcStimOptions = params->getString("boundary stimulation",m_bcStimOptions);
181 }
182 
183 void
185 {
186 
187  if (not m_CmOptions.empty())
188  m_functions->add("dicoCm",m_CmOptions);
189  else
190  // Build Cm vector from ionic models in case it is needed by the PDE.
191  {
193  for (auto model: m_ionicModels)
194  for (auto attr: model->getAttributes())
195  cmMap[attr] = model->getPaperCm(true);
196  // Add a -1 entry in case it is not defined everywhere
197  // it is a default value : eval starts with meaningful attributes
198  cmMap[-1] = 1.;
199  m_functions->addEntry("dicoCm",newCstPiecewiseSAFunc(cmMap));
200  }
201 
202  auto dofs = m_discr->getDistributedDofs();
203  m_Cm = ceps::getNew<ScalarField<DegreeOfFreedom>>(m_functions->getScalar("dicoCm"),&(dofs->getOwned()));
204 
205  // Link Cm built from options to ionic models
206  if (not m_CmOptions.empty())
207  for (auto model: m_ionicModels)
208  model->setCm(m_Cm);
209 
210  return;
211 }
212 
213 void
215 {
216  m_functions->add("dicoAm",m_AmOptions);
217  auto dofs = m_discr->getDistributedDofs();
218  m_Am = ceps::getNew<ScalarField<DegreeOfFreedom>>(m_functions->getScalar("dicoAm"),&(dofs->getOwned()));
219  return;
220 }
221 
222 void
224 {
225 
226  m_ionicModels.clear();
227 
228  CEPS_ABORT_IF(m_ionOptions.empty(),
229  "There is no ionic model provided as input !"
230  );
231  // This map keeps track of all ionic models region assignments for all unknowns
233  auto tAttrs = this->getTissueAttributes();
234 
235  for (CepsString ionOpt : ceps::split(m_ionOptions,","))
236  m_ionicModels.push_back(getIonicModelFromString(ionOpt,m_parameters,this,prevAttrs,tAttrs));
237 
238  return;
239 
240 }
241 
242 void
244 {
246 }
247 
248 void
250  CepsString sigmaIOpts,
251  CepsString sigmaEOpts,
252  TensorField<GeomCell>*& sigmaI,
253  TensorField<GeomCell>*& sigmaE,
254  CepsString fiberOptions,
255  CepsString suffix
256 )
257 {
258  CepsBool doVolFrac = not m_volFracOptions.empty();
259 
260  // ==========================================================
261  // Volume fraction : a reference tensor is interpolated from file
262  if (doVolFrac)
263  {
264  auto words = ceps::split(m_volFracOptions);
265 
266  CepsString errMessage =
267  CepsString("Incorrect options for volume fraction: please provide either :\n") +
268  " - a file name and the name of the scalar data array, defined on cells.\n" +
269  " - a string defining a physical coefficient (cf documentation)\n";
270 
271  CEPS_ABORT_IF(words.size()<1,errMessage);
272 
273  if (ceps::fileExists(words[0]))
274  {
275  CEPS_ABORT_IF(words.size()<2,errMessage);
276  m_functions->add("volFrac","FILE " + words[0] + " SCALAR " + words[1] + " CELL",getGeometry());
277  }
278  else
279  {
280  m_functions->add("volFrac",m_volFracOptions);
281  }
282 
283  // Create the scalar field with vol frac
284 
285  // Create interpolation table
286  CepsMap<CepsReal,CepsMathTensor> tableI,tableE;
287  std::ifstream ifileI(m_volFracItpFileI);
288  CEPS_ABORT_IF(not ifileI.good(),
289  "Unable to open file with volume fraction interpolation map : " << m_volFracItpFileI
290  );
291 
292  CepsUInt n = ceps::readInt(ifileI,"Unable to read number of lines in volume fraction table file");
293  for (CepsUInt i=0;i<n;i++)
294  {
295  CepsReal x = ceps::readReal (ifileI,"Cannot read coefficient in volume fraction table");
296  CepsMathTensor t = ceps::readTensor(ifileI,"Cannot read tensor in volume fraction table");
297  tableI[x] = t;
298  }
299  std::ifstream ifileE(m_volFracItpFileE);
300  CEPS_ABORT_IF(not ifileE.good(),
301  "Unable to open file with volume fraction interpolation map : " << m_volFracItpFileE
302  );
303 
304  n = ceps::readInt(ifileE,"Unable to read number of lines in volume fraction table file");
305  for (CepsUInt i=0;i<n;i++)
306  {
307  CepsReal x = ceps::readReal (ifileE,"Cannot read coefficient in volume fraction table");
308  CepsMathTensor t = ceps::readTensor(ifileE,"Cannot read tensor in volume fraction table");
309  tableE[x] = t;
310  }
311 
312  ScalarSAFunc* funcV = ceps::runtimeCast<ScalarSAFunc*>(m_functions->getScalar("volFrac"));
313 
314  m_functions->addEntry("sigmaIVF"+suffix,newCoeffInterpolatorSAFunc(tableI,funcV));
315  m_functions->addEntry("sigmaEVF"+suffix,newCoeffInterpolatorSAFunc(tableE,funcV));
316 
317  // We modify conductivity only in the tissue !
318  m_functions->add("sigmaIOrg"+suffix,sigmaIOpts);
319  m_functions->add("sigmaEOrg"+suffix,sigmaEOpts);
320 
321  for (CepsString tag: {"I","E"})
322  {
323  CepsString tmpopts = "FPIECEWISE ";
324  for (CepsAttribute attr : this->getTissueAttributes())
325  tmpopts += ceps::toString(attr) + " sigma"+tag+"VF"+suffix+", ";
326  tmpopts += "-1 sigma"+tag+"Org"+suffix;
327  m_functions->add("sigma"+tag+"Ref"+suffix,tmpopts);
328  }
329 
330  }
331  // ==========================================================
332  // No volume fraction : a reference diagonal tensor is read from options
333  else
334  {
335  m_functions->add("sigmaIRef"+suffix,sigmaIOpts);
336  m_functions->add("sigmaERef"+suffix,sigmaEOpts);
337  }
338 
339  createFibersAndConductivities(fiberOptions,sigmaI,sigmaE,suffix);
340 
341 }
342 
343 void
345 {
346 
347  CepsUInt i=0;
348  for (CepsString opts: ceps::split(m_stimOptions,","))
349  {
350  // Add function to dictionary
351  CepsString label = "stim"+ceps::toString(i);
352  m_functions->addFunction("dico"+label,opts);
353 
354  CepsString fullOpts = "dico" + label + " " + opts + " TYPE IAPP";
355  if (this->getTMVUnknowns().size()==1 and opts.find("UNKNOWN") == opts.npos)
356  fullOpts += " UNKNOWN 0";
357 
358  m_sourceTerms->add(label,fullOpts,true);
359 
360  // Link stimulation to corresponding ionic model
361  ScalarSourceTerm* stim = m_sourceTerms->getSourceTerm(label); // we just created it
362  Unknown* u = this->getUnknown(stim->getUnknownId());
363  for (AbstractIonicModel* model: m_ionicModels)
364  if (model->getUnknown() == u)
365  model->addStimulation(stim);
366 
367  i++;
368  }
369 
370 }
371 
372 void
374 {
375  CepsUInt i=0;
376  for (CepsString opts: ceps::split(m_bcStimOptions,","))
377  {
378  // Add function to dictionary
379  CepsString label = "bcstim"+ceps::toString(i);
380  m_functions->addFunction("dico"+label,opts);
381 
382  CepsString fullOpts = "dico" + label + " " + opts;
383 
384  if (this->getTMVUnknowns().size()==1 and opts.find("UNKNOWN") == opts.npos)
385  fullOpts += " UNKNOWN 0";
386 
387  if (opts.find("DIRICHLET") != opts.npos)
389  else if (opts.find("NEUMANN") != opts.npos)
391  else
392  {
393  CEPS_ABORT(
394  "When specifying a boundary stimulation, the DIRICHLET or "
395  "NEUMANN keyword must be given in the options"
396  );
397  }
398 
399  i++;
400  }
401 
402 }
403 
404 void
406 {
408 }
409 
410 void
412  CepsString fiberOptions,
413  TensorField<GeomCell>*& sigmaI,
414  TensorField<GeomCell>*& sigmaE,
415  CepsString suffix
416 )
417 {
418  CepsBool doVolFrac = not m_volFracOptions.empty();
419 
420  if (fiberOptions.empty())
421  {
422  m_functions->add("fibersL"+suffix,"CONSTANT 1. 0. 0.");
423  m_functions->add("fibersT"+suffix,"CONSTANT 0. 1. 0.");
424  m_functions->add("fibersN"+suffix,"CONSTANT 0. 0. 1.");
425  }
426  else
427  {
428  auto words = ceps::split(fiberOptions);
429 
430  if (ceps::fileExists(words[0]))
431  {
432  CepsString keywordL = words.size() < 2 ? "fibers" : words[1];
433  CepsString keywordT = words.size() < 3 ? "fibers_transverse" : words[2];
434  CepsString keywordN = words.size() < 4 ? "fibers_normal" : words[3];
435  m_functions->addFromFile("fibersL"+suffix,words[0]+" VECTOR "+keywordL+" CELL",getGeometry());
436  m_functions->addFromFile("fibersT"+suffix,words[0]+" VECTOR "+keywordT+" CELL",getGeometry(),true);
437  m_functions->addFromFile("fibersN"+suffix,words[0]+" VECTOR "+keywordN+" CELL",getGeometry(),true);
438  }
439  else
440  {
441  auto fopts = ceps::split(fiberOptions,",");
442  m_functions->add("fibersL"+suffix,fopts[0],m_geom);
443  if (fopts.size()>1)
444  m_functions->add("fibersT"+suffix,fopts[1],m_geom);
445  if (fopts.size()>2)
446  m_functions->add("fibersN"+suffix,fopts[2],m_geom);
447  }
448 
449  }
450 
451  VectorSAFunc* fL = m_functions->getVector("fibersL"+suffix);
452  VectorSAFunc* fT = m_functions->getVector("fibersT"+suffix,nullptr);
453  VectorSAFunc* fN = m_functions->getVector("fibersN"+suffix,nullptr);
454 
455  CEPS_ABORT_IF(doVolFrac and ceps::isNullPtr(fT),
456  "Using volume fraction requires that at least two components of the fibers orientation are provided"
457  );
458 
459  if (m_functions->hasTensor("sigmaIRef"))
460  {
461  m_functions->addEntry("sigmaI"+suffix,new FiberAligner(fL,fT,fN,m_functions->getTensor("sigmaIRef")));
462  m_functions->addEntry("sigmaE"+suffix,new FiberAligner(fL,fT,fN,m_functions->getTensor("sigmaERef")));
463  }
464  else
465  {
466  m_functions->addEntry("sigmaI"+suffix,new FiberAligner(fL,fT,fN,nullptr,m_functions->getVector("sigmaIRef")));
467  m_functions->addEntry("sigmaE"+suffix,new FiberAligner(fL,fT,fN,nullptr,m_functions->getVector("sigmaERef")));
468  }
469 
470  // ==========================================================
471  // Create fields
472 
473  // We do not bufferize data, unless there is volume fraction, which makes conductivity
474  // different at each point
476  sigmaI = ceps::getNew<TensorField<GeomCell>>(m_functions->getTensor("sigmaI"+suffix),&emp,doVolFrac);
477  sigmaE = ceps::getNew<TensorField<GeomCell>>(m_functions->getTensor("sigmaE"+suffix),&emp,doVolFrac);
478 
479  // In optimized mode adding the empty vector domain does not seem to work
480  // size is undefined, very large
481  sigmaI->clearDomains();
482  sigmaE->clearDomains();
483 
484  for(CepsUInt dim=1;dim<=3;dim++)
485  if (m_geom->hasMeshOfDim(dim))
486  {
487  sigmaI->addDomain(&(m_geom->getMeshOfDim(dim)->getCells()));
488  sigmaE->addDomain(&(m_geom->getMeshOfDim(dim)->getCells()));
489  }
490 
491 }
492 
494  VectorSAFunc* fL,
495  VectorSAFunc* fT,
496  VectorSAFunc* fN,
497  TensorSAFunc* sT,
498  VectorSAFunc* sV
499 ):
500  m_fL(fL),m_fT(fT),m_fN(fN),m_sT(sT),m_sV(sV)
501 {
502 }
503 
506 {
507 
508  if (ceps::isNullPtr(m_fT)) // one direction
509  {
510  CepsReal g0 = ceps::isNullPtr(m_sT) ? m_sV->eval(args)(0) : m_sT->eval(args)(0,0);
511  CepsReal g1 = ceps::isNullPtr(m_sT) ? m_sV->eval(args)(1) : m_sT->eval(args)(1,1);
512  CepsMathVertex f = m_fL->eval(args);
513  CepsMathTensor outer = f*f.transpose();
514  return g1*CepsMathTensor::Identity() + (g0-g1)*outer;
515  }
516 
517  CepsMathTensor f;
518  CepsMathTensor s;
519  if (ceps::isNullPtr(m_sT))
520  s = m_sV->eval(args).asDiagonal();
521  else
522  s = m_sT->eval(args);
523 
524  f.col(0) = m_fL->eval(args);
525  f.col(1) = m_fT->eval(args);
526  if (ceps::isNullPtr(m_fN)) // two directions
527  f.col(2) = f.col(0).cross(f.col(1));
528  else
529  f.col(2) = m_fN->eval(args);
530 
531  return f*s*f.transpose();
532 
533 }
534 
535 CepsEnum
537 {
538  CepsEnum res1 = m_fL->getFlags();
539  if (ceps::isValidPtr(m_fT))
540  res1 = res1 | m_fT->getFlags();
541  if (ceps::isValidPtr(m_fN))
542  res1 = res1 | m_fN->getFlags();
543 
544  CepsEnum res2 = ceps::isValidPtr(m_sT) ? m_sT->getFlags() : m_sV->getFlags();
545 
546  return res1 | res2;
547 
548 }
549 
550 
AbstractIonicModel * getIonicModelFromString(CepsString ionOpts, InputParameters *params, AbstractPdeProblem *pb, CepsMap< CepsUnknownIndex, CepsSet< CepsAttribute >> &prevAttrs, const CepsSet< CepsAttribute > &tissueAttrs)
Obtain a new instance of ionic model from input string.
@ Dirichlet
Dirichlet BC.
#define CEPS_ABORT(message)
Stops the execution with a message. If testing is enabled, only throws a runtime_error.
#define CEPS_SAYS(message)
Writes a message in the debug log and in the terminal (stdio).
#define CEPS_ABORT_IF(condition, message)
Stops the execution with a message if condition is true. If testing is enabled, only throws a runtime...
#define CEPS_SEPARATOR
Writes a separator in the debug log and in the terminal.
std::basic_string< CepsChar > CepsString
C++ format string.
Definition: CepsTypes.hpp:128
std::map< _Key, _Tp, _Compare, _Alloc > CepsMap
C++ map.
Definition: CepsTypes.hpp:196
int CepsEnum
Enum type.
Definition: CepsTypes.hpp:216
std::set< _Type, _Compare, _Alloc > CepsSet
C++ set.
Definition: CepsTypes.hpp:209
Eigen::Matrix< CepsScalar, 3, 3 > CepsMathTensor
Tensor, eigen format.
Definition: CepsTypes.hpp:137
std::vector< _Type, _Alloc > CepsVector
C++ vector.
Definition: CepsTypes.hpp:155
bool CepsBool
Booleans.
Definition: CepsTypes.hpp:124
CepsInt CepsAttribute
Used to define regions.
Definition: CepsTypes.hpp:215
std::make_unsigned_t< CepsInt > CepsUInt
Unsigned version on CepsInt.
Definition: CepsTypes.hpp:109
float CepsReal
Need single precision floating point.
Definition: CepsTypes.hpp:100
Eigen::Matrix< CepsScalar, 3, 1 > CepsMathVertex
Vertex, eigen format.
Definition: CepsTypes.hpp:135
std::shared_ptr< DistributedHaloVector > DHVecPtr
Typedef for pointer on Distributed Halo CepsVector.
CoeffInterpolatorSAFunc< _Result > * newCoeffInterpolatorSAFunc(const CepsMap< CepsReal, _Result > &map, ScalarSAFunc *coeff)
Direct way to build a coeffInterpolator.
CstPiecewiseSAFunc< _Result > * newCstPiecewiseSAFunc(const CepsMap< CepsAttribute, _Result > &map)
Direct way to build a CstPiecewiseSAFunc.
DistributedInfos< DegreeOfFreedom * > * getDistributedDofs() const
Get the stored Degree Of Freedom repartition.
Represents a ionic model for a group of cells, i.e. multiple systems of ODEs.
virtual void defineAnalyticSolution()
Set directly the analytic function, default sets no solution, unless there is a collection of referen...
AbstractDiscretization * m_discr
Discretization method (eg FE for now)
SourceTermManager * m_sourceTerms
All source terms.
Unknown * getUnknown(const CepsString &label) const
Get an unknown by its name.
InputParameters * m_parameters
Input file data.
Geometry * m_geom
Link to geometry on which the pb is defined.
void createSpatialDiscretization()
Compute the discretization structure.
Geometry * getGeometry() const
Link to geometry on which the pb is defined.
BoundaryConditionManager * m_boundaryConditions
All BCs should be there.
FunctionDictionary * m_functions
Collection of custom functions.
void add(const CepsString &params)
Add a boundary condition term from parameters.
A functor that aligns conductivities along the fibers directions.
CepsEnum getFlags() const override
Combination of flags of all 3 arrays.
FiberAligner(VectorSAFunc *fL, VectorSAFunc *fT, VectorSAFunc *fN, TensorSAFunc *sT=nullptr, VectorSAFunc *sV=nullptr)
Constructor with a functor for each direction. Input conductivity can be either vector (diagonal) or ...
CepsMathTensor eval(CepsStandardArgs args) override
Get the full tensor.
void defineBoundaryConditions() override
For cardiac problems, use the "boundary stimulation" key to create boundary conditions using the same...
void getInitialCondition(DHVecPtr v) const override
Zero + asks each ionic model to fill the parts of the Vm vector with its initial value.
ScalarField< DegreeOfFreedom > * m_Cm
Membrane capacitance, may depend on x and t.
CepsString m_fibersOptions
Options for fiber orientation.
CepsString m_bcStimOptions
Options for stimulation, on boundary.
~CardiacProblem() override
Destructor.
CepsString m_CmOptions
Options for membrance capacitance.
void initializeCm()
Sets the membrane conductivity from the input parameters.
CepsString m_AmOptions
Options for membrane surface.
CepsString m_volFracOptions
Options for volume fraction.
void initializeIonicModels()
Creates and assign ionic models to tissue regions from input string.
void initializeAm()
Set the surface of membrane from input parameters.
CepsString m_ionOptions
Options for ionic models.
TensorField< GeomCell > * getSigmaE() const
Link to extracellular conductivity.
CardiacProblem(Geometry *g, InputParameters *params=nullptr)
Constructor with input file and geometry.
virtual void initializeConductivities()
Generates the functors that compute conductivity either from inputs or volume fraction.
void setupWithParameters(InputParameters *params) override
Sets options from the parameters.
virtual void initializeStimulations()
Generates stimulations and links them to ionic models. Called within define source terms.
CepsString m_sigmaIOptions
Options for intracellular conductivity.
TensorField< GeomCell > * m_sigmaI
Intracellular conductivity, defined on cells.
void createFibersAndConductivities(CepsString fiberOptions, TensorField< GeomCell > *&sigmaI, TensorField< GeomCell > *&sigmaE, CepsString suffix="")
Creates the entries in the dictionary for each direction of fibers from file This is splitted from in...
CepsVector< AbstractIonicModel * > getIonicModels() const
Vector of all initd ionic models.
virtual CepsVector< Unknown * > getTMVUnknowns() const =0
Returns a vector containing all unknowns that are a TMV (especially useful for bilayer)
CepsString m_sigmaEOptions
Options for extracellulat conductivity.
CepsVector< AbstractIonicModel * > m_ionicModels
All ionic models defined on the tissue.
CepsSet< CepsAttribute > m_tissueAttributes
Identifier for the tissue region, default {-1}.
ScalarField< DegreeOfFreedom > * m_Am
Surface (cm2) of cell membrane per cm3 of myocardium.
ScalarField< GeomCell > * m_volFrac
Fraction of tissue made of valid myocytes.
const CepsSet< CepsAttribute > & getTissueAttributes() const
All attributes that localize tissue.
TensorField< GeomCell > * m_sigmaE
Extracellulat conductivity, defined on cells.
ScalarField< DegreeOfFreedom > * getCm() const
Link to Cm coefficient.
CepsString m_stimOptions
Options for stimulation.
CepsString m_volFracItpFileI
Options for volume fraction.
CepsString m_volFracItpFileE
Options for volume fraction.
void initializeEquation() override
Initializes all the elements of the PDE from options.
ScalarField< DegreeOfFreedom > * getAm() const
Link to Am coefficient.
TensorField< GeomCell > * getSigmaI() const
Link to intracellular conductivity.
void defineSourceTerms() override
For cardiac problem, only calls initializeStimulation. Can be overriden.
A Field is an object wrapped around a SAFunc functor, defined on at least one domain.
Definition: Field.hpp:80
void addDomain(const _Domain *domain)
Add another domain of definition.
void clearDomains()
Removes domains and support.
void addFromFile(const CepsString &label, const CepsString &params, Geometry *geom, CepsBool neverMind=false)
Add a function read from data file, requires geometry. If the extension is compatible with CoeffReade...
CepsBool hasTensor(const CepsString &label) const
Tells if function "label" is registered.
const TensorEntry getTensor(const CepsString &label) const
Get a single tensor entry, const version.
const VectorEntry getVector(const CepsString &label) const
Get a single vector entry, const version.
void add(const CepsString &label, const CepsString &params, Geometry *geom=nullptr)
Add an object from parameters.
void addFunction(const CepsString &label, const CepsString &params)
Add a function deduced from tags only, works only with scalar return type.
const ScalarEntry getScalar(const CepsString &label) const
Get a single scalar entry, const version.
void addEntry(const CepsString &label, ScalarEntry func)
Ads an entry to the map of scalar functions.
Encapsulates all the geometrical data.
Definition: Geometry.hpp:50
Mesh * getMeshOfDim(CepsUInt dim) const
Return the mesh of requested dimension.
Definition: Geometry.cpp:139
CepsBool hasMeshOfDim(CepsUInt dim) const
true if geometry has data of requested dimension
Definition: Geometry.cpp:167
Heat PDE, single unknown, constant diffusion coeff 1, homogeneous Neumann (no BC defined)
Definition: HeatProblem.hpp:36
void defineUnknowns() override
Lists the unknowns of the problem (one here)
Definition: HeatProblem.cpp:61
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.
const CepsVector< GeomCell * > & getCells()
CepsVector of cells stored on this process.
Definition: Mesh.cpp:204
A SAFunc is a ceps::Function that uses CepsStandardArgs as argument of call operator (),...
Definition: SAFunc.hpp:100
void add(const CepsString &params, CepsBool computeSupport=false)
Add a source term from parameters.
ScalarSourceTerm * getSourceTerm(CepsString label) const
Get a source term, nullptr if not found.
Source term, essentially a ScalarField.
Definition: SourceTerm.hpp:50
CepsUnknownIndex getUnknownId() const
Get the name of the unknown.
A class used to defined an unknown of a PDE problem The unknown can be defined on a specific region,...
Definition: Unknown.hpp:45
CepsString toString(_Tp value)
Convert a given value to a string (input has to be compatible with std::to_string)
Definition: CepsString.hpp:409
CepsSet< CepsInt > toInts(const CepsString &s)
Cast CepsString to a set of CepsInt.
Definition: CepsString.cpp:284
CepsBool isValidPtr(_Type *ptr)
Tells if pointer is not null.
Definition: CepsMemory.hpp:61
CepsInt readInt(std::istream &file, const CepsString &errorMessage="")
Reads an integral number from an istream, aborts if conversion fails advances the stream by 1 word.
Definition: CepsString.cpp:677
CepsBool isNullPtr(_Type *ptr)
Tells if passed pointer is null.
Definition: CepsMemory.hpp:45
CepsVector< CepsString > split(const CepsString &s, const CepsString &delimiters=CepsString(" \t"))
Splits a string using mulitple delimiters in a single string.
Definition: CepsString.cpp:38
CepsMathTensor readTensor(std::istream &file, const CepsString &errorMessage="")
Reads 9 floating point numbers from an istream, aborts if conversion fails advances the stream by 9 w...
Definition: CepsString.cpp:704
void destroyObject(_Type &)
Destroy[delete] any type.
Definition: CepsMemory.hpp:116
CepsBool fileExists(const CepsString &fileName, const CepsString &directory)
Definition: CepsString.cpp:595
CepsReal readReal(std::istream &file, const CepsString &errorMessage="")
Reads a floating point number from an istream, aborts if conversion fails advances the stream by 1 wo...
Definition: CepsString.cpp:661
Structure used to pass arguments to SAFunc (see pde directory) The flags of the SAFunc allows extract...
Definition: CepsTypes.hpp:239