LifeV
heart.cpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file
29  @brief Cardiac Electrophysiology Test
30  @author Lucia Mirabella <lucia.mirabella@mail.polimi.it> and Mauro Perego <mauro.perego@polimi.it>
31  @date 11-2007
32  @contributors Ricardo Ruiz-Baier <ricardo.ruiz@epfl.ch>, Simone Rossi <simone.rossi@epfl.ch>
33  @last update 11-2010
34  */
35 
36 
37 #include <Epetra_ConfigDefs.h>
38 #ifdef EPETRA_MPI
39 #include <mpi.h>
40 #include <Epetra_MpiComm.h>
41 #else
42 #include <Epetra_SerialComm.h>
43 #endif
44 
45 
46 #include "heart.hpp"
47 
48 using namespace LifeV;
49 
51 
52 //! Identifiers for heart boundaries
53 const Int EPICARDIUM = 40;
54 const Int ENDOCARDIUM = 60;
55 const Int TRUNC_SEC = 50;
56 
57 Real zero_scalar ( const Real& /* t */,
58  const Real& /* x */,
59  const Real& /* y */,
60  const Real& /* z */,
61  const ID& /* i */ )
62 {
63  return 0.;
64 }
65 
66 // ===================================================
67 //! Constructors
68 // ===================================================
69 
70 Heart::Heart ( Int argc,
71  char** argv )
72 {
73  GetPot command_line (argc, argv);
74  const std::string data_file_name = command_line.follow ("data", 2, "-f", "--file");
75  GetPot dataFile (data_file_name);
76 
77  //! Pointer to access functors
78  M_heart_fct.reset (new HeartFunctors ( dataFile) );
79  ion_model = dataFile ("electric/physics/ion_model", 1);
80  M_heart_fct->M_comm.reset (new Epetra_MpiComm ( MPI_COMM_WORLD ) );
81 
82  if (!M_heart_fct->M_comm->MyPID() )
83  {
84  std::cout << "My PID = " << M_heart_fct->M_comm->MyPID() << std::endl;
85  }
86 }
87 
88 
89 // ===================================================
90 //! Methods
91 // ===================================================
92 
93 void
95 {
96  typedef FESpace< mesh_Type, MapEpetra > feSpace_Type;
97  typedef std::shared_ptr<feSpace_Type> feSpacePtr_Type;
98 
99  LifeChrono chronoinitialsettings;
100  LifeChrono chronototaliterations;
101  chronoinitialsettings.start();
102  Real normu;
103  Real meanu;
104  Real minu;
105 
106  //! Construction of data classes
107 
108 #ifdef MONODOMAIN
109  HeartMonodomainData _data (M_heart_fct);
110 #else
111  HeartBidomainData _data (M_heart_fct);
112 #endif
113  HeartIonicData _dataIonic (M_heart_fct->M_dataFile);
114 
115  MeshData meshData;
116  meshData.setup (M_heart_fct->M_dataFile, "electric/space_discretization");
117  std::shared_ptr<mesh_Type > fullMeshPtr ( new mesh_Type ( M_heart_fct->M_comm ) );
118  readMesh (*fullMeshPtr, meshData);
119  bool verbose = (M_heart_fct->M_comm->MyPID() == 0);
120 
121  //! Boundary conditions handler and function
122  BCFunctionBase uZero ( zero_scalar );
123  BCHandler bcH;
124  bcH.addBC ( "Endo", ENDOCARDIUM, Natural, Full, uZero, 1 );
125  bcH.addBC ( "Epi", EPICARDIUM, Natural, Full, uZero, 1 );
126  bcH.addBC ( "Trunc", TRUNC_SEC, Natural, Full, uZero, 1 );
127 
128  const ReferenceFE* refFE_w;
129  const QuadratureRule* qR_w;
130  const QuadratureRule* bdQr_w;
131 
132  const ReferenceFE* refFE_u;
133  const QuadratureRule* qR_u;
134  const QuadratureRule* bdQr_u;
135 
136 
137  //! Construction of the partitioned mesh
138  std::shared_ptr<mesh_Type> localMeshPtr;
139  {
140  MeshPartitioner< mesh_Type > meshPart (fullMeshPtr, M_heart_fct->M_comm);
141  localMeshPtr = meshPart.meshPartition();
142  }
143  std::string uOrder = M_heart_fct->M_dataFile ( "electric/space_discretization/u_order", "P1");
144 
145  //! Initialization of the FE type and quadrature rules for both the variables
146  if ( uOrder.compare ("P1") == 0 )
147  {
148  if (verbose)
149  {
150  std::cout << "P1 potential " << std::flush;
151  }
152  refFE_u = &feTetraP1;
153  qR_u = &quadRuleTetra15pt;
154  bdQr_u = &quadRuleTria3pt;
155  }
156  else
157  {
158  cout << "\n " << uOrder << " finite element not implemented yet \n";
159  exit (1);
160  }
161 
162  std::string wOrder = M_heart_fct->M_dataFile ( "electric/space_discretization/w_order", "P1");
163  if ( wOrder.compare ("P1") == 0 )
164  {
165  if (verbose)
166  {
167  std::cout << "P1 recovery variable " << std::flush;
168  }
169  refFE_w = &feTetraP1;
170  qR_w = &quadRuleTetra4pt;
171  bdQr_w = &quadRuleTria3pt;
172  }
173  else
174  {
175  cout << "\n " << wOrder << " finite element not implemented yet \n";
176  exit (1);
177  }
178 
179  //! Construction of the FE spaces
180  if (verbose)
181  {
182  std::cout << "Building the potential FE space ... " << std::flush;
183  }
184 
185  feSpacePtr_Type uFESpacePtr ( new feSpace_Type ( localMeshPtr,
186  *refFE_u,
187  *qR_u,
188  *bdQr_u,
189  1,
190  M_heart_fct->M_comm) );
191 
192 #ifdef BIDOMAIN
193  feSpacePtr_Type _FESpacePtr ( new feSpace_Type (localMeshPtr,
194  *refFE_u,
195  *qR_u,
196  *bdQr_u,
197  2,
198  M_heart_fct->M_comm) );
199 #endif
200  if (verbose)
201  {
202  std::cout << "ok." << std::endl;
203  }
204  if (verbose)
205  {
206  std::cout << "Building the recovery variable FE space ... " << std::flush;
207  }
208  if (verbose)
209  {
210  std::cout << "ok." << std::endl;
211  }
212 
213  UInt totalUDof = uFESpacePtr->map().map (Unique)->NumGlobalElements();
214  if (verbose)
215  {
216  std::cout << "Total Potential DOF = " << totalUDof << std::endl;
217  }
218  if (verbose)
219  {
220  std::cout << "Calling the electric model constructor ... ";
221  }
222 
223 #ifdef MONODOMAIN
224  HeartMonodomainSolver< mesh_Type > electricModel (_data, *uFESpacePtr, bcH, M_heart_fct->M_comm);
225 #else
226  HeartBidomainSolver< mesh_Type > electricModel (_data, *_FESpacePtr, *uFESpacePtr, bcH, M_heart_fct->M_comm);
227 #endif
228 
229  if (verbose)
230  {
231  std::cout << "ok." << std::endl;
232  }
233  MapEpetra fullMap (electricModel.getMap() );
234  vector_Type rhs ( fullMap);
235  electricModel.setup ( M_heart_fct->M_dataFile );
236  std::cout << "setup ok" << std::endl;
237 
238  if (verbose)
239  {
240  std::cout << "Calling the ionic model constructor ... ";
241  }
242  std::shared_ptr< HeartIonicSolver< mesh_Type > > ionicModel;
243  if (ion_model == 1)
244  {
245  if (verbose)
246  {
247  std::cout << "Ion Model = Rogers-McCulloch" << std::endl << std::flush;
248  }
249  ionicModel.reset (new RogersMcCulloch< mesh_Type > (_dataIonic,
250  *localMeshPtr,
251  *uFESpacePtr,
252  *M_heart_fct->M_comm) );
253  }
254  else if (ion_model == 2)
255  {
256  if (verbose)
257  {
258  std::cout << "Ion Model = Luo-Rudy" << std::endl << std::flush;
259  }
260  ionicModel.reset (new LuoRudy< mesh_Type > (_dataIonic,
261  *localMeshPtr,
262  *uFESpacePtr,
263  *M_heart_fct->M_comm) );
264  }
265  else if (ion_model == 3)
266  {
267  if (verbose)
268  {
269  std::cout << "Ion Model = Mitchell-Schaeffer" << std::endl << std::flush;
270  }
271  ionicModel.reset (new MitchellSchaeffer< mesh_Type > (_dataIonic,
272  *localMeshPtr,
273  *uFESpacePtr,
274  *M_heart_fct->M_comm) );
275  }
276 
277 #ifdef MONODOMAIN
278  electricModel.initialize ( M_heart_fct->initialScalar() );
279 #else
280  electricModel.initialize ( M_heart_fct->initialScalar(),
281  M_heart_fct->zeroScalar() );
282 #endif
283 
284  if (verbose)
285  {
286  std::cout << "ok." << std::endl;
287  }
288 
289  ionicModel->initialize( );
290 
291  //! Building time-independent part of the system
292  electricModel.buildSystem( );
293  std::cout << "buildsystem ok" << std::endl;
294  //! Initialization
295  Real dt = _data.timeStep();
296  Real t0 = 0;
297  Real tFinal = _data.endTime();
298  MPI_Barrier (MPI_COMM_WORLD);
299 
300  if (verbose)
301  {
302  std::cout << "Setting the initial solution ... " << std::endl << std::endl;
303  }
304  _data.setTime (t0);
305  electricModel.resetPreconditioner();
306  if (verbose)
307  {
308  std::cout << " ok " << std::endl;
309  }
310 
311  //! Setting generic Exporter postprocessing
312  std::shared_ptr< Exporter<mesh_Type > > exporter;
313  std::string const exporterType = M_heart_fct->M_dataFile ( "exporter/type", "ensight");
314 #ifdef HAVE_HDF5
315  if (exporterType.compare ("hdf5") == 0)
316  {
317  exporter.reset ( new ExporterHDF5<mesh_Type > ( M_heart_fct->M_dataFile,
318  "heart" ) );
319  exporter->setPostDir ( "./" ); // This is a test to see if M_post_dir is working
320  exporter->setMeshProcId ( localMeshPtr, M_heart_fct->M_comm->MyPID() );
321  }
322  else
323 #endif
324  {
325  if (exporterType.compare ("none") == 0)
326  {
327  exporter.reset ( new ExporterEmpty<mesh_Type > ( M_heart_fct->M_dataFile,
328  localMeshPtr,
329  "heart",
330  M_heart_fct->M_comm->MyPID() ) );
331  }
332  else
333  {
334  exporter.reset ( new ExporterEnsight<mesh_Type > ( M_heart_fct->M_dataFile,
335  localMeshPtr,
336  "heart",
337  M_heart_fct->M_comm->MyPID() ) );
338  }
339  }
340 
341 
342  vectorPtr_Type Uptr ( new vector_Type (electricModel.solutionTransmembranePotential(), Repeated ) );
343 
344  exporter->addVariable ( ExporterData<mesh_Type>::ScalarField, "potential", uFESpacePtr,
345  Uptr, UInt (0) );
346 
347 #ifdef BIDOMAIN
348  vectorPtr_Type Ueptr ( new vector_Type (electricModel.solutionExtraPotential(), Repeated ) );
349  exporter->addVariable ( ExporterData<mesh_Type>::ScalarField, "potential_e", _FESpacePtr,
350  Ueptr, UInt (0) );
351 #endif
352 
353  vectorPtr_Type Fptr ( new vector_Type (electricModel.fiberVector(), Repeated ) );
354 
355  if (_data.hasFibers() )
356  exporter->addVariable ( ExporterData<mesh_Type>::VectorField,
357  "fibers",
358  uFESpacePtr,
359  Fptr,
360  UInt (0) );
361  exporter->postProcess ( 0 );
362 
363  MPI_Barrier (MPI_COMM_WORLD);
364  chronoinitialsettings.stop();
365 
366  //! Temporal loop
367  LifeChrono chrono;
368  Int iter = 1;
369  chronototaliterations.start();
370  for ( Real time = t0 + dt ; time <= tFinal + dt / 2.; time += dt, iter++)
371  {
372  _data.setTime (time);
373  if (verbose)
374  {
375  std::cout << std::endl;
376  std::cout << "We are now at time " << _data.time() << " s. " << std::endl;
377  std::cout << std::endl;
378  }
379  chrono.start();
380  MPI_Barrier (MPI_COMM_WORLD);
381  ionicModel->solveIonicModel ( electricModel.solutionTransmembranePotential(), _data.timeStep() );
382  rhs *= 0;
383  computeRhs ( rhs, electricModel, ionicModel, _data );
384  electricModel.updatePDESystem ( rhs );
385  electricModel.PDEiterate ( bcH );
386  normu = electricModel.solutionTransmembranePotential().norm2();
387  electricModel.solutionTransmembranePotential().epetraVector().MeanValue (&meanu);
388  electricModel.solutionTransmembranePotential().epetraVector().MaxValue (&minu);
389  if (verbose)
390  {
391  std::cout << "norm u " << normu << std::endl;
392  std::cout << "mean u " << meanu << std::endl;
393  std::cout << "max u " << minu << std::endl << std::flush;
394  }
395 
396  *Uptr = electricModel.solutionTransmembranePotential();
397 #ifdef BIDOMAIN
398  *Ueptr = electricModel.solutionExtraPotential();
399 #endif
400 
401  exporter->postProcess ( time );
402  MPI_Barrier (MPI_COMM_WORLD);
403  chrono.stop();
404  if (verbose)
405  {
406  std::cout << "Total iteration time " << chrono.diff() << " s." << std::endl;
407  }
408  chronototaliterations.stop();
409  }
410 
411  if (verbose)
412  {
413  std::cout << "Total iterations time " << chronototaliterations.diff() << " s." << std::endl;
414  }
415  if (verbose)
416  {
417  std::cout << "Total initial settings time " << chronoinitialsettings.diff() << " s." << std::endl;
418  }
419  if (verbose)
420  {
421  std::cout << "Total execution time " << chronoinitialsettings.diff() + chronototaliterations.diff() << " s." << std::endl;
422  }
423 }
424 
425 #ifdef MONODOMAIN
427  HeartMonodomainSolver< mesh_Type >& electricModel,
428  std::shared_ptr< HeartIonicSolver< mesh_Type > > ionicModel,
429  HeartMonodomainData& data )
430 {
431  bool verbose = (M_heart_fct->M_comm->MyPID() == 0);
432  if (verbose)
433  {
434  std::cout << " f- Computing Rhs ... " << "\n" << std::flush;
435  }
436  LifeChrono chrono;
437  chrono.start();
438 
439  //! u, w with repeated map
440  vector_Type uVecRep (electricModel.solutionTransmembranePotential(), Repeated);
441  ionicModel->updateRepeated();
442  VectorElemental elvec_Iapp ( electricModel.potentialFESpace().fe().nbFEDof(), 2 ),
443  elvec_u ( electricModel.potentialFESpace().fe().nbFEDof(), 1 ),
444  elvec_Iion ( electricModel.potentialFESpace().fe().nbFEDof(), 1 );
445 
446  for (UInt iVol = 0; iVol < electricModel.potentialFESpace().mesh()->numVolumes(); ++iVol)
447  {
448  electricModel.potentialFESpace().fe().updateJacQuadPt ( electricModel.potentialFESpace().mesh()->volumeList ( iVol ) );
449  elvec_Iapp.zero();
450  elvec_u.zero();
451  elvec_Iion.zero();
452 
453  UInt eleIDu = electricModel.potentialFESpace().fe().currentLocalId();
454  UInt nbNode = ( UInt ) electricModel.potentialFESpace().fe().nbFEDof();
455 
456  //! Filling local elvec_u with potential values in the nodes
457  for ( UInt iNode = 0 ; iNode < nbNode ; iNode++ )
458  {
459  Int ig = electricModel.potentialFESpace().dof().localToGlobalMap ( eleIDu, iNode );
460  elvec_u.vec() [ iNode ] = uVecRep[ig];
461  }
462 
463  ionicModel->updateElementSolution (eleIDu);
464  ionicModel->computeIonicCurrent (data.membraneCapacitance(), elvec_Iion, elvec_u, electricModel.potentialFESpace() );
465 
466  //! Computing the current source of the righthand side, repeated
467  AssemblyElemental::source (M_heart_fct->stimulus(),
468  elvec_Iapp,
469  electricModel.potentialFESpace().fe(),
470  data.time(),
471  0);
472  AssemblyElemental::source (M_heart_fct->stimulus(),
473  elvec_Iapp,
474  electricModel.potentialFESpace().fe(),
475  data.time(),
476  1);
477 
478  //! Assembling the righthand side
479  for ( UInt i = 0 ; i < electricModel.potentialFESpace().fe().nbFEDof() ; i++ )
480  {
481  Int ig = electricModel.potentialFESpace().dof().localToGlobalMap ( eleIDu, i );
482  rhs.sumIntoGlobalValues (ig, (data.conductivityRatio() * elvec_Iapp.vec() [i] +
483  elvec_Iapp.vec() [i + nbNode]) /
484  (1 + data.conductivityRatio() ) + data.volumeSurfaceRatio() * elvec_Iion.vec() [i] );
485  }
486  }
487  rhs.globalAssemble();
488  Real coeff = data.volumeSurfaceRatio() * data.membraneCapacitance() / data.timeStep();
489  vector_Type tmpvec (electricModel.solutionTransmembranePotential() );
490  tmpvec *= coeff;
491  rhs += electricModel.massMatrix() * tmpvec;
492  MPI_Barrier (MPI_COMM_WORLD);
493  chrono.stop();
494  if (verbose)
495  {
496  std::cout << "done in " << chrono.diff() << " s." << std::endl;
497  }
498 }
499 #else
500 void Heart::computeRhs ( vector_Type& rhs,
501  HeartBidomainSolver< mesh_Type >& electricModel,
502  std::shared_ptr< HeartIonicSolver< mesh_Type > > ionicModel,
503  HeartBidomainData& data )
504 {
505  bool verbose = (M_heart_fct->M_comm->MyPID() == 0);
506  if (verbose)
507  {
508  std::cout << " f- Computing Rhs ... " << "\n" << std::flush;
509  }
510  LifeChrono chrono;
511  chrono.start();
512 
513  //! u, w with repeated map
514  vector_Type uVecRep (electricModel.solutionTransmembranePotential(), Repeated);
515  ionicModel->updateRepeated();
516 
517  VectorElemental elvec_Iapp ( electricModel.potentialFESpace().fe().nbFEDof(), 2 ),
518  elvec_u ( electricModel.potentialFESpace().fe().nbFEDof(), 1 ),
519  elvec_Iion ( electricModel.potentialFESpace().fe().nbFEDof(), 1 );
520  for (UInt iVol = 0; iVol < electricModel.potentialFESpace().mesh()->numVolumes(); ++iVol)
521  {
522  electricModel.potentialFESpace().fe().updateJacQuadPt ( electricModel.potentialFESpace().mesh()->volumeList ( iVol ) );
523  elvec_u.zero();
524  elvec_Iion.zero();
525  elvec_Iapp.zero();
526 
527  UInt eleIDu = electricModel.potentialFESpace().fe().currentLocalId();
528  UInt nbNode = ( UInt ) electricModel.potentialFESpace().fe().nbFEDof();
529  for ( UInt iNode = 0 ; iNode < nbNode ; iNode++ )
530  {
531  Int ig = electricModel.potentialFESpace().dof().localToGlobalMap ( eleIDu, iNode );
532  elvec_u.vec() [ iNode ] = uVecRep[ig];
533  }
534 
535  UInt eleID = electricModel.potentialFESpace().fe().currentLocalId();
536  ionicModel->updateElementSolution (eleID);
537  ionicModel->computeIonicCurrent (data.membraneCapacitance(), elvec_Iion, elvec_u, electricModel.potentialFESpace() );
538 
539  //! Computing Iapp
540  AssemblyElemental::source (M_heart_fct->stimulus(),
541  elvec_Iapp,
542  electricModel.potentialFESpace().fe(),
543  data.time(), 0);
544  AssemblyElemental::source (M_heart_fct->stimulus(),
545  elvec_Iapp,
546  electricModel.potentialFESpace().fe(),
547  data.time(),
548  1);
549  UInt totalUDof = electricModel.potentialFESpace().map().map (Unique)->NumGlobalElements();
550 
551  for ( UInt iNode = 0 ; iNode < nbNode ; iNode++ )
552  {
553  Int ig = electricModel.potentialFESpace().dof().localToGlobalMap ( eleIDu, iNode );
554  rhs.sumIntoGlobalValues (ig, elvec_Iapp.vec() [iNode] +
555  data.volumeSurfaceRatio() * elvec_Iion.vec() [iNode] );
556  rhs.sumIntoGlobalValues (ig + totalUDof,
557  -elvec_Iapp.vec() [iNode + nbNode] -
558  data.volumeSurfaceRatio() * elvec_Iion.vec() [iNode] );
559  }
560  }
561  rhs.globalAssemble();
562 
563  rhs += electricModel.matrMass() * data.volumeSurfaceRatio() *
564  data.membraneCapacitance() * electricModel.BDFIntraExtraPotential().time_der (data.timeStep() );
565 
566  MPI_Barrier (MPI_COMM_WORLD);
567 
568  chrono.stop();
569  if (verbose)
570  {
571  std::cout << "done in " << chrono.diff() << " s." << std::endl;
572  }
573 }
574 #endif
FESpace - Short description here please!
Definition: FESpace.hpp:78
const QuadratureRule quadRuleTetra15pt(pt_tetra_15pt, 5, "Quadrature rule 15 points on a tetraedra", TETRA, 15, 5)
GetPot(const int argc_, char **argv_, const char *FieldSeparator=0x0)
Definition: GetPot.hpp:507
const QuadratureRule quadRuleTetra4pt(pt_tetra_4pt, 2, "Quadrature rule 4 points on a tetraedra", TETRA, 4, 2)
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
const Int ENDOCARDIUM
Definition: heart.cpp:54
void computeRhs(vector_Type &rhs, HeartMonodomainSolver< RegionMesh< LinearTetra > > &electricModel, std::shared_ptr< HeartIonicSolver< RegionMesh< LinearTetra > > > ionicModel, HeartMonodomainData &dataMonodomain)
To compute the righthand side of the system.
Definition: heart.cpp:426
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
uint32_type ID
IDs.
Definition: LifeV.hpp:194
Heart(Int argc, char **argv)
Constructors.
Definition: heart.cpp:70
#define MONODOMAIN
Definition: heart.hpp:39
const Int TRUNC_SEC
Definition: heart.cpp:55
std::shared_ptr< std::vector< Int > > M_isOnProc
MeshData - class for handling spatial discretization.
Definition: MeshData.hpp:72
RegionMesh< LinearTetra > mesh_Type
Definition: heart.cpp:50
UInt ion_model
Definition: heart.hpp:119
double Real
Generic real data.
Definition: LifeV.hpp:175
const QuadratureRule quadRuleTria3pt(pt_tria_3pt, 2, "Quadrature rule 3 points on a triangle", TRIANGLE, 3, 2)
The class for a reference Lagrangian finite element.
void run()
To build the system and iterate.
Definition: heart.cpp:94
std::shared_ptr< vector_Type > vectorPtr_Type
Definition: heart.hpp:81
int operator()(const char *VarName, int Default) const
Definition: GetPot.hpp:2021
HeartMonodomainSolver< RegionMesh< LinearTetra > >::vector_Type vector_Type
Definition: heart.hpp:75
QuadratureRule - The basis class for storing and accessing quadrature rules.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
const Int EPICARDIUM
Identifiers for heart boundaries.
Definition: heart.cpp:53