LifeV
ElectroETAMonodomainSolver.hpp
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  @file
28  @brief Class for solving the Monodomain model in electrophysiology.
29 
30  @date 02 - 2013
31  @author Simone Rossi <simone.rossi@epfl.ch>
32 
33  @last update 04 - 2014
34 
35  This class provides interfaces to solve the monodomain equation
36  ( reaction diffusion equation ) using the ETA framework.
37  The solution can be performed using three different methods:
38  -operator splitting method (at this point available only with forward Euler
39  for the reaction step and backward Euler for the diffusion step.
40  Second order splitting is available but still experimental. );
41  -Ionic Currents Interpolation (at this point only forward Euler);
42  -State Variable interpolation (at this point only forward Euler).
43  */
44 
45 #ifndef _ELECTROETAMONODOMAINSOLVER_H_
46 #define _ELECTROETAMONODOMAINSOLVER_H_
47 
48 
49 #include <lifev/core/filter/ExporterEnsight.hpp>
50 #ifdef HAVE_HDF5
51 #include <lifev/core/filter/ExporterHDF5.hpp>
52 #endif
53 #include <lifev/core/filter/ExporterEmpty.hpp>
54 
55 #include <Epetra_LocalMap.h>
56 
57 #include <lifev/core/array/MatrixSmall.hpp>
58 
59 #include <lifev/core/array/MapEpetra.hpp>
60 #include <lifev/core/array/MatrixEpetra.hpp>
61 #include <lifev/core/array/VectorEpetra.hpp>
62 #include <lifev/core/fem/SobolevNorms.hpp>
63 #include <lifev/core/fem/GeometricMap.hpp>
64 #include <lifev/electrophysiology/solver/IonicModels/ElectroIonicModel.hpp>
65 #include <lifev/electrophysiology/stimulus/ElectroStimulus.hpp>
66 
67 #include <lifev/core/util/LifeChrono.hpp>
68 #include <lifev/core/fem/FESpace.hpp>
69 #include <lifev/electrophysiology/util/HeartUtility.hpp>
70 
71 #include <lifev/eta/fem/ETFESpace.hpp>
72 #include <lifev/eta/expression/Integrate.hpp>
73 #include <lifev/core/mesh/MeshLoadingUtility.hpp>
74 
75 #include <lifev/core/algorithm/LinearSolver.hpp>
76 #include <lifev/core/algorithm/Preconditioner.hpp>
77 #include <lifev/core/algorithm/PreconditionerML.hpp>
78 #include <lifev/core/algorithm/PreconditionerIfpack.hpp>
79 
80 
81 namespace LifeV
82 {
83 
84 //! monodomainSolver - Class featuring the solver for monodomain equations
85 
86 template<typename Mesh, typename IonicModel>
88 {
89 
90  //!Monodomain Solver
91  /*!
92  The monodomain equation reads
93  \f \Chi
94 
95  */
96 
97 public:
98 
99  //! @name Type definitions
100  //@{
101 
102  //! Mesh
103  typedef Mesh mesh_Type;
104 
106 
107  //! Distributed vector // For parallel usage
109 
111 
113 
115 
117 
118  //! Distributed Matrix // For parallel usage
120 
122 
123  //! Communicator to exchange informations among processes
125 
127 
128  //! Expression template scalar finite element space
129  //! To be used in the expression assembly namespace
131 
133 
134  //! Expression template vectorial finite element space
135  //! To be used in the expression assembly namespace
137 
139 
140  //! Finite element space
142 
144 
145  //! Linear Solver
146  typedef LinearSolver linearSolver_Type;
147 
149 
150  //! Exporter to save the solution
151  typedef Exporter<mesh_Type> IOFile_Type;
152 
154 
155  //! Exporter data
156  typedef ExporterData<mesh_Type> IOData_Type;
157 
159 
160 #ifdef HAVE_HDF5
162 #endif
163 
164  //! Preconditioner
165  typedef LifeV::Preconditioner basePrec_Type;
166 
168 
169  //! MultiLevel Preconditioner
170  typedef LifeV::PreconditionerML prec_Type;
171 
173 
174  //! Ionic model
175  typedef IonicModel ionicModel_Type;
176 
177  //! Base class of the ionic model
179 
181 
182  //! xml list to read parameters
184 
185  //! boost function
186  typedef std::function < Real (const Real& t,
187  const Real& x,
188  const Real& y,
189  const Real& z,
190  const ID& i) > function_Type;
191 
192  //! 3x3 matrix
193  typedef MatrixSmall<3, 3> matrixSmall_Type;
194 
195  //@}
196 
197  //! @name Constructors & Destructor
198  //@{
199 
200  //!Empty Constructor
201  /*!
202  */
204 
205  //! Constructor
206  /*!
207  * @param GetPot datafile (for preconditioner)
208  * @param std::shared_ptr<IonicModel> chosen ionic model pointer
209  * @param std::shared_ptr<Mesh> Pointer to the partitioned mesh
210  */
212  meshPtr_Type meshPtr);
213 
214  //! Constructor
215  /*!
216  * @param meshName file name of the mesh
217  * @param meshPath path to the mesh
218  * @param datafile GetPot file to setup the preconditioner
219  * @param model shared pointer to the chosen ionic model
220  */
221  ElectroETAMonodomainSolver (std::string meshName, std::string meshPath,
222  GetPot& dataFile, ionicModelPtr_Type model);
223 
224  //! Constructor
225  /*!
226  * @param string file name of the mesh
227  * @param string path to the mesh
228  * @param GetPot datafile (for preconditioner)
229  * @param std::shared_ptr<IonicModel> chosen ionic model pointer
230  * @param std::shared_ptr<Epetra_Comm> Epetra communicator
231  */
232  ElectroETAMonodomainSolver (std::string meshName, std::string meshPath,
233  GetPot& dataFile, ionicModelPtr_Type model, commPtr_Type comm);
234 
235  //! Copy Constructor
236  /*!
237  * @param ElectroETAmonodomainSolver object
238  */
240 
241  //!Operator=()
242  /*!
243  * @param ElectroETAmonodomainSolver object
244  */
245  ElectroETAMonodomainSolver<Mesh, IonicModel>& operator= (
246  const ElectroETAMonodomainSolver& solver);
247 
248  //! Destructor
250  {
251  }
252 
253  //@}
254 
255  //! @name Get Methods
256  //@{
257 
258  //! get the surface to volume ratio
259  /*!
260  * Not used in the code ( implicit definition inside the diffusion tensor)
261  */
262  inline const Real& surfaceVolumeRatio() const
263  {
264  return M_surfaceVolumeRatio;
265  }
266 
267  //! get the initial time (by default 0)
268  inline const Real& initialTime() const
269  {
270  return M_initialTime;
271  }
272 
273  //! get the final time
274  inline const Real& timeStep() const
275  {
276  return M_timeStep;
277  }
278 
279  //! get the time step
280  inline const Real& endTime() const
281  {
282  return M_endTime;
283  }
284 
285  //! get the diagonal diffusion tensor
286  inline const VectorSmall<3>& diffusionTensor() const
287  {
288  return M_diffusionTensor;
289  }
290 
291  //! get the order of the elements
292  inline const std::string elementsOrder() const
293  {
294  return M_elementsOrder;
295  }
296 
297  //! get the pointer to the ionic model
298  inline const ionicModelPtr_Type ionicModelPtr() const
299  {
300  return M_ionicModelPtr;
301  }
302 
303  //! get the pointer to the Epetra communicator
304  inline const commPtr_Type commPtr() const
305  {
306  return M_commPtr;
307  }
308 
309  //! get the pointer to the partitioned mesh
310  inline const meshPtr_Type localMeshPtr() const
311  {
312  return M_localMeshPtr;
313  }
314 
315  //! get the pointer to the partitioned mesh
317  {
318  return M_localMeshPtr;
319  }
320 
321  //! get the pointer to the partitioned mesh
322  inline const meshPtr_Type fullMeshPtr() const
323  {
324  return M_fullMeshPtr;
325  }
326 
327  //! get the pointer to the ETA finite element space
328  inline const ETFESpacePtr_Type ETFESpacePtr() const
329  {
330  return M_ETFESpacePtr;
331  }
332 
333  //! get the pointer to the usual finite element space
334  inline const feSpacePtr_Type feSpacePtr() const
335  {
336  return M_feSpacePtr;
337  }
338 
339  //! get the pointer to the mass matrix
340  inline const matrixPtr_Type massMatrixPtr() const
341  {
342  return M_massMatrixPtr;
343  }
344 
345  //! get the pointer to the mass matrix
346  inline const matrixPtr_Type fullMassMatrixPtr() const
347  {
348  return M_fullMassMatrixPtr;
349  }
350 
351  //! get the pointer to the stiffness matrix
352  inline const matrixPtr_Type stiffnessMatrixPtr() const
353  {
354  return M_stiffnessMatrixPtr;
355  }
356 
357  //! get the pointer to the global matrix
358  /*!
359  * \f[
360  * A = \frac{M}{\Delta t} + K(\mathbf{f})
361  * \f]
362  */
363  inline const matrixPtr_Type globalMatrixPtr() const
364  {
365  return M_globalMatrixPtr;
366  }
367 
368  //! get the pointer to the right hand side
369  inline const vectorPtr_Type rhsPtr() const
370  {
371  return M_rhsPtr;
372  }
373 
374  //! get the pointer to the unique version of the right hand side
375  inline const vectorPtr_Type rhsPtrUnique() const
376  {
377  return M_rhsPtrUnique;
378  }
379 
380  //! get the pointer to the transmembrane potential
381  inline const vectorPtr_Type potentialPtr() const
382  {
383  return M_potentialPtr;
384  }
385 
386  //! get the pointer to the fiber vector
387  inline const vectorPtr_Type fiberPtr() const
388  {
389  return M_fiberPtr;
390  }
391 
392  //! get the pointer to the fiber vector
394  {
395  return M_fiberPtr;
396  }
397 
398  //! get the pointer to the applied current vector
400  {
401  return M_ionicModelPtr->appliedCurrentPtr();
402  }
403 
404  //! get the pointer to the linear solver
406  {
407  return M_linearSolverPtr;
408  }
409 
410  //! get the pointer to the vector of pointers containing the transmembrane potential (at 0) and the gating variables
411  inline const vectorOfPtr_Type& globalSolution() const
412  {
413  return M_globalSolution;
414  }
415 
416  //! get the pointer to the vector of pointers containing the rhs for transmembrane potential (at 0) and the gating variables
417  inline const vectorOfPtr_Type& globalRhs() const
418  {
419  return M_globalRhs;
420  }
421 
422  //! getter for the boolean to know if we want a lumped matrix
423  inline bool lumpedMassMatrix() const
424  {
425  return M_lumpedMassMatrix;
426  }
427  //@}
428 
429  //! @name Set Methods
430  //@{
431 
432  //! set the surface to volume ratio
433  /*!
434  @param surfaceVolumeRatio surface to volume ratio
435  */
436  inline void setSurfaceVolumeRatio (const Real& surfaceVolumeRatio)
437  {
438  this->M_surfaceVolumeRatio = surfaceVolumeRatio;
439  }
440 
441  //! set the starting time
442  /*!
443  @param initialTime initial time
444  */
445  inline void setInitialTime (const Real& initialTime)
446  {
447  this->M_initialTime = initialTime;
448  }
449 
450  //! set the ending time
451  /*!
452  @param timeStep ending time
453  */
454  inline void setTimeStep (const Real& timeStep)
455  {
456  this->M_timeStep = timeStep;
457  }
458 
459  //! set the time step
460  /*!
461  @param endTime time step
462  */
463  inline void setEndTime (const Real& endTime)
464  {
465  this->M_endTime = endTime;
466  }
467 
468  //! set the diagonal diffusion tensor
469  /*!
470  @param diffusionTensor diagonal diffusion tensor
471  */
472  inline void setDiffusionTensor (const VectorSmall<3>& diffusionTensor)
473  {
474  this->M_diffusionTensor = diffusionTensor;
475  }
476 
477  //! set the pointer to the ionic model
478  /*!
479  @param ionicModelPtr pointer to the ionic model
480  */
481  inline void setIonicModelPtr (const ionicModelPtr_Type ionicModelPtr)
482  {
483  this->M_ionicModelPtr = ionicModelPtr;
484  }
485 
486  //! set ionic model
487  /*!
488  @param ionicModel ionic model
489  */
490  inline void setIonicModel (const ionicModel_Type& ionicModel)
491  {
492  (* (M_ionicModelPtr) ) = ionicModel;
493  }
494 
495 
496  //! set the pointer to the Epetra communicator
497  /*!
498  @param commPtr pointer to the Epetra communicator
499  */
500  inline void setCommPtr (const commPtr_Type commPtr)
501  {
502  this->M_commPtr = commPtr;
503  }
504 
505  //! set the Epetra communicator
506  /*!
507  @param comm Epetra communicator
508  */inlinevoidsetComm(constcomm_Type&comm)
509  {
510  (* (M_commPtr) ) = comm;
511  }
512 
513  //! set the pointer to the partitioned mesh
514  /*!
515  @param localMeshPtr pointer to the partitioned mesh
516  */
517  inline void setLocalMeshPtr (const meshPtr_Type localMeshPtr)
518  {
519  this->M_localMeshPtr = localMeshPtr;
520  }
521 
522  //! set the partitioned mesh
523  /*!
524  @param localMesh partitioned mesh
525  */
526  inline void setLocalMesh (const mesh_Type& localMesh)
527  {
528  (* (M_localMeshPtr) ) = localMesh;
529  }
530 
531 
532  //! set the pointer to the non partitioned mesh
533  /*!
534  @param fullMeshPtr pointer to the partitioned mesh
535  */
536  inline void setFullMeshPtr (const meshPtr_Type fullMeshPtr)
537  {
538  this->M_fullMeshPtr = fullMeshPtr;
539  }
540  //! set the non partitioned mesh
541  /*!
542  @param fullMesh pointer to the partitioned mesh
543  */
544  inline void setFullMesh (const mesh_Type& fullMesh)
545  {
546  (* (M_fullMeshPtr) ) = fullMesh;
547  }
548 
549 
550  //! set the pointer to the ETA fe space
551  /*!
552  @param ETFESpacePtr pointer to the ETA fe space
553  */
554  inline void setETFESpacePtr (const ETFESpacePtr_Type ETFESpacePtr)
555  {
556  this->M_ETFESpacePtr = ETFESpacePtr;
557  }
558 
559  //! set the scalar ETA fe space
560  /*!
561  @param ETFESpace scalar ETA fe space
562  */
563  inline void setETFESpace (const ETFESpace_Type& ETFESpace)
564  {
565  (* (M_ETFESpacePtr) ) = ETFESpace;
566  }
567 
568  //! set the pointer to the usual fe space
569  /*!
570  @param feSpacePtr pointer to the usual fe space
571  */
572  inline void setFeSpacePtr (const feSpacePtr_Type feSpacePtr)
573  {
574  this->M_feSpacePtr = feSpacePtr;
575  }
576 
577  //! set the fe space
578  /*!
579  @param feSpace the fe space
580  */
581  inline void setFeSpace (const feSpace_Type& feSpace)
582  {
583  (* (M_feSpacePtr) ) = feSpace;
584  }
585 
586 
587  //! set the pointer to the mass matrix
588  /*!
589  @param massMatrixPtr pointer to the mass matrix
590  */
591  inline void setMassMatrixPtr (const matrixPtr_Type massMatrixPtr)
592  {
593  this->M_massMatrixPtr = massMatrixPtr;
594  }
595 
596  //! set the mass matrix
597  /*!
598  @param massMatrix the mass matrix
599  */
600  inline void setMassMatrix (const matrix_Type& massMatrix)
601  {
602  (* (M_massMatrixPtr) ) = massMatrix;
603  }
604 
605  //! set the pointer to the full mass matrix
606  /*!
607  @param massMatrixPtr pointer to the mass matrix
608  */
609  inline void setFullMassMatrixPtr (const matrixPtr_Type fullMassMatrixPtr)
610  {
611  this->M_fullMassMatrixPtr = fullMassMatrixPtr;
612  }
613 
614  //! set the full mass matrix
615  /*!
616  @param massMatrix the mass matrix
617  */
618  inline void setFullMassMatrix (const matrix_Type& fullMassMatrix)
619  {
620  (* (M_fullMassMatrixPtr) ) = fullMassMatrix;
621  }
622 
623  //! set the pointer to the stiffness matrix
624  /*!
625  @param stiffnessMatrixPtr pointer to the stiffness matrix
626  */
627  inline void setStiffnessMatrixPtr (const matrixPtr_Type stiffnessMatrixPtr)
628  {
629  this->M_stiffnessMatrixPtr = stiffnessMatrixPtr;
630  }
631 
632  //! set the stiffness matrix
633  /*!
634  @param stiffnessMatrix the stiffness matrix
635  */
636  inline void setStiffnessMatrix (const matrix_Type& stiffnessMatrix)
637  {
638  (* (M_stiffnessMatrixPtr) ) = stiffnessMatrix;
639  }
640 
641 
642  //! set the pointer to the global matrix
643  /*!
644  @param globalMatrix pointer to the global matrix
645  */
646  inline void setGlobalMatrixPtr (const matrixPtr_Type globalMatrixPtr)
647  {
648  this->M_globalMatrixPtr = globalMatrixPtr;
649  }
650 
651  //! set the global matrix
652  /*!
653  @param globalMatrix the global matrix
654  */
655  inline void setGlobalMatrix (const matrix_Type& globalMatrix)
656  {
657  (* (M_globalMatrixPtr) ) = globalMatrix;
658  }
659 
660 
661  //! set the pointer to the right hand side
662  /*!
663  @param rhsPtr pointer to the right hand side
664  */
665  inline void setRhsPtr (const vectorPtr_Type rhsPtr)
666  {
667  this->M_rhsPtr = rhsPtr;
668  }
669 
670  //! set the right hand side
671  /*!
672  @param rhs the right hand side
673  */
674  inline void setRhs (const vector_Type& rhs)
675  {
676  (* (M_rhsPtr) ) = rhs;
677  }
678 
679 
680  //! set the pointer to the unique version of the right hand side
681  /*!
682  @param rhsPtrUnique pointer to the unique version of the right hand side
683  */
684  inline void setRhsPtrUnique (const vectorPtr_Type rhsPtrUnique)
685  {
686  this->M_rhsPtrUnique = rhsPtrUnique;
687  this->M_globalRhs.at (0) = M_rhsPtrUnique;
688  }
689 
690  //! set the unique version of the right hand side
691  /*!
692  @param rhsPtrUnique the unique version of the right hand side
693  */
694  inline void setRhsUnique (const vector_Type& rhsPtrUnique)
695  {
696  (* (M_rhsPtrUnique) ) = rhsPtrUnique;
697  }
698 
699  //! set the pointer to the potential
700  /*!
701  @param potentialPtr pointer to the potential
702  */
703  inline void setPotentialPtr (const vectorPtr_Type potentialPtr)
704  {
705  this->M_potentialPtr = potentialPtr;
706  this->M_globalSolution.at (0) = M_potentialPtr;
707  }
708 
709  //! set the potential
710  /*!
711  @param potential the potential
712  */
713  inline void setPotential (const vector_Type& potential)
714  {
715  (* (M_potentialPtr) ) = potential;
716  }
717 
718  //! set the pointer to the applied current vector
719  /*!
720  @param appliedCurrentPtr pointer to the applied current vector
721  */
722  inline void setAppliedCurrentPtr (const vectorPtr_Type appliedCurrentPtr)
723  {
724  M_ionicModelPtr->setAppliedCurrentPtr (appliedCurrentPtr);
725  }
726 
727  //! set the applied current vector
728  /*!
729  @param appliedCurrent the applied current vector
730  */
731  inline void setAppliedCurrent (const vector_Type& appliedCurrent)
732  {
733  M_ionicModelPtr->setAppliedCurrent (appliedCurrent);
734  }
735 
736  //! set the pointer to the linear solver
737  /*!
738  @param linearSolverPtr pointer to the linear solver
739  */
740  inline void setLinearSolverPtr (const linearSolverPtr_Type linearSolverPtr)
741  {
742  this->M_linearSolverPtr = linearSolverPtr;
743  }
744 
745  //! set the linear solver
746  /*!
747  @param linearSolver the linear solver
748  */
749  inline void setLinearSolver (const linearSolver_Type& linearSolver)
750  {
751  (* (M_linearSolverPtr) ) = linearSolver;
752  }
753 
754  //! set the vector of pointers containing the transmembrane potential (at 0) and the gating variables
755  /*!
756  @param globalSolution vector of pointers containing the transmembrane potential (at 0) and the gating variables
757  */
758  inline void setGlobalSolutionPtrs (const vectorOfPtr_Type& globalSolution)
759  {
760  this->M_globalSolution = globalSolution;
761  }
762 
763  //! set the vectors of unknowns: containing the transmembrane potential (at 0) and the gating variables
764  /*!
765  @param p vector of pointers containing the transmembrane potential (at 0) and the gating variables
766  */
767  inline void setGlobalSolution (const vectorOfPtr_Type& globalSolution)
768  {
769  for (int j = 0; j < M_ionicModelPtr->Size(); j++)
770  {
771  (* (M_globalSolution.at (j) ) ) = (* (globalSolution.at (j) ) );
772  }
773  }
774 
775  //! set the pointer to the \[j\]-th gating variable
776  /*!
777  @param gatingVariable pointer to the gating variable
778  @param j index of the gating variable
779  */
780  inline void setVariablePtr (const vectorPtr_Type gatingVariable, int j)
781  {
782  M_globalSolution.at (j) = gatingVariable;
783  }
784 
785  //! set the \[j\]-th gating variable
786  /*!
787  @param gatingVariable the gating variable
788  @param j index of the gating variable
789  */
790  inline void setVariablePtr (const vector_Type& gatingVariable, int j)
791  {
792  * (M_globalSolution.at (j) ) = gatingVariable;
793  }
794 
795  //! set the vector of pointers containing the rhs for the transmembrane potential (at 0) and the gating variables
796  /*!
797  @param globalRhs vector of pointers containing the rhs for the transmembrane potential (at 0) and the gating variables
798  */
799  inline void setGlobalRhsPtrs (const vectorOfPtr_Type& globalRhs)
800  {
801  this->M_globalRhs = globalRhs;
802  }
803 
804  //! set the vectors containing the rhs for the transmembrane potential (at 0) and the gating variables
805  /*!
806  @param globalRhs vector of pointers containing the rhs for the transmembrane potential (at 0) and the gating variables
807  */
808  inline void setGlobalRhs (const vectorOfPtr_Type& globalRhs)
809  {
810  for (int j = 0; j < M_ionicModelPtr->Size(); j++)
811  {
812  (* (M_globalRhs.at (j) ) ) = (* (globalRhs.at (j) ) );
813  }
814  }
815 
816  //! set the pointer to the fiber direction vector
817  /*!
818  @param fiberPtr pointer to the fiber direction vector
819  */
820  inline void setFiberPtr (const vectorPtr_Type fiberPtr)
821  {
822  this->M_fiberPtr = fiberPtr;
823  }
824 
825  //! set the fiber direction vector
826  /*!
827  @param fiber the fiber direction vector
828  */
829  inline void setFiber (const vector_Type& fiber)
830  {
831  (* (M_fiberPtr) ) = fiber;
832  }
833 
834  //! set the the choice of lumping
835  /*!
836  @param isLumped true if you want to lump the mass matrix
837  */
838  inline void setLumpedMassMatrix (bool isLumped)
839  {
840  M_lumpedMassMatrix = isLumped;
841  }
842 
843  //@}
844 
845  //! @name Methods
846  //@{
847 
848  //! setup method used in the constructor
849  /*!
850  @param dataFile needed to set up the preconditioner
851  @param ionicSize number of equation in the ionic model
852  */
853  virtual void setup (GetPot& dataFile, short int ionicSize);
854 
855  //! setup method used in the constructor
856  /*!
857  @param meshFile filename of the mesh
858  @param meshPath directory where we have the mesh
859  @param dataFile needed to set up the preconditioner
860  @param ionicSize number of equation in the ionic model
861  */
862  virtual void setup (std::string meshName, std::string meshPath, GetPot& dataFile,
863  short int ionicSize);
864 
865  //! create mass matrix
866  /*!
867  * Computes the mass matrix calling different methods if the mass should be lumped
868  */
869  void setupMassMatrix(); //! create mass matrix
870 
871  //! create mass matrix
872  /*!
873  * Computes the lumped mass matrix by nodal integration.
874  */
875  void setupLumpedMassMatrix();
876 
877  //! create stiffness matrix
878  /*!
879  * Computes the stiffness matrix calling different methods
880  */
881  virtual void setupStiffnessMatrix();
882 
883  //! create stiffness matrix given a diagonal diffusion tensor
884  /*!
885  @param diffusion vector defining the conductivities
886  */
887  void setupStiffnessMatrix (VectorSmall<3> diffusion);
888 
889  //! setup the total matrix
890  /*!
891  * \f[
892  * A = C_m\frac{M}{\Delta t} + K(\mathbf{f})
893  * \f]
894  *
895  * where \fC_m\f is the membrane capacitance, \f\Delta t\f the timestep,
896  * M is the mass matrix and K is the stiffness matrix which depends on
897  * the fiber direction.
898  */
899  void setupGlobalMatrix();
900 
901  //! setup the linear solver
902  /*!
903  * A file named MonodomainSolverParamList.xml must be in the execution folder
904  * with the parameters to set the linear solver
905  @param dataFile GetPot to setup the preconditioners
906  */
907  void setupLinearSolver (GetPot dataFile);
908 
909  //! Initialize the potential to the value k
910  /*!
911  @param k value to intialize the potential
912  */
913  void inline initializePotential (Real k = 0.0)
914  {
915  (*M_potentialPtr) = k;
916  }
917 
918  //! Initialize the applied current to the value k
919  /*!
920  @param k value to intialize the applied current
921  */
922  void inline initializeAppliedCurrent (Real k = 0.0)
923  {
924  (* (M_ionicModelPtr->appliedCurrentPtr() ) ) = k;
925  }
926 
927  //! creates a vector of pointers to store the solution
928  /*!
929  * The first pointer points to the vector of the transmembrane potential,
930  * while the others point to the gating variables
931  @param ionicSize number of unknowns in the ionic model
932  */
933  void setupGlobalSolution (short int ionicSize);
934 
935  //! creates a vector of pointers to store the rhs
936  /*!
937  * The first pointer points to the rhs of the transmembrane potential,
938  * while the others point to the rhs of the gating variables
939  @param ionicSize number of unknowns in the ionic model
940  */
941  void setupGlobalRhs (short int ionicSize);
942 
943  //! Set parameters from an xml file
944  /*!
945  @param list Teuchos parameter list with the monodomain parameters
946  */
947  void setParameters (list_Type list);
948 
949  //! partition the mesh
950  /*!
951  @param meshName filename of the mesh
952  @param meshPath path to the folder where you have the mesh
953  */
954  void inline partitionMesh (std::string meshName, std::string meshPath)
955  {
956  MeshUtility::loadMesh (M_localMeshPtr, M_fullMeshPtr, meshName, meshPath);
957  }
958 
959  //! given a boost function initialize the potential
960  /*!
961  @param f function defining the potential
962  @param time time at which we want to evaluate the function
963  */
964  void inline setPotentialFromFunction (function_Type& f, Real time = 0.0)
965  {
966  M_feSpacePtr->interpolate (
967  static_cast<FESpace<RegionMesh<LinearTetra>, MapEpetra>::function_Type> (f),
968  *M_potentialPtr, time);
969  }
970 
971  //! given a boost function initialize the applied current
972  /*!
973  @param f function defining the applied current
974  @param time time at which we want to evaluate the function
975  */
977  Real time = 0.0)
978  {
979  M_ionicModelPtr->setAppliedCurrentFromFunction (f, M_feSpacePtr, time);
980  }
981 
982  //! given a ElectroStimulus object initialize the applied current
983  /*!
984  @param stimulus pacing protocol
985  @param time time at which we want to evaluate the stimulus
986  */
988  Real time = 0.0)
989  {
990 
991  M_ionicModelPtr->setAppliedCurrentFromElectroStimulus (stimulus, M_feSpacePtr, time);
992  }
993 
994  //! Solves one reaction step using the forward Euler scheme and N subiterations
995  /*!
996  * \f[
997  * \mathbf{V}^* = \mathbf{V}^{n+k/N} + \frac{\Delta t}{N} I_{ion}(\mathbf{V}^{n+k/N}), \quad k=0,\dots,N-1.
998  * \f]
999  */
1000  /*!
1001  @param int number of subiterations
1002  */
1003  void solveOneReactionStepFE (int subiterations = 1);
1004 
1005  //! Solves one reaction step using the forward Euler scheme
1006  /*!
1007  * \f[
1008  * \mathbf{V}^* = \mathbf{V}^{n+k/N} + \frac{\Delta t}{N} M I_{ion}(\mathbf{V}^{n+k/N}), \quad k=0,\dots,N-1.
1009  * \f]
1010  */
1011  /*!
1012  @param matrix_Type full mass matrix
1013  @param int number of subiterations
1014  */
1015  void solveOneReactionStepFE (matrix_Type& mass, int subiterations = 1);
1016 
1017  //! Solves one reaction step using the Rush-Larsen scheme
1018  /*!
1019  @param int number of subiterations
1020  */
1021  void solveOneReactionStepRL (int subiterations = 1);
1022 
1023  //! Update the rhs
1024  /*!
1025  * \f[
1026  * rhs \leftarrow C_m \frac{M}{\Delta t} \mathbf{V}^n
1027  * \f]
1028  */
1029  void inline updateRhs()
1030  {
1031  (*M_rhsPtrUnique) += (*M_massMatrixPtr) * (*M_potentialPtr)
1032  * (M_ionicModelPtr -> membraneCapacitance() / (M_timeStep) );
1033  }
1034 
1035  //! Solves one diffusion step using the BDF2 scheme
1036  /*!
1037  * \f[
1038  * ( \frac{3}{\Delta t}M + A ) V^{n+1} = \frac{1}{\Delta t}M(4 V^n -V^{n-1})
1039  * \f]
1040  */
1041  /*!
1042  @param previousPotentialPtr potential at \f n-1 \f
1043  */
1044  void solveOneDiffusionStepBDF2 (vectorPtr_Type previousPotentialPtr);
1045 
1046  //! Solves one diffusion step using the backward Euler scheme
1047  /*!
1048  * \f[
1049  * A\mathbf{V}^{n+1} = \left( C_m \frac{M}{\Delta t} + K(\mathbf{f}) \right)\mathbf{V}^{n+1} =\frac{M}{\Delta t} \mathbf{V}^*.
1050  * \f]
1051  */
1052  void solveOneDiffusionStepBE();
1053 
1054  //!Solve one full step with operator splitting
1055  /*!
1056  * \f[
1057  * \mathbf{V}^* = \mathbf{V}^n + \Delta t I_{ion}(\mathbf{V}^n).
1058  * \f]
1059  * \f[
1060  * A\mathbf{V}^{n+1} = \left( \frac{M}{\Delta t} + K(\mathbf{f}) \right)\mathbf{V}^{n+1} =\frac{M}{\Delta t} \mathbf{V}^*.
1061  * \f]
1062  */
1063  void solveOneSplittingStep();
1064 
1065  //!Solve the system with operator splitting from M_initialTime to the M_endTime with time step M_timeStep
1066  void solveSplitting();
1067 
1068  //!Solve one full step with operator splitting and export the solution
1069  /*!
1070  * \f[
1071  * \mathbf{V}^* = \mathbf{V}^n + \Delta t I_{ion}(\mathbf{V}^n).
1072  * \f]
1073  * \f[
1074  * A\mathbf{V}^{n+1} = \left( \frac{M}{\Delta t} + K(\mathbf{f}) \right)\mathbf{V}^{n+1} =\frac{M}{\Delta t} \mathbf{V}^*.
1075  * \f]
1076  */
1077  /*!
1078  @param exporter where you want to save the solution
1079  @param t time at which we save the solution
1080  */
1081  void solveOneSplittingStep (IOFile_Type& exporter, Real t);
1082 
1083  //!Solve the system with operator splitting from M_initialTime to the M_endTime with time step M_timeStep and export the solution
1084  /*!
1085  @param exporter where you want to save the solution
1086  */
1087  void solveSplitting (IOFile_Type& exporter);
1088 
1089  //!Solve the system with operator splitting from M_initialTime to the M_endTime with time step M_timeStep and export the solution every dt
1090  /*!
1091  @param exporter where you want to save the solution
1092  @param t time at which we save the solution
1093  */
1094  void solveSplitting (IOFile_Type& exporter, Real dt);
1095 
1096  //! add to a given exporter the pointer to the potential saved with name fileName
1097  /*!
1098  @param exporter where you want to save the solution
1099  @param t time at which we save the solution
1100  */
1101  void setupPotentialExporter (IOFile_Type& exporter, std::string fileName = "Potential");
1102 
1103  //! add to a given exporter the pointer to the potential and to the gating variables saved with name fileName
1104  /*!
1105  @param exporter where you want to save the solution
1106  @param fileName name of the file we wish to export
1107  @param folder directory where to save the solution
1108  */
1109  void setupExporter (IOFile_Type& exporter, std::string fileName = "output",
1110  std::string folder = "./");
1111 
1112  //! Generates a default fiber direction (0,1,0)
1113  void setupFibers();
1114 
1115  //! Generates the fiber direction given the three component of the vector (F_x,F_y,F_z)
1116  /*!
1117  @param fibers vector with the fiber direction
1118  */
1119  void setupFibers (VectorSmall<3> fibers);
1120 
1121  //! Imports the fiber direction from a hdf5 file
1122  /*!
1123  @param fibersFile name of the hdf5 file with the fibers
1124  */
1125  inline void setupFibers (std::string fibersFile, const std::string& filePath = "./")
1126  {
1127  ElectrophysiologyUtility::importFibers (M_fiberPtr, fibersFile, M_localMeshPtr, filePath);
1128  }
1129 
1130  //! Imports the fiber direction from a vtk file ( format = 0), or text file
1131  /*!
1132  @param fibersFile name of the file with the fibers
1133  @param directory folder in which we have the file for the fibers
1134  @param format format in which fibers are saved
1135  *
1136  * format 0 = fibers saved as (fx, fy, fz) in each row
1137  *
1138  * format 1 = fibers saved as fx in each row for all the mesh
1139  * fy in each row for all the mesh
1140  * fz in each row for all the mesh
1141  */
1142  inline void setupFibers (std::string fibersFile, std::string directory,
1143  int format = 0)
1144  {
1145  ElectrophysiologyUtility::importFibersFromTextFile (M_fiberPtr, fibersFile,
1146  directory, format);
1147  }
1148 
1149  //! Solves the gating variables with forward Euler
1151 
1152  //! Solves the gating variables with Rush-Larsen scheme
1154 
1155  //! Compute the rhs using state variable interpolation
1156  void computeRhsSVI();
1157 
1158  //! Compute the rhs using ionic current interpolation
1159  void computeRhsICI();
1160 
1161  //! Compute the rhs using ionic current interpolation
1162  /*!
1163  * This method is useful to solve ICI without lumping the mass matrix
1164  * in fron of the reaction term.
1165  * Lump the mass matrix, and pass as argument a full mass matrix
1166  */
1167  void computeRhsICIWithFullMass ();
1168 
1169  //!Solve one full step with ionic current interpolation
1170  /*!
1171  * \f[
1172  * A\mathbf{V}^{n+1} = \left( \frac{M}{\Delta t} + K(\mathbf{f}) \right)\mathbf{V}^{n+1} =\frac{M}{\Delta t} \mathbf{V}^n+M\mathbf{I},
1173  * \f]
1174  * where $\mathbf{I}$ is the vector of the ionic currents $I_j = I_{ion}(V_j^n)$
1175  */
1176  virtual void solveOneICIStep();
1177 
1178  //! solves using ionic current interpolation
1179  /*!
1180  * This method is useful to solve ICI without lumping the mass matrix
1181  * in front of the reaction term.
1182  * Lump the mass matrix, and pass as argument a full mass matrix
1183  */
1185 
1186  //!Solve one full step with state variable interpolation
1187  /*!
1188  * \f[
1189  * A\mathbf{V}^{n+1} = \left( \frac{M}{\Delta t} + K(\mathbf{f}) \right)\mathbf{V}^{n+1} =\frac{M}{\Delta t} \mathbf{V}^n+\mathbf{I}_{ion}(\mathbf{V}^n).
1190  * \f]
1191  */
1192  void solveOneSVIStep();
1193 
1194  //! solve system using ICI from M_initialTime to the M_endTime with time step M_timeStep
1195  void solveICI();
1196 
1197  //! solve system using SVI from M_initialTime to the M_endTime with time step M_timeStep
1198  void solveSVI();
1199 
1200  //!Solve one full step with ionic current interpolation and export the solution
1201  /*!
1202  * \f[
1203  * A\mathbf{V}^{n+1} = \left( \frac{M}{\Delta t} + K(\mathbf{f}) \right)\mathbf{V}^{n+1} =\frac{M}{\Delta t} \mathbf{V}^n+M\mathbf{I},
1204  * \f]
1205  * where $\mathbf{I}$ is the vector of the ionic currents $I_j = I_{ion}(V_j^n)$
1206  @param exporter where we want to save the solution
1207  @param t time at wich we save the solution
1208  */
1209  void solveOneICIStep (IOFile_Type& exporter, Real t);
1210 
1211  //!Solve one full step with ionic current interpolation and export the solution
1212  /*!
1213  * \f[
1214  * A\mathbf{V}^{n+1} = \left( \frac{M}{\Delta t} + K(\mathbf{f}) \right)\mathbf{V}^{n+1} =\frac{M}{\Delta t} \mathbf{V}^n+M\mathbf{I},
1215  * \f]
1216  * where $\mathbf{I}$ is the vector of the ionic currents $I_j = I_{ion}(V_j^n)$
1217  * This method is useful to solve ICI without lumping the mass matrix
1218  * in front of the reaction term.
1219  * Lump the mass matrix, and pass as argument a full mass matrix
1220  @param exporter where we want to save the solution
1221  @param t time at wich we save the solution
1222  */
1223  void solveOneICIStepWithFullMass (IOFile_Type& exporter, Real t);
1224 
1225  //!Solve one full step with ionic current interpolation and export the solution
1226  /*!
1227  * \f[
1228  * A\mathbf{V}^{n+1} = \left( \frac{M}{\Delta t} + K(\mathbf{f}) \right)\mathbf{V}^{n+1} =\frac{M}{\Delta t} \mathbf{V}^n+\mathbf{I}_{ion}(\mathbf{V}^n).
1229  * \f]
1230  @param exporter where we want to save the solution
1231  @param t time at wich we save the solution
1232  */
1233  void solveOneSVIStep (IOFile_Type& exporter, Real t);
1234 
1235  //! solve system using ICI from M_initialTime to the M_endTime with time step M_timeStep and export the solution
1236  /*!
1237  @param exporter where we want to save the solution
1238  */
1239  void solveICI (IOFile_Type& exporter);
1240 
1241  //! solve system using SVI from M_initialTime to the M_endTime with time step M_timeStep and export the solution
1242  /*!
1243  @param exporter where we want to save the solution
1244  */
1245  void solveSVI (IOFile_Type& exporter);
1246 
1247  //!Solve the system using ICI from M_initialTime to the M_endTime with time step M_timeStep and export the solution every dt
1248  /*!
1249  @param exporter where we want to save the solution
1250  @param t time at wich we save the solution
1251  */
1252  void solveICI (IOFile_Type& exporter, Real dt);
1253 
1254  //!Solve the system using ICI from M_initialTime to the M_endTime with time step M_timeStep and export the solution every dt
1255  /*!
1256  * This method is useful to solve ICI without lumping the mass matrix
1257  * in front of the reaction term.
1258  * Lump the mass matrix, and pass as argument a full mass matrix
1259  @param exporter where we want to save the solution
1260  @param t time at wich we save the solution
1261  */
1262  void solveICIWithFullMass (IOFile_Type& exporter, Real dt);
1263 
1264  //!Solve the using SVI from M_initialTime to the M_endTime with time step M_timeStep and export the solution every dt
1265  /*!
1266  @param exporter where we want to save the solution
1267  @param t time at wich we save the solution
1268  */
1269  void solveSVI (IOFile_Type& exporter, Real dt);
1270 
1271  //! Generates a file where the fiber direction is saved
1272  /*!
1273  @param postDir directory in which we save the fibers
1274  */
1275  void exportFiberDirection (std::string postDir = "./");
1276 
1277  //! save the fiber direction into the given exporter
1278  /*!
1279  @param exporter where we want to save the solution
1280  */
1281  void exportFiberDirection (IOFile_Type& exporter);
1282 
1283  //! Save the solution in the exporter
1284  /*!
1285  @param exporter where we want to save the solution
1286  @param t time at wich we save the solution
1287  */
1288  void inline exportSolution (IOFile_Type& exporter, Real t)
1289  {
1290  exporter.postProcess (t);
1291  }
1292 
1293  //! Importer: lead a solution from an hdf5 file
1294  /*!
1295  @param prefix name of the hdf5 file to import
1296  @param postDir folder where the file to import is
1297  @param time time at wich we want to import the solution
1298  */
1299  void importSolution (std::string prefix, std::string postDir, Real time = 0.0);
1300 
1301  //! Initialize the solution with resting values of the ionic model
1302  void inline setInitialConditions()
1303  {
1304  M_ionicModelPtr->initialize (M_globalSolution);
1305  }
1306 
1307  //! save the fiber direction into the given exporter
1308  /*!
1309  * The activationTimeVector is required to be initialized with negative values
1310  *
1311  @param activationTimeVector vector where we register the activation time
1312  @param time time at which we are
1313  @param threshold value for which we consider activation
1314  */
1315  void registerActivationTime (vector_Type& activationTimeVector, Real time,
1316  Real threshold = 0.0);
1317  //! set the verbosity
1318  /*!
1319  *
1320  @param verbose show additional output
1321  */
1322  void setVerbosity (bool verbose);
1323 
1324  //@}
1325 
1326 private:
1327 
1328  //! Set default parameters
1329  void setParameters();
1330 
1331  //! initialization in constructor
1332  void init();
1333 
1334  //! initialization in constructor
1335  /*!
1336  @param comm epetra communicator
1337  */
1338  void init (commPtr_Type comm);
1339 
1340  //! initialization in constructor
1341  /*!
1342  @param meshPtr pointer to the mesh
1343  */
1344  void init (meshPtr_Type meshPtr);
1345 
1346  //! initialization in constructor
1347  /*!
1348  @param model pointer to the ionic model
1349  */
1350  void init (ionicModelPtr_Type model);
1351 
1352 protected:
1353  //surface to volume ration
1355  //ionic model
1357  //Epetra communicator
1359  //partitioned mesh
1361  //non partitioned mesh
1363  //ET finite element space
1365  //finite element space
1367  //mass matrix
1369  //full mass matrix
1371  //stiffness matrix
1373  //mass matrix / timestep + stiffness matrix
1375  //initial time t_0
1377  //final time t_f
1379  //timestep dt
1381  // conductivity tensor
1383  //rhs of the potential equation
1385  //rhs of the potential equation - unique version
1387  //potential
1389  //linear solver
1391  //vector of pointers pointing to the potential
1392  // and to the other gating variables
1394  //vector of pointers pointing to rhs of the potential
1395  // and to the ths of the other gating variables
1397  //order of the elements (P1)
1399  //fiber field
1401  //Create the identity matrix I
1403  //using lumped mass matrix
1405  //verbosity
1407 
1408 };
1409 // class MonodomainSolver
1410 
1411 //
1412 // IMPLEMENTATION
1413 //
1414 // ===================================================
1415 //! Constructors
1416 // ===================================================
1417 //!Empty constructor
1418 template<typename Mesh, typename IonicModel>
1420 {
1421  M_verbose = false;
1422  setParameters();
1423  init();
1424 }
1425 
1426 //!constructor
1427 template<typename Mesh, typename IonicModel>
1429  std::string meshName, std::string meshPath, GetPot& dataFile,
1430  ionicModelPtr_Type model)
1431 {
1432  M_verbose = false;
1433  setParameters();
1434  init (model);
1435  setup (meshName, meshPath, dataFile, M_ionicModelPtr->Size() );
1436 }
1437 
1438 //!constructor with communicator
1439 template<typename Mesh, typename IonicModel>
1441  std::string meshName, std::string meshPath, GetPot& dataFile,
1442  ionicModelPtr_Type model, commPtr_Type comm) :
1443  M_ionicModelPtr (model), M_verbose (false)
1444 {
1445  setParameters();
1446  init (comm);
1447  setup (meshName, meshPath, dataFile, M_ionicModelPtr->Size() );
1448 }
1449 
1450 template<typename Mesh, typename IonicModel>
1452  GetPot& dataFile, ionicModelPtr_Type model, meshPtr_Type meshPtr) :
1453  M_ionicModelPtr (model), M_verbose (false)
1454 {
1455  setParameters();
1456  init (meshPtr);
1457  setup (dataFile, M_ionicModelPtr->Size() );
1458 }
1459 
1460 //! Copy constructor
1461 template<typename Mesh, typename IonicModel>
1463  const ElectroETAMonodomainSolver& solver) :
1464  M_surfaceVolumeRatio (solver.M_surfaceVolumeRatio),
1465  M_ionicModelPtr (new IonicModel (*solver.M_ionicModelPtr) ),
1466  M_commPtr (solver.M_commPtr),
1467  M_localMeshPtr ( solver.M_localMeshPtr),
1468  M_fullMeshPtr (solver.M_fullMeshPtr),
1469  M_ETFESpacePtr ( new ETFESpace_Type (*solver.M_ETFESpacePtr) ),
1470  M_feSpacePtr ( new feSpace_Type (*solver.M_feSpacePtr) ),
1474  M_initialTime ( solver.M_initialTime),
1475  M_endTime (solver.M_endTime),
1476  M_timeStep ( solver.M_timeStep),
1477  M_diffusionTensor (solver.M_diffusionTensor),
1478  M_rhsPtr ( new vector_Type (* (solver.M_rhsPtr) ) ),
1479  M_rhsPtrUnique ( new vector_Type (* (M_rhsPtr), Unique) ),
1483  M_fiberPtr ( new vector_Type (* (solver.M_fiberPtr) ) ) ,
1484  M_lumpedMassMatrix (solver.M_lumpedMassMatrix),
1485  M_verbose (solver.M_verbose),
1487 {
1488  setupGlobalSolution (M_ionicModelPtr->Size() );
1489  setGlobalSolution (solver.M_globalSolution);
1490  setupGlobalRhs (M_ionicModelPtr->Size() );
1491  setGlobalRhs (solver.M_globalRhs);
1492 }
1493 
1494 //! Assignment operator
1495 template<typename Mesh, typename IonicModel>
1496 ElectroETAMonodomainSolver<Mesh, IonicModel>& ElectroETAMonodomainSolver < Mesh,
1497  IonicModel >::operator= (const ElectroETAMonodomainSolver& solver)
1498 {
1499  if (M_verbose && M_commPtr -> MyPID() == 0)
1500  {
1501  std::cout << "\n WARNING!!! ETA Monodomain Solver: you are using the assignment operator! This method is outdated.";
1502  std::cout << "\n WARNING!!! ETA Monodomain Solver: Don't count on it, at this moment. Feel free to update yourself...";
1503  }
1504  M_surfaceVolumeRatio = solver.M_surfaceVolumeRatio;
1505  setIonicModel ( (*solver.M_ionicModelPtr) );
1506  M_commPtr = solver.M_commPtr;
1507  M_localMeshPtr = solver.M_localMeshPtr;
1508  M_fullMeshPtr = solver.M_fullMeshPtr;
1509  setETFESpace (* (solver.M_ETFESpacePtr) );
1510  setFeSpace (* (solver.M_feSpacePtr) );
1511  setMassMatrix (* (solver.M_massMatrixPtr) );
1512  setStiffnessMatrix (* (solver.M_stiffnessMatrixPtr) );
1513  setGlobalMatrix (* (solver.M_globalMatrixPtr) );
1514  M_initialTime = solver.M_initialTime;
1515  M_endTime = solver.M_endTime;
1516  M_timeStep = solver.M_timeStep;
1517  M_diffusionTensor = solver.M_diffusionTensor;
1518  setRhs (* (solver.M_rhsPtr) );
1519  setRhsUnique (* (solver.M_rhsPtrUnique) );
1520  setPotential (* (solver.M_potentialPtr) );
1521 
1522  setLinearSolver (* (solver.M_linearSolverPtr) );
1523  setGlobalSolution (solver.M_globalSolution);
1524  setGlobalRhs (solver.M_globalRhs);
1525  M_elementsOrder = solver.M_elementsOrder;
1526  setFiber (* (solver.M_fiberPtr) );
1527  M_verbose = solver.M_verbose;
1528  M_identity = solver.M_identity;
1529 
1530  return *this;
1531 }
1532 
1533 /********* SETUP METHODS */ //////
1534 template<typename Mesh, typename IonicModel>
1535 void ElectroETAMonodomainSolver<Mesh, IonicModel>::setupFibers()
1536 {
1537 
1538  std::shared_ptr<FESpace<mesh_Type, MapEpetra> > Space3D (
1539  new FESpace<mesh_Type, MapEpetra> (M_localMeshPtr, M_elementsOrder,
1540  3, M_commPtr) );
1541 
1542  M_fiberPtr.reset (new vector_Type (Space3D->map() ) );
1543 
1544  int d1 = (*M_fiberPtr).epetraVector().MyLength() / 3;
1545  (*M_fiberPtr) *= 0;
1546  int j (0);
1547  for (int k (0); k < d1; k++)
1548  {
1549  j = (*M_fiberPtr).blockMap().GID (k + d1);
1550  (*M_fiberPtr) [j] = 1.0;
1551  }
1552 }
1553 
1554 template<typename Mesh, typename IonicModel>
1555 void ElectroETAMonodomainSolver<Mesh, IonicModel>::setupFibers (
1556  VectorSmall<3> fibers)
1557 {
1558  std::shared_ptr<FESpace<mesh_Type, MapEpetra> > Space3D (
1559  new FESpace<mesh_Type, MapEpetra> (M_localMeshPtr, M_elementsOrder,
1560  3, M_commPtr) );
1561 
1562  M_fiberPtr.reset (new vector_Type (Space3D->map() ) );
1563 
1564  ElectrophysiologyUtility::setupFibers (*M_fiberPtr, fibers);
1565 }
1566 
1567 template<typename Mesh, typename IonicModel>
1569  std::string postDir)
1570 {
1571  std::shared_ptr<FESpace<mesh_Type, MapEpetra> > Space3D (
1572  new FESpace<mesh_Type, MapEpetra> (M_localMeshPtr, M_elementsOrder,
1573  3, M_commPtr) );
1574 
1575  ExporterHDF5 < mesh_Type > exp;
1576  exp.setMeshProcId (M_localMeshPtr, M_commPtr->MyPID() );
1577  exp.setPostDir (postDir);
1578  exp.setPrefix ("FiberDirection");
1579  exp.addVariable (ExporterData<mesh_Type>::VectorField, "fibers", Space3D,
1580  M_fiberPtr, UInt (0) );
1581  exp.postProcess (0);
1582  exp.closeFile();
1583 }
1584 
1585 template<typename Mesh, typename IonicModel>
1587  IOFile_Type& exporter)
1588 {
1589  std::shared_ptr<FESpace<mesh_Type, MapEpetra> > Space3D (
1590  new FESpace<mesh_Type, MapEpetra> (M_localMeshPtr, M_elementsOrder,
1591  3, M_commPtr) );
1592 
1593  exporter.addVariable (ExporterData<mesh_Type>::VectorField, "fibers",
1594  Space3D, M_fiberPtr, UInt (0) );
1595  exporter.postProcess (0);
1596 }
1597 
1598 template<typename Mesh, typename IonicModel>
1599 void ElectroETAMonodomainSolver<Mesh, IonicModel>::importSolution (std::string prefix, std::string postDir, Real time)
1600 {
1601  IOFilePtr_Type importer (new hdf5IOFile_Type() );
1602  importer->setPrefix (prefix);
1603  importer->setPostDir (postDir);
1604 
1605  importer->setMeshProcId (M_feSpacePtr->mesh(),
1606  M_feSpacePtr->map().comm().MyPID() );
1607 
1608  importer->addVariable (IOData_Type::ScalarField, "Variable0", M_feSpacePtr,
1609  M_potentialPtr, static_cast<UInt> (0) );
1610  for (int i (1); i < M_ionicModelPtr->Size(); i++)
1611  importer->addVariable (IOData_Type::ScalarField,
1612  "Variable" + number2string (i), M_feSpacePtr,
1613  M_globalSolution.at (i), static_cast<UInt> (0) );
1614  importer->importFromTime (time);
1615  importer->closeFile();
1616 }
1617 
1618 template<typename Mesh, typename IonicModel>
1619 void ElectroETAMonodomainSolver<Mesh, IonicModel>::setup (GetPot& dataFile,
1620  short int ionicSize)
1621 {
1622  M_feSpacePtr.reset ( new feSpace_Type (M_localMeshPtr, M_elementsOrder, 1, M_commPtr) );
1623 
1624  M_ETFESpacePtr.reset ( new ETFESpace_Type (M_localMeshPtr, & (M_feSpacePtr -> refFE() ) , M_commPtr) );
1625 
1626  M_massMatrixPtr.reset (new matrix_Type (M_ETFESpacePtr->map() ) );
1627 
1628  M_stiffnessMatrixPtr.reset (new matrix_Type (M_ETFESpacePtr->map() ) );
1629 
1630  M_globalMatrixPtr.reset (new matrix_Type (M_ETFESpacePtr->map() ) );
1631 
1632  M_rhsPtr.reset (new vector_Type (M_ETFESpacePtr->map(), Repeated) );
1633 
1634  M_rhsPtrUnique.reset (new vector_Type (* (M_rhsPtr), Unique) );
1635 
1636  M_potentialPtr.reset (new vector_Type (M_ETFESpacePtr->map() ) );
1637 
1638  //***********************//
1639  // Setup Linear Solver //
1640  //***********************//
1641  setupLinearSolver (dataFile);
1642 
1643  //**************************//
1644  // Setup Initial condition //
1645  //**************************//
1647 
1648  vector_Type Iapp (M_feSpacePtr->map() );
1649  Iapp *= 0.0;
1650 
1651  M_ionicModelPtr->setAppliedCurrent (Iapp);
1652 
1653  setupGlobalSolution (ionicSize);
1654 
1655  setupGlobalRhs (ionicSize);
1656 }
1657 
1658 template<typename Mesh, typename IonicModel>
1659 void ElectroETAMonodomainSolver<Mesh, IonicModel>::setup (std::string meshName,
1660  std::string meshPath,
1661  GetPot& dataFile,
1662  short int ionicSize)
1663 {
1664  //partitioning the mesh
1665  partitionMesh (meshName, meshPath);
1666  setup (dataFile, ionicSize);
1667 }
1668 
1669 template<typename Mesh, typename IonicModel>
1671 {
1672  if (M_lumpedMassMatrix)
1673  {
1675  }
1676  else
1677  {
1678  *M_massMatrixPtr *= 0.0;
1679  if (M_verbose && M_localMeshPtr->comm()->MyPID() == 0)
1680  {
1681  std::cout << "\nETA Monodomain Solver: Setting up mass matrix";
1682  }
1683 
1684  {
1685  using namespace ExpressionAssembly;
1686 
1687  integrate (elements (M_localMeshPtr), M_feSpacePtr->qr(),
1688  M_ETFESpacePtr, M_ETFESpacePtr, phi_i * phi_j)
1689  >> M_massMatrixPtr;
1690 
1691  }
1692  M_massMatrixPtr->globalAssemble();
1693  }
1694 }
1695 
1696 template<typename Mesh, typename IonicModel>
1698 {
1699 
1700  M_lumpedMassMatrix = true;
1701  *M_massMatrixPtr *= 0.0;
1702  if (M_verbose && M_localMeshPtr->comm()->MyPID() == 0)
1703  {
1704  std::cout << "\nETA Monodomain Solver: Setting up lumped mass matrix";
1705  }
1706  {
1707  using namespace ExpressionAssembly;
1708 
1709  integrate (elements (M_localMeshPtr), quadRuleTetra4ptNodal,
1710  M_ETFESpacePtr, M_ETFESpacePtr, phi_i * phi_j)
1711  >> M_massMatrixPtr;
1712 
1713  }
1714  M_massMatrixPtr->globalAssemble();
1715 }
1716 
1717 
1718 template<typename Mesh, typename IonicModel>
1720 {
1721  setupStiffnessMatrix (M_diffusionTensor);
1722 }
1723 
1724 template<typename Mesh, typename IonicModel>
1726  VectorSmall<3> diffusion)
1727 {
1728  if (M_verbose && M_localMeshPtr->comm()->MyPID() == 0)
1729  {
1730  std::cout
1731  << "\nETA Monodomain Solver: Setting up stiffness matrix (only fiber field)";
1732  }
1733 
1734  *M_stiffnessMatrixPtr *= 0.0;
1735  Real sigmal = M_diffusionTensor[0];
1736  Real sigmat = M_diffusionTensor[1];
1737 
1738  ETFESpaceVectorialPtr_Type spaceVectorial (
1739  new ETFESpaceVectorial_Type (M_localMeshPtr, & (M_feSpacePtr -> refFE() ), M_commPtr) );
1740 
1741  {
1742  using namespace ExpressionAssembly;
1743 
1744  auto I = value(M_identity);
1745  auto f0 = value (spaceVectorial, *M_fiberPtr);
1746  auto D = value (sigmat) * I + (value (sigmal) - value (sigmat) ) * outerProduct (f0, f0);
1747 
1748  integrate (elements (M_localMeshPtr), M_feSpacePtr->qr(), M_ETFESpacePtr,
1749  M_ETFESpacePtr,
1750  dot ( D * grad (phi_i), grad (phi_j) ) )
1751  >> M_stiffnessMatrixPtr;
1752 
1753  }
1754 
1755  M_stiffnessMatrixPtr->globalAssemble();
1756 }
1757 
1758 template<typename Mesh, typename IonicModel>
1760 {
1761  (*M_globalMatrixPtr) *= 0;
1762  (*M_globalMatrixPtr) = (*M_stiffnessMatrixPtr);
1763  (*M_globalMatrixPtr) *= 1.0 / M_surfaceVolumeRatio;
1764  (*M_globalMatrixPtr) += ( (*M_massMatrixPtr) * ( M_ionicModelPtr -> membraneCapacitance() / M_timeStep) );
1765 }
1766 
1767 template<typename Mesh, typename IonicModel>
1769  GetPot dataFile)
1770 {
1771  prec_Type* precRawPtr;
1772  basePrecPtr_Type precPtr;
1773  precRawPtr = new prec_Type;
1774  precRawPtr->setDataFromGetPot (dataFile, "prec");
1775  precPtr.reset (precRawPtr);
1776 
1777  Teuchos::RCP < Teuchos::ParameterList > solverParamList = Teuchos::rcp ( new Teuchos::ParameterList);
1778 
1779  std::string xmlpath = dataFile ("electrophysiology/monodomain_xml_path", "./");
1780  std::string xmlfile = dataFile ("electrophysiology/monodomain_xml_file", "MonodomainSolverParamList.xml");
1781 
1782  solverParamList = Teuchos::getParametersFromXmlFile (xmlpath + xmlfile);
1783 
1784  M_linearSolverPtr->setCommunicator (M_commPtr);
1785  M_linearSolverPtr->setParameters (*solverParamList);
1786  M_linearSolverPtr->setPreconditioner (precPtr);
1787  M_linearSolverPtr->setOperator (M_globalMatrixPtr);
1788 }
1789 
1790 template<typename Mesh, typename IonicModel>
1791 void ElectroETAMonodomainSolver<Mesh, IonicModel>::setupGlobalSolution (
1792  short int ionicSize)
1793 {
1794  M_globalSolution.push_back (M_potentialPtr);
1795  for (int k = 1; k < ionicSize; ++k)
1796  {
1797  M_globalSolution.push_back (
1798  * (new vectorPtr_Type (new VectorEpetra (M_ETFESpacePtr->map() ) ) ) );
1799  }
1800 }
1801 
1802 template<typename Mesh, typename IonicModel>
1803 void ElectroETAMonodomainSolver<Mesh, IonicModel>::setupGlobalRhs (
1804  short int ionicSize)
1805 {
1806  M_globalRhs.push_back (M_rhsPtrUnique);
1807  for (int k = 1; k < ionicSize; ++k)
1808  {
1809  M_globalRhs.push_back (
1810  * (new vectorPtr_Type (new VectorEpetra (M_ETFESpacePtr->map() ) ) ) );
1811  }
1812 }
1813 
1814 /************** EXPORTER */ //////////////
1815 template<typename Mesh, typename IonicModel>
1816 void ElectroETAMonodomainSolver<Mesh, IonicModel>::setupPotentialExporter (
1817  IOFile_Type& exporter, std::string fileName)
1818 {
1819  exporter.setMeshProcId (M_localMeshPtr, M_commPtr->MyPID() );
1820  exporter.setPrefix (fileName);
1821  exporter.exportPID (M_localMeshPtr, M_commPtr);
1822  exporter.addVariable (ExporterData<mesh_Type>::ScalarField, "Potential",
1823  M_feSpacePtr, M_potentialPtr, UInt (0) );
1824 }
1825 
1826 template<typename Mesh, typename IonicModel>
1827 void ElectroETAMonodomainSolver<Mesh, IonicModel>::setupExporter (
1828  IOFile_Type& exporter, std::string fileName, std::string folder)
1829 {
1830  exporter.setMeshProcId (M_localMeshPtr, M_commPtr->MyPID() );
1831  exporter.setPrefix (fileName);
1832  exporter.exportPID (M_localMeshPtr, M_commPtr);
1833  exporter.setPostDir (folder);
1834  std::string variableName;
1835  for (int i = 0; i < M_ionicModelPtr->Size(); i++)
1836  {
1837  variableName = "Variable" + std::to_string<std::string> (i);
1838  exporter.addVariable (ExporterData<mesh_Type>::ScalarField, variableName,
1839  M_feSpacePtr, M_globalSolution.at (i), UInt (0) );
1840  }
1841 }
1842 
1843 /********* SOLVING METHODS */ ////////////////////////
1844 template<typename Mesh, typename IonicModel>
1845 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneReactionStepFE (
1846  int subiterations)
1847 {
1848  M_ionicModelPtr->superIonicModel::computeRhs (M_globalSolution, M_globalRhs);
1849 
1850  for (int i = 0; i < M_ionicModelPtr->Size(); i++)
1851  {
1852  if (i == 0)
1853  * (M_globalSolution.at (i) ) = * (M_globalSolution.at (i) )
1854  + ( (M_timeStep) / subiterations / M_ionicModelPtr -> membraneCapacitance() ) * (* (M_globalRhs.at (i) ) );
1855  else
1856  * (M_globalSolution.at (i) ) = * (M_globalSolution.at (i) )
1857  + ( (M_timeStep) / subiterations) * (* (M_globalRhs.at (i) ) );
1858  }
1859 }
1860 
1861 
1862 template<typename Mesh, typename IonicModel>
1863 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneReactionStepFE (matrix_Type& mass, int subiterations)
1864 {
1865  M_ionicModelPtr->superIonicModel::computeRhs (M_globalSolution, M_globalRhs);
1866 
1867  for (int i = 0; i < M_ionicModelPtr->Size(); i++)
1868  {
1869  if (i == 0)
1870  {
1871 
1872  vector_Type aux ( M_potentialPtr -> map() );
1873  aux = mass.operator * ( (* (M_globalRhs.at (i) ) ) );
1874  * (M_globalSolution.at (i) ) = * (M_globalSolution.at (i) )
1875  + ( (M_timeStep) / subiterations / M_ionicModelPtr -> membraneCapacitance() ) * aux;
1876  }
1877  else
1878  * (M_globalSolution.at (i) ) = * (M_globalSolution.at (i) )
1879  + ( (M_timeStep) / subiterations) * (* (M_globalRhs.at (i) ) );
1880  }
1881 }
1882 
1883 
1884 
1885 template<typename Mesh, typename IonicModel>
1886 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneReactionStepRL (
1887  int subiterations)
1888 {
1889  M_ionicModelPtr->superIonicModel::computeRhs (M_globalSolution, M_globalRhs);
1890 
1891  * (M_globalSolution.at (0) ) = * (M_globalSolution.at (0) )
1892  + ( (M_timeStep) / subiterations / M_ionicModelPtr -> membraneCapacitance() ) * (* (M_globalRhs.at (0) ) );
1893 
1894  M_ionicModelPtr->superIonicModel::computeGatingVariablesWithRushLarsen (
1895  M_globalSolution, M_timeStep / subiterations);
1896  int offset = M_ionicModelPtr->numberOfGatingVariables() + 1;
1897  for (int i = offset; i < M_ionicModelPtr->Size(); i++)
1898  {
1899  * (M_globalSolution.at (i) ) = * (M_globalSolution.at (i) )
1900  + ( (M_timeStep) / subiterations) * (* (M_globalRhs.at (i) ) );
1901  }
1902 
1903 }
1904 
1905 template<typename Mesh, typename IonicModel>
1906 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneDiffusionStepBDF2 (
1907  vectorPtr_Type previousPotentialPtr)
1908 {
1909  matrixPtr_Type OperatorBDF2 (new matrix_Type (M_feSpacePtr->map() ) );
1910  vectorPtr_Type rhsBDF2 (new vector_Type (M_feSpacePtr->map() ) );
1911  (*OperatorBDF2) *= 0;
1912  (*OperatorBDF2) = (*M_stiffnessMatrixPtr);
1913  (*OperatorBDF2) += (*M_stiffnessMatrixPtr);
1914  (*OperatorBDF2) += ( (*M_massMatrixPtr) * (3.0 / M_timeStep) );
1915  (*rhsBDF2) *= 0;
1916  (*rhsBDF2) = 4.0 * (*M_rhsPtrUnique);
1917  (*rhsBDF2) -= (*M_massMatrixPtr) * (*previousPotentialPtr)
1918  * (1.0 / M_timeStep);
1919  M_linearSolverPtr->setOperator (OperatorBDF2);
1920  M_linearSolverPtr->setRightHandSide (rhsBDF2);
1921  M_linearSolverPtr->solve (M_potentialPtr);
1922 }
1923 
1924 template<typename Mesh, typename IonicModel>
1925 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneDiffusionStepBE()
1926 {
1927  M_linearSolverPtr->setRightHandSide (M_rhsPtrUnique);
1928  M_linearSolverPtr->solve (M_potentialPtr);
1929 }
1930 
1931 template<typename Mesh, typename IonicModel>
1932 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneSplittingStep()
1933 {
1934  solveOneReactionStepFE();
1935  (*M_rhsPtrUnique) *= 0;
1936  updateRhs();
1937  solveOneDiffusionStepBE();
1938 }
1939 
1940 template<typename Mesh, typename IonicModel>
1941 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneSplittingStep (
1942  IOFile_Type& exporter, Real t)
1943 {
1944  solveOneSplittingStep();
1945  exportSolution (exporter, t);
1946 }
1947 
1948 template<typename Mesh, typename IonicModel>
1949 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveSplitting()
1950 {
1951  for (Real t = M_initialTime; t < M_endTime;)
1952  {
1953  t = t + M_timeStep;
1954  solveOneSplittingStep();
1955  }
1956 }
1957 
1958 template<typename Mesh, typename IonicModel>
1959 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveSplitting (
1960  IOFile_Type& exporter)
1961 {
1962  if (M_endTime > M_timeStep)
1963  {
1964  for (Real t = M_initialTime; t < M_endTime;)
1965  {
1966  t = t + M_timeStep;
1967  solveOneSplittingStep (exporter, t);
1968  }
1969  }
1970 }
1971 
1972 template<typename Mesh, typename IonicModel>
1973 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveSplitting (
1974  IOFile_Type& exporter, Real dt)
1975 {
1976  assert (
1977  dt >= M_timeStep
1978  && "Cannot save the solution for step smaller than the timestep!");
1979  int iter ( (dt / M_timeStep) + 1e-9);
1980  int k (0);
1981  if (M_endTime > M_timeStep)
1982  {
1983  for (Real t = M_initialTime; t < M_endTime;)
1984  {
1985 
1986  t += M_timeStep;
1987  k++;
1988  if (k % iter == 0)
1989  {
1990  solveOneSplittingStep (exporter, t);
1991  }
1992  else
1993  {
1994  solveOneSplittingStep();
1995  }
1996 
1997  }
1998  }
1999 }
2000 
2001 template<typename Mesh, typename IonicModel>
2002 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneStepGatingVariablesFE()
2003 {
2004  M_ionicModelPtr->superIonicModel::computeGatingRhs (M_globalSolution,
2005  M_globalRhs);
2006 
2007  for (int i = 1; i < M_ionicModelPtr->Size(); i++)
2008  {
2009  * (M_globalSolution.at (i) ) = * (M_globalSolution.at (i) )
2010  + M_timeStep * (* (M_globalRhs.at (i) ) );
2011  }
2012 }
2013 template<typename Mesh, typename IonicModel>
2014 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneStepGatingVariablesRL()
2015 {
2016 
2017  M_ionicModelPtr->superIonicModel::computeGatingVariablesWithRushLarsen (
2018  M_globalSolution, M_timeStep);
2019  M_ionicModelPtr->superIonicModel::computeNonGatingRhs (M_globalSolution,
2020  M_globalRhs);
2021  int offset = M_ionicModelPtr->numberOfGatingVariables() + 1;
2022  for (int i = offset; i < M_ionicModelPtr->Size(); i++)
2023  {
2024  * (M_globalRhs[i]) *= M_timeStep;
2025  * (M_globalSolution[i]) += * (M_globalRhs[i]);
2026  }
2027 }
2028 
2029 template<typename Mesh, typename IonicModel>
2030 void ElectroETAMonodomainSolver<Mesh, IonicModel>::computeRhsICI()
2031 {
2032  M_ionicModelPtr->superIonicModel::computePotentialRhsICI (M_globalSolution,
2033  M_globalRhs, (*M_massMatrixPtr) );
2034  updateRhs();
2035 }
2036 
2037 template<typename Mesh, typename IonicModel>
2038 void ElectroETAMonodomainSolver<Mesh, IonicModel>::computeRhsICIWithFullMass ()
2039 {
2040  if (M_fullMassMatrixPtr)
2041  {
2042  M_ionicModelPtr->superIonicModel::computePotentialRhsICI (M_globalSolution,
2043  M_globalRhs, *M_fullMassMatrixPtr);
2044  }
2045  else
2046  {
2047  assert (0 && "fullMassMatrix Pointer was not set! Use the computeRhsICI() method!");
2048  }
2049  updateRhs();
2050 }
2051 
2052 template<typename Mesh, typename IonicModel>
2053 void ElectroETAMonodomainSolver<Mesh, IonicModel>::computeRhsSVI()
2054 {
2055  if (M_verbose && M_commPtr -> MyPID() == 0)
2056  {
2057  std::cout << "\nETA Monodomain Solver: updating rhs with SVI";
2058  }
2059  M_ionicModelPtr->superIonicModel::computePotentialRhsSVI (M_globalSolution,
2060  M_globalRhs, (*M_feSpacePtr) );
2061  updateRhs();
2062 }
2063 
2064 template<typename Mesh, typename IonicModel>
2065 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneICIStep()
2066 {
2067  computeRhsICI();
2068  M_linearSolverPtr->setRightHandSide (M_rhsPtrUnique);
2069  M_linearSolverPtr->solve (M_potentialPtr);
2070 }
2071 
2072 template<typename Mesh, typename IonicModel>
2073 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneICIStepWithFullMass ()
2074 {
2075  computeRhsICIWithFullMass ();
2076  M_linearSolverPtr->setRightHandSide (M_rhsPtrUnique);
2077  M_linearSolverPtr->solve (M_potentialPtr);
2078 }
2079 
2080 template<typename Mesh, typename IonicModel>
2081 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneSVIStep()
2082 {
2083  computeRhsSVI();
2084  M_linearSolverPtr->setRightHandSide (M_rhsPtrUnique);
2085  M_linearSolverPtr->solve (M_potentialPtr);
2086 }
2087 
2088 template<typename Mesh, typename IonicModel>
2089 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveICI()
2090 {
2091  for (Real t = M_initialTime; t < M_endTime;)
2092  {
2093  t = t + M_timeStep;
2094  solveOneStepGatingVariablesFE();
2095  solveOneICIStep();
2096  }
2097 }
2098 
2099 template<typename Mesh, typename IonicModel>
2100 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveSVI()
2101 {
2102  for (Real t = M_initialTime; t < M_endTime;)
2103  {
2104  t = t + M_timeStep;
2105  solveOneStepGatingVariablesFE();
2106  solveOneSVIStep();
2107  }
2108 }
2109 
2110 template<typename Mesh, typename IonicModel>
2111 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneICIStep (
2112  IOFile_Type& exporter, Real t)
2113 {
2114  solveOneICIStep();
2115  exportSolution (exporter, t);
2116 }
2117 
2118 template<typename Mesh, typename IonicModel>
2119 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneICIStepWithFullMass (
2120  IOFile_Type& exporter, Real t)
2121 {
2122  solveOneICIStepWithFullMass();
2123  exportSolution (exporter, t);
2124 }
2125 
2126 template<typename Mesh, typename IonicModel>
2127 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveOneSVIStep (
2128  IOFile_Type& exporter, Real t)
2129 {
2130  solveOneSVIStep();
2131  exportSolution (exporter, t);
2132 }
2133 
2134 template<typename Mesh, typename IonicModel>
2135 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveICI (
2136  IOFile_Type& exporter)
2137 {
2138 
2139  Real dt = M_timeStep;
2140  for (Real t = M_initialTime; t < M_endTime;)
2141  {
2142  t += M_timeStep;
2143  if (t > M_endTime)
2144  {
2145  M_timeStep = M_endTime - (t - dt);
2146  }
2147  solveOneStepGatingVariablesFE();
2148  solveOneICIStep (exporter, t);
2149  }
2150 }
2151 
2152 template<typename Mesh, typename IonicModel>
2153 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveSVI (
2154  IOFile_Type& exporter)
2155 {
2156  for (Real t = M_initialTime; t < M_endTime;)
2157  {
2158  t = t + M_timeStep;
2159  solveOneStepGatingVariablesFE();
2160  solveOneSVIStep (exporter, t);
2161  }
2162 }
2163 
2164 template<typename Mesh, typename IonicModel>
2165 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveICI (
2166  IOFile_Type& exporter, Real dt)
2167 {
2168  assert (
2169  dt >= M_timeStep
2170  && "Cannot save the solution for step smaller than the timestep!");
2171  int iter ( (dt / M_timeStep) + 1e-9);
2172  int k (0);
2173 
2174  if (M_endTime > M_timeStep)
2175  {
2176  for (Real t = M_initialTime; t < M_endTime;)
2177  {
2178 
2179  t += M_timeStep;
2180  if (t > M_endTime)
2181  {
2182  M_timeStep = M_endTime - (t - dt);
2183  }
2184  k++;
2185  solveOneStepGatingVariablesFE();
2186  if (k % iter == 0)
2187  {
2188  solveOneICIStep (exporter, t);
2189  }
2190  else
2191  {
2192  solveOneICIStep();
2193  }
2194 
2195  }
2196  }
2197 }
2198 
2199 
2200 template<typename Mesh, typename IonicModel>
2201 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveICIWithFullMass (
2202  IOFile_Type& exporter, Real dt)
2203 {
2204  assert (
2205  dt >= M_timeStep
2206  && "Cannot save the solution for step smaller than the timestep!");
2207  if (!M_fullMassMatrixPtr)
2208  {
2209  solveICI (exporter, dt);
2210  }
2211  else
2212  {
2213  int iter ( (dt / M_timeStep) + 1e-9);
2214  int k (0);
2215 
2216  if (M_endTime > M_timeStep)
2217  {
2218  for (Real t = M_initialTime; t < M_endTime;)
2219  {
2220 
2221  t += M_timeStep;
2222  if (t > M_endTime)
2223  {
2224  M_timeStep = M_endTime - (t - dt);
2225  }
2226  k++;
2227  solveOneStepGatingVariablesFE();
2228  if (k % iter == 0)
2229  {
2230  solveOneICIStepWithFullMass (exporter, t);
2231  }
2232  else
2233  {
2234  solveOneICIStepWithFullMass( );
2235  }
2236 
2237  }
2238  }
2239  }
2240 }
2241 
2242 template<typename Mesh, typename IonicModel>
2243 void ElectroETAMonodomainSolver<Mesh, IonicModel>::solveSVI (
2244  IOFile_Type& exporter, Real dt)
2245 {
2246  assert (
2247  dt >= M_timeStep
2248  && "Cannot save the solution for step smaller than the timestep!");
2249  int iter ( (dt / M_timeStep) + 1e-9);
2250  int k (0);
2251  if (M_endTime > M_timeStep)
2252  {
2253  for (Real t = M_initialTime; t < M_endTime;)
2254  {
2255 
2256  t += M_timeStep;
2257  k++;
2258  solveOneStepGatingVariablesFE();
2259  if (k % iter == 0)
2260  {
2261  solveOneSVIStep (exporter, t);
2262  }
2263  else
2264  {
2265  solveOneSVIStep();
2266  }
2267 
2268  }
2269  }
2270 }
2271 
2272 template<typename Mesh, typename IonicModel>
2273 void ElectroETAMonodomainSolver<Mesh, IonicModel>::registerActivationTime (
2274  vector_Type& activationTimeVector, Real time, Real threshold)
2275 {
2276  int n1 = M_potentialPtr->epetraVector().MyLength();
2277  int i (0);
2278  for (int l (0); l < n1; l++)
2279  {
2280  i = M_potentialPtr->blockMap().GID (l);
2281  if (activationTimeVector[i] < 0 && (* (M_potentialPtr) ) [i] > threshold)
2282  {
2283  activationTimeVector[i] = time;
2284  }
2285 
2286  }
2287 }
2288 
2289 /******** INITIALIZITION FOR CONSTRUCTOR ****/ //////
2290 template<typename Mesh, typename IonicModel>
2291 void ElectroETAMonodomainSolver<Mesh, IonicModel>::init()
2292 {
2293  M_linearSolverPtr.reset (new LinearSolver() );
2294  M_globalSolution = vectorOfPtr_Type();
2295  M_globalRhs = vectorOfPtr_Type();
2296 
2297  M_identity (0, 0) = 1.0;
2298  M_identity (0, 1) = 0.0;
2299  M_identity (0, 2) = 0.0;
2300  M_identity (1, 0) = 0.0;
2301  M_identity (1, 1) = 1.0;
2302  M_identity (1, 2) = 0.0;
2303  M_identity (2, 0) = 0.0;
2304  M_identity (2, 1) = 0.0;
2305  M_identity (2, 2) = 1.0;
2306 
2307  M_commPtr.reset (new Epetra_MpiComm (MPI_COMM_WORLD) );
2308  M_localMeshPtr.reset (new mesh_Type (M_commPtr) );
2309  M_fullMeshPtr.reset (new mesh_Type (M_commPtr) );
2310 }
2311 
2312 template<typename Mesh, typename IonicModel>
2313 void ElectroETAMonodomainSolver<Mesh, IonicModel>::init (
2314  ionicModelPtr_Type model)
2315 {
2316  init();
2317  M_ionicModelPtr = model;
2318 }
2319 
2320 template<typename Mesh, typename IonicModel>
2321 void ElectroETAMonodomainSolver<Mesh, IonicModel>::init (commPtr_Type comm)
2322 {
2323  init();
2324  M_localMeshPtr.reset (new mesh_Type (M_commPtr) );
2325  M_fullMeshPtr.reset (new mesh_Type (M_commPtr) );
2326  M_commPtr = comm;
2327 }
2328 
2329 template<typename Mesh, typename IonicModel>
2330 void ElectroETAMonodomainSolver<Mesh, IonicModel>::init (meshPtr_Type meshPtr)
2331 {
2332  init();
2333  //TODO change the meshPtr to pass the fullMeshPtr
2334  M_localMeshPtr = meshPtr;
2335  M_fullMeshPtr.reset (new mesh_Type (M_commPtr) );
2336  M_commPtr = meshPtr->comm();
2337 }
2338 
2339 /********* parameter initialization */ ////////
2340 template<typename Mesh, typename IonicModel>
2341 void ElectroETAMonodomainSolver<Mesh, IonicModel>::setParameters()
2342 {
2343  M_surfaceVolumeRatio = 1400.0;
2344  M_diffusionTensor[0] = 1.0;
2345  M_diffusionTensor[1] = 1.0;
2346  M_diffusionTensor[2] = 1.0;
2347  M_initialTime = 0.0;
2348  M_endTime = 100.0;
2349  M_timeStep = 0.01;
2350  M_elementsOrder = "P1";
2351  M_lumpedMassMatrix = false;
2352 
2353 }
2354 
2355 template<typename Mesh, typename IonicModel>
2356 void ElectroETAMonodomainSolver<Mesh, IonicModel>::setParameters (
2357  list_Type list)
2358 {
2359  M_surfaceVolumeRatio = list.get ("surfaceVolumeRatio", 1400.0);
2360  M_diffusionTensor[0] = list.get ("longitudinalDiffusion", 1.0);
2361  M_diffusionTensor[1] = list.get ("transversalDiffusion", 1.0);
2362  M_diffusionTensor[2] = M_diffusionTensor[1];
2363  M_initialTime = list.get ("initialTime", 0.0);
2364  M_endTime = list.get ("endTime", 100.0);
2365  M_timeStep = list.get ("timeStep", 0.01);
2366  M_elementsOrder = list.get ("elementsOrder", "P1");
2367  M_lumpedMassMatrix = list.get ("LumpedMass", false);
2368 
2369 }
2370 
2371 template<typename Mesh, typename IonicModel>
2372 void ElectroETAMonodomainSolver<Mesh, IonicModel>::setVerbosity (
2373  bool verbose)
2374 {
2375  M_verbose = verbose;
2376 }
2377 } // namespace LifeV
2378 
2379 #endif //_MONODOMAINSOLVER_H_
void computeRhsSVI()
Compute the rhs using state variable interpolation.
void setEndTime(const Real &endTime)
set the time step
void init(ionicModelPtr_Type model)
initialization in constructor
VectorEpetra - The Epetra Vector format Wrapper.
void setPotentialPtr(const vectorPtr_Type potentialPtr)
set the pointer to the potential
virtual void setup(GetPot &dataFile, short int ionicSize)
setup method used in the constructor
void setFullMesh(const mesh_Type &fullMesh)
set the non partitioned mesh
void solveOneICIStep(IOFile_Type &exporter, Real t)
Solve one full step with ionic current interpolation and export the solution.
void initializeAppliedCurrent(Real k=0.0)
Initialize the applied current to the value k.
ElectroETAMonodomainSolver(std::string meshName, std::string meshPath, GetPot &dataFile, ionicModelPtr_Type model, commPtr_Type comm)
Constructor.
void solveOneDiffusionStepBE()
Solves one diffusion step using the backward Euler scheme.
void solveICI(IOFile_Type &exporter, Real dt)
Solve the system using ICI from M_initialTime to the M_endTime with time step M_timeStep and export t...
void setMassMatrix(const matrix_Type &massMatrix)
set the mass matrix
void setRhs(const vector_Type &rhs)
set the right hand side
std::shared_ptr< ETFESpace< mesh_Type, MapEpetra, 3, 1 > > ETFESpacePtr_Type
MatrixEpetra< Real > matrix_Type
Distributed Matrix // For parallel usage.
const vectorOfPtr_Type & globalRhs() const
get the pointer to the vector of pointers containing the rhs for transmembrane potential (at 0) and t...
void setLumpedMassMatrix(bool isLumped)
set the the choice of lumping
void exportFiberDirection(std::string postDir="./")
Generates a file where the fiber direction is saved.
void solveOneICIStepWithFullMass(IOFile_Type &exporter, Real t)
Solve one full step with ionic current interpolation and export the solution.
void solveOneICIStepWithFullMass()
solves using ionic current interpolation
void solveICIWithFullMass(IOFile_Type &exporter, Real dt)
Solve the system using ICI from M_initialTime to the M_endTime with time step M_timeStep and export t...
void setVerbosity(bool verbose)
set the verbosity
void solveSplitting()
Solve the system with operator splitting from M_initialTime to the M_endTime with time step M_timeSte...
const meshPtr_Type localMeshPtr() const
get the pointer to the partitioned mesh
void importSolution(std::string prefix, std::string postDir, Real time=0.0)
Importer: lead a solution from an hdf5 file.
void partitionMesh(std::string meshName, std::string meshPath)
partition the mesh
ExporterEnsight data exporter.
virtual void setupStiffnessMatrix()
create stiffness matrix
void setupFibers(VectorSmall< 3 > fibers)
Generates the fiber direction given the three component of the vector (F_x,F_y,F_z) ...
const matrixPtr_Type massMatrixPtr() const
get the pointer to the mass matrix
const vectorOfPtr_Type & globalSolution() const
get the pointer to the vector of pointers containing the transmembrane potential (at 0) and the gatin...
FESpace - Short description here please!
Definition: FESpace.hpp:78
void setETFESpacePtr(const ETFESpacePtr_Type ETFESpacePtr)
set the pointer to the ETA fe space
void setFiberPtr(const vectorPtr_Type fiberPtr)
set the pointer to the fiber direction vector
ElectroIonicModel superIonicModel
Base class of the ionic model.
void setTimeStep(const Real &timeStep)
set the ending time
vectorPtr_Type fiberPtr()
get the pointer to the fiber vector
void importFromHDF5(std::string const &fileName, std::string const &matrixName="matrix")
Read a matrix from a HDF5 (.h5) file.
std::shared_ptr< matrix_Type > matrixPtr_Type
void solveSplitting(IOFile_Type &exporter)
Solve the system with operator splitting from M_initialTime to the M_endTime with time step M_timeSte...
virtual void solveOneICIStep()
Solve one full step with ionic current interpolation.
ETFESpace< mesh_Type, MapEpetra, 3, 1 > ETFESpace_Type
Expression template scalar finite element space To be used in the expression assembly namespace...
void setupGlobalMatrix()
setup the total matrix
std::vector< vectorPtr_Type > vectorOfPtr_Type
virtual std::vector< std::vector< Real > > getJac(const std::vector< Real > &v, Real h=1.0e-8)
This methods computes the Jacobian numerically.
void setupGlobalRhs(short int ionicSize)
creates a vector of pointers to store the rhs
const Real & endTime() const
get the time step
void solveOneSVIStep(IOFile_Type &exporter, Real t)
Solve one full step with ionic current interpolation and export the solution.
void exportFiberDirection(IOFile_Type &exporter)
save the fiber direction into the given exporter
void setFullMassMatrixPtr(const matrixPtr_Type fullMassMatrixPtr)
set the pointer to the full mass matrix
const matrixPtr_Type globalMatrixPtr() const
get the pointer to the global matrix
void setMassMatrixPtr(const matrixPtr_Type massMatrixPtr)
set the pointer to the mass matrix
void exportSolution(IOFile_Type &exporter, Real t)
Save the solution in the exporter.
LifeV::Preconditioner basePrec_Type
Preconditioner.
void setFullMassMatrix(const matrix_Type &fullMassMatrix)
set the full mass matrix
void setAppliedCurrentFromFunction(function_Type &f, Real time=0.0)
given a boost function initialize the applied current
ExporterData< mesh_Type > IOData_Type
Exporter data.
const linearSolverPtr_Type linearSolverPtr() const
get the pointer to the linear solver
Exporter< mesh_Type > IOFile_Type
Exporter to save the solution.
void setETFESpace(const ETFESpace_Type &ETFESpace)
set the scalar ETA fe space
ElectroETAMonodomainSolver(GetPot &dataFile, ionicModelPtr_Type model, meshPtr_Type meshPtr)
Constructor.
void init()
initialization in constructor
std::shared_ptr< feSpace_Type > feSpacePtr_Type
void setGlobalMatrix(const matrix_Type &globalMatrix)
set the global matrix
const vectorPtr_Type rhsPtr() const
get the pointer to the right hand side
void setParameters()
Set default parameters.
const Real & initialTime() const
get the initial time (by default 0)
void setFullMeshPtr(const meshPtr_Type fullMeshPtr)
set the pointer to the non partitioned mesh
void setCommPtr(const commPtr_Type commPtr)
set the pointer to the Epetra communicator
void setInitialConditions()
Initialize the solution with resting values of the ionic model.
void solveOneSVIStep()
Solve one full step with state variable interpolation.
ElectroETAMonodomainSolver< Mesh, IonicModel > & operator=(const ElectroETAMonodomainSolver &solver)
Operator=()
void solveICI(IOFile_Type &exporter)
solve system using ICI from M_initialTime to the M_endTime with time step M_timeStep and export the s...
std::shared_ptr< ETFESpaceVectorial_Type > ETFESpaceVectorialPtr_Type
std::shared_ptr< VectorEpetra > vectorPtr_Type
const meshPtr_Type fullMeshPtr() const
get the pointer to the partitioned mesh
std::function< Real(const Real &t, const Real &x, const Real &y, const Real &z, const ID &i) > function_Type
boost function
const ETFESpacePtr_Type ETFESpacePtr() const
get the pointer to the ETA finite element space
void solveOneDiffusionStepBDF2(vectorPtr_Type previousPotentialPtr)
Solves one diffusion step using the BDF2 scheme.
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
void setIonicModelPtr(const ionicModelPtr_Type ionicModelPtr)
set the pointer to the ionic model
void solveOneSplittingStep()
Solve one full step with operator splitting.
void setStiffnessMatrix(const matrix_Type &stiffnessMatrix)
set the stiffness matrix
const vectorPtr_Type potentialPtr() const
get the pointer to the transmembrane potential
void setGlobalSolution(const vectorOfPtr_Type &globalSolution)
set the vectors of unknowns: containing the transmembrane potential (at 0) and the gating variables ...
void setupLinearSolver(GetPot dataFile)
setup the linear solver
const Real & timeStep() const
get the final time
std::shared_ptr< IOFile_Type > IOFilePtr_Type
const Real & surfaceVolumeRatio() const
get the surface to volume ratio
const vectorPtr_Type rhsPtrUnique() const
get the pointer to the unique version of the right hand side
void solveOneReactionStepRL(int subiterations=1)
Solves one reaction step using the Rush-Larsen scheme.
void solveOneReactionStepFE(int subiterations=1)
Solves one reaction step using the forward Euler scheme and N subiterations.
void solveSVI(IOFile_Type &exporter, Real dt)
Solve the using SVI from M_initialTime to the M_endTime with time step M_timeStep and export the solu...
VectorEpetra vector_Type
Distributed vector // For parallel usage.
void setPotentialFromFunction(function_Type &f, Real time=0.0)
given a boost function initialize the potential
void solveSVI(IOFile_Type &exporter)
solve system using SVI from M_initialTime to the M_endTime with time step M_timeStep and export the s...
void setGlobalSolutionPtrs(const vectorOfPtr_Type &globalSolution)
set the vector of pointers containing the transmembrane potential (at 0) and the gating variables ...
ExporterEnsight< mesh_Type > ensightIOFile_Type
void setLocalMesh(const mesh_Type &localMesh)
set the partitioned mesh
const matrixPtr_Type fullMassMatrixPtr() const
get the pointer to the mass matrix
ETFESpace< mesh_Type, MapEpetra, 3, 3 > ETFESpaceVectorial_Type
Expression template vectorial finite element space To be used in the expression assembly namespace...
void setInitialTime(const Real &initialTime)
set the starting time
const std::string elementsOrder() const
get the order of the elements
std::shared_ptr< basePrec_Type > basePrecPtr_Type
void setRhsPtrUnique(const vectorPtr_Type rhsPtrUnique)
set the pointer to the unique version of the right hand side
void setIonicModel(const ionicModel_Type &ionicModel)
set ionic model
void setPotential(const vector_Type &potential)
set the potential
void setParameters(list_Type list)
Set parameters from an xml file.
const VectorSmall< 3 > & diffusionTensor() const
get the diagonal diffusion tensor
ElectroETAMonodomainSolver(const ElectroETAMonodomainSolver &solver)
Copy Constructor.
Epetra_Comm comm_Type
Communicator to exchange informations among processes.
void setLinearSolver(const linearSolver_Type &linearSolver)
set the linear solver
const feSpacePtr_Type feSpacePtr() const
get the pointer to the usual finite element space
void initializePotential(Real k=0.0)
Initialize the potential to the value k.
void setupPotentialExporter(IOFile_Type &exporter, std::string fileName="Potential")
add to a given exporter the pointer to the potential saved with name fileName
const vectorPtr_Type appliedCurrentPtr()
get the pointer to the applied current vector
void setLocalMeshPtr(const meshPtr_Type localMeshPtr)
set the pointer to the partitioned mesh
void setComm(const comm_Type &comm)
set the Epetra communicator
void setVariablePtr(const vector_Type &gatingVariable, int j)
set the [j]-th gating variable
void solveSVI()
solve system using SVI from M_initialTime to the M_endTime with time step M_timeStep ...
std::shared_ptr< LinearSolver > linearSolverPtr_Type
LifeV::PreconditionerML prec_Type
MultiLevel Preconditioner.
void setAppliedCurrentPtr(const vectorPtr_Type appliedCurrentPtr)
set the pointer to the applied current vector
double Real
Generic real data.
Definition: LifeV.hpp:175
void solveOneReactionStepFE(matrix_Type &mass, int subiterations=1)
Solves one reaction step using the forward Euler scheme.
void setRhsUnique(const vector_Type &rhsPtrUnique)
set the unique version of the right hand side
const ionicModelPtr_Type ionicModelPtr() const
get the pointer to the ionic model
FESpace< mesh_Type, MapEpetra > feSpace_Type
Finite element space.
void setFeSpace(const feSpace_Type &feSpace)
set the fe space
void setupFibers()
Generates a default fiber direction (0,1,0)
void setFiber(const vector_Type &fiber)
set the fiber direction vector
void setRhsPtr(const vectorPtr_Type rhsPtr)
set the pointer to the right hand side
void setStiffnessMatrixPtr(const matrixPtr_Type stiffnessMatrixPtr)
set the pointer to the stiffness matrix
void setSurfaceVolumeRatio(const Real &surfaceVolumeRatio)
set the surface to volume ratio
void setupStiffnessMatrix(VectorSmall< 3 > diffusion)
create stiffness matrix given a diagonal diffusion tensor
void solveOneStepGatingVariablesFE()
Solves the gating variables with forward Euler.
void setLinearSolverPtr(const linearSolverPtr_Type linearSolverPtr)
set the pointer to the linear solver
const commPtr_Type commPtr() const
get the pointer to the Epetra communicator
virtual void setup(std::string meshName, std::string meshPath, GetPot &dataFile, short int ionicSize)
setup method used in the constructor
void registerActivationTime(vector_Type &activationTimeVector, Real time, Real threshold=0.0)
save the fiber direction into the given exporter
VectorEpetra & operator*=(const data_type &scalar)
Multiplication operator.
void solveICI()
solve system using ICI from M_initialTime to the M_endTime with time step M_timeStep ...
void setAppliedCurrent(const vector_Type &appliedCurrent)
set the applied current vector
void solveSplitting(IOFile_Type &exporter, Real dt)
Solve the system with operator splitting from M_initialTime to the M_endTime with time step M_timeSte...
void solveOneStepGatingVariablesRL()
Solves the gating variables with Rush-Larsen scheme.
void setupGlobalSolution(short int ionicSize)
creates a vector of pointers to store the solution
bool lumpedMassMatrix() const
getter for the boolean to know if we want a lumped matrix
MatrixSmall< 3, 3 > matrixSmall_Type
3x3 matrix
Teuchos::ParameterList list_Type
xml list to read parameters
void setFeSpacePtr(const feSpacePtr_Type feSpacePtr)
set the pointer to the usual fe space
const matrixPtr_Type stiffnessMatrixPtr() const
get the pointer to the stiffness matrix
const vectorPtr_Type fiberPtr() const
get the pointer to the fiber vector
void solveOneSplittingStep(IOFile_Type &exporter, Real t)
Solve one full step with operator splitting and export the solution.
void setVariablePtr(const vectorPtr_Type gatingVariable, int j)
set the pointer to the [j]-th gating variable
void setGlobalRhs(const vectorOfPtr_Type &globalRhs)
set the vectors containing the rhs for the transmembrane potential (at 0) and the gating variables ...
class ETFESpace A light, templated version of the FESpace
Definition: ETFESpace.hpp:93
ElectroETAMonodomainSolver(std::string meshName, std::string meshPath, GetPot &dataFile, ionicModelPtr_Type model)
Constructor.
void setGlobalRhsPtrs(const vectorOfPtr_Type &globalRhs)
set the vector of pointers containing the rhs for the transmembrane potential (at 0) and the gating v...
void computeRhsICI()
Compute the rhs using ionic current interpolation.
void computeRhsICIWithFullMass()
Compute the rhs using ionic current interpolation.
void setupFibers(std::string fibersFile, const std::string &filePath="./")
Imports the fiber direction from a hdf5 file.
void setupFibers(std::string fibersFile, std::string directory, int format=0)
Imports the fiber direction from a vtk file ( format = 0), or text file.
std::shared_ptr< superIonicModel > ionicModelPtr_Type
void setAppliedCurrentFromElectroStimulus(ElectroStimulus &stimulus, Real time=0.0)
given a ElectroStimulus object initialize the applied current
void setupExporter(IOFile_Type &exporter, std::string fileName="output", std::string folder="./")
add to a given exporter the pointer to the potential and to the gating variables saved with name file...
void setGlobalMatrixPtr(const matrixPtr_Type globalMatrixPtr)
set the pointer to the global matrix
void setDiffusionTensor(const VectorSmall< 3 > &diffusionTensor)
set the diagonal diffusion tensor
meshPtr_Type localMeshPtr()
get the pointer to the partitioned mesh