39 #ifndef _BIDOMAINSOLVER_H_ 40 #define _BIDOMAINSOLVER_H_ 42 #include <lifev/core/array/MatrixElemental.hpp> 43 #include <lifev/core/array/VectorElemental.hpp> 44 #include <lifev/core/fem/AssemblyElemental.hpp> 45 #include <lifev/core/fem/Assembly.hpp> 46 #include <lifev/core/fem/BCManage.hpp> 47 #include <lifev/core/algorithm/SolverAztecOO.hpp> 48 #include <lifev/core/array/MapEpetra.hpp> 49 #include <lifev/core/array/MatrixEpetra.hpp> 50 #include <lifev/core/array/VectorEpetra.hpp> 51 #include <lifev/core/fem/SobolevNorms.hpp> 52 #include <lifev/core/fem/GeometricMap.hpp> 53 #include <lifev/heart/solver/HeartBidomainData.hpp> 54 #include <lifev/core/util/LifeChrono.hpp> 55 #include <boost/shared_ptr.hpp> 56 #include <lifev/core/fem/FESpace.hpp> 57 #include <lifev/heart/solver/HeartStiffnessFibers.hpp> 58 #include <lifev/core/fem/TimeAdvanceBDF.hpp> 65 template <
typename Mesh,
111 std::shared_ptr<Epetra_Comm>& comm );
140 void initialize (
const Function&,
const Function& );
330 template<
typename Mesh,
typename SolverType>
336 std::shared_ptr<Epetra_Comm>& comm ) :
372 std::stringstream MyPID;
373 ifstream fibers (M_data.fibersFile().c_str() );
375 UInt numPoints = M_localMap_u.map (Unique)->NumGlobalElements();
376 UInt numGlobalElements = M_localMapVec.map (Unique)->NumGlobalElements();
377 std::vector<Real> fiberGlobalVector (numGlobalElements);
380 fibers.getline (line, 1024);
381 for (
UInt i = 0; i < numPoints; ++i)
382 for (
UInt k = 0; k < 3; ++k)
384 fibers >> fiberGlobalVector[i + k * numPoints];
389 for (
UInt i = 0 ; i < numGlobalElements; ++i)
391 fibers >> fiberGlobalVector[i];
394 UInt numMyElements = M_localMapVec.map (Repeated)->NumMyElements();
395 for (
UInt j = 0; j < numMyElements; ++j)
397 UInt ig = M_localMapVec.map (Repeated)->MyGlobalElements() [j];
398 M_fiberVector[ig] = fiberGlobalVector[ig];
400 std::cout << std::endl;
401 fiberGlobalVector.clear();
405 template<
typename Mesh,
typename SolverType>
411 template<
typename Mesh,
typename SolverType>
414 M_diagonalize = dataFile
( "electric/space_discretization/diagonalize", 1.
);
416 M_linearSolver.setCommunicator (M_comm);
419 std::string precType = dataFile
( "electric/prec/prectype", "Ifpack");
420 M_prec.reset ( PRECFactory::instance().createObject ( precType ) );
421 ASSERT (M_prec.get() != 0,
"bidomainSolver : Preconditioner not set");
422 M_prec->setDataFromGetPot ( dataFile,
"electric/prec" );
425 template<
typename Mesh,
typename SolverType>
428 M_matrMass.reset (
new matrix_Type (M_localMap) );
429 M_matrStiff.reset (
new matrix_Type (M_localMap) );
433 std::cout <<
" f- Computing constant matrices ... ";
440 Chrono chronoStiffAssemble;
441 Chrono chronoMassAssemble;
450 for (
UInt iVol = 0; iVol <
M_pFESpace.mesh()->numVolumes(); iVol++ )
466 stiff ( M_data.longitudinalInternalConductivity(),
467 M_data.transversalInternalConductivity(),
471 M_pFESpace.dof(), 0, 0);
472 stiff ( M_data.longitudinalExternalConductivity(),
473 M_data.transversalExternalConductivity(),
477 M_pFESpace.dof(), 1, 1);
481 stiff ( M_data.internalDiffusivity(), M_elmatStiff, M_pFESpace.fe(), 0, 0 );
482 stiff ( M_data.externalDiffusivity(), M_elmatStiff, M_pFESpace.fe(), 1, 1 );
491 stiff ( M_data.M_reducedConductivitySphere, M_data.longitudinalInternalConductivity(),
492 M_data.transversalInternalConductivity(),
493 M_fiberVector, M_elmatStiff, M_pFESpace.fe(), M_pFESpace.dof(), 0, 0, 0);
494 stiff ( M_data.M_reducedConductivitySphere, M_data.longitudinalExternalConductivity(),
495 M_data.transversalExternalConductivity(),
496 M_fiberVector, M_elmatStiff, M_pFESpace.fe(), M_pFESpace.dof(), 1, 1, 1);
500 stiff ( M_data.M_reducedConductivitySphere, M_data.internalDiffusivity(),
501 M_elmatStiff, M_pFESpace.fe(), M_pFESpace.dof(), 0, 0, 0);
502 stiff ( M_data.M_reducedConductivitySphere, M_data.externalDiffusivity(),
503 M_elmatStiff, M_pFESpace.fe(), M_pFESpace.dof(), 1, 1, 1);
512 stiff ( M_data.M_reducedConductivityCylinder, M_data.longitudinalInternalConductivity(),
513 M_data.transversalInternalConductivity(), M_fiberVector,
514 M_elmatStiff, M_pFESpace.fe(), M_pFESpace.dof(), 0, 0, 0);
515 stiff ( M_data.M_reducedConductivityCylinder, M_data.longitudinalExternalConductivity(),
516 M_data.transversalExternalConductivity(), M_fiberVector,
517 M_elmatStiff, M_pFESpace.fe(), M_pFESpace.dof(), 1, 1, 1);
521 stiff ( M_data.M_reducedConductivityCylinder, M_data.internalDiffusivity(),
522 M_elmatStiff, M_pFESpace.fe(), M_pFESpace.dof(), 0, 0 , 0);
523 stiff ( M_data.M_reducedConductivityCylinder, M_data.externalDiffusivity(),
524 M_elmatStiff, M_pFESpace.fe(), M_pFESpace.dof(), 1, 1, 1);
533 stiff ( M_data.M_reducedConductivityBox, M_data.longitudinalInternalConductivity(),
534 M_data.transversalInternalConductivity(), M_fiberVector, M_elmatStiff,
535 M_pFESpace.fe(), M_pFESpace.dof(), 0, 0, 0);
536 stiff ( M_data.M_reducedConductivityBox, M_data.longitudinalExternalConductivity(),
537 M_data.transversalExternalConductivity(), M_fiberVector, M_elmatStiff,
538 M_pFESpace.fe(), M_pFESpace.dof(), 1, 1, 1);
542 stiff ( M_data.M_reducedConductivityBox, M_data.internalDiffusivity(),
543 M_elmatStiff, M_pFESpace.fe(), M_pFESpace.dof(), 0, 0, 0 );
544 stiff ( M_data.M_reducedConductivityBox, M_data.externalDiffusivity(),
545 M_elmatStiff, M_pFESpace.fe(), M_pFESpace.dof(), 1, 1, 1 );
552 mass ( 1., M_elmatMass, M_pFESpace.fe(), 0, 0 );
553 mass ( -1., M_elmatMass, M_pFESpace.fe(), 0, 1 );
554 mass ( -1., M_elmatMass, M_pFESpace.fe(), 1, 0 );
555 mass ( 1., M_elmatMass, M_pFESpace.fe(), 1, 1 );
558 chronoStiffAssemble.start();
559 for (
UInt iComp = 0; iComp <
nbComp; iComp++ )
561 assembleMatrix ( *M_matrStiff,
568 iComp * potentialFESpaceDimension(), iComp * potentialFESpaceDimension() );
570 chronoStiffAssemble.stop();
572 chronoMassAssemble.start();
573 for (
UInt iComp = 0; iComp <
nbComp; iComp++ )
575 for (
UInt jComp = 0; jComp <
nbComp; jComp++ )
577 assembleMatrix ( *M_matrMass,
584 iComp * potentialFESpaceDimension(), jComp * potentialFESpaceDimension() );
587 chronoMassAssemble.stop();
598 std::cout <<
"done in " << chrono.diff() <<
" s.\n" << std::flush;
602 std::cout <<
" f- Finalizing the matrices ... " << std::flush;
606 M_matrStiff->globalAssemble();
607 M_matrMass->globalAssemble();
610 M_matrNoBC.reset (
new matrix_Type (M_localMap, M_matrStiff->meanNumEntries() ) );
613 *M_matrNoBC += *M_matrStiff;
614 *M_matrNoBC += *M_matrMass * massCoeff;
615 M_matrNoBC->globalAssemble();
619 std::cout <<
"done in " << chrono.diff() <<
" s." << std::endl;
623 std::cout <<
"partial times: \n" 624 <<
" Der " << chronoDer.diff_cumul() <<
" s.\n" 625 <<
" Zero " << chronoZero.diff_cumul() <<
" s.\n" 626 <<
" Stiff " << chronoStiff.diff_cumul() <<
" s.\n" 627 <<
" Stiff Assemble " << chronoStiffAssemble.diff_cumul() <<
" s.\n" 628 <<
" Mass " << chronoMass.diff_cumul() <<
" s.\n" 629 <<
" Mass Assemble " << chronoMassAssemble.diff_cumul() <<
" s.\n" 632 template<
typename Mesh,
typename SolverType>
640 M_uFESpace.interpolate (ui0, intracellularPotential, 0.);
641 M_uFESpace.interpolate (ue0, extracellularPotential, 0.);
642 initialize (intracellularPotential, extracellularPotential);
645 template<
typename Mesh,
typename SolverType>
652 M_uFESpace.interpolate (ui0, intracellularPotential, 0.);
653 M_uFESpace.interpolate (ue0, extracellularPotential, 0.);
654 initialize (intracellularPotential, extracellularPotential);
657 template<
typename Mesh,
typename SolverType>
678 template<
typename Mesh,
typename SolverType>
685 std::cout <<
" f- Updating mass term and right hand side... " 697 std::cout <<
"done in " << chrono.diff() <<
" s.\n" << std::flush;
708 std::cout <<
" f- Copying the matrices ... " 713 M_matrNoBC.reset (
new matrix_Type (M_localMap, M_matrStiff->meanNumEntries() ) );
715 *M_matrNoBC += *M_matrStiff;
717 *M_matrNoBC += *M_matrMass * alpha;
720 if (M_verbose) std::cout <<
"done in " << chrono.diff() <<
" s.\n" 724 M_matrNoBC->globalAssemble();
727 template<
typename Mesh,
typename SolverType>
735 std::cout <<
" f- Updating right hand side... " 745 std::cout <<
"done in " << chrono.diff() <<
" s.\n" << std::flush;
749 template<
typename Mesh,
typename SolverType>
762 std::cout <<
"done in " << chrono.diff() <<
" s.\n" 767 if (M_verbose) std::cout <<
" f- Applying boundary conditions ... " 771 applyBoundaryConditions ( *matrFull, rhsFull, bch);
779 std::cout <<
"done in " << chrono.diff() <<
" s.\n" << std::flush;
783 solveSystem ( matrFull, rhsFull );
791 template<
typename Mesh,
typename SolverType>
799 std::cout <<
" f- Setting up the solver ... ";
803 M_linearSolver.setMatrix (*matrFull);
807 std::cout <<
"done in " << chrono.diff() <<
" s.\n" 816 std::cout <<
" f- Computing the precond ... ";
818 M_prec->buildPreconditioner (matrFull);
827 std::cout <<
"done in " << chrono.diff() <<
" s.\n";
828 std::cout <<
" Estimated condition number = " << condest <<
"\n" << std::flush;
837 std::cout <<
" f- Reusing precond ... \n" << std::flush;
845 std::cout <<
" f- Solving system ... ";
854 std::cout <<
"\ndone in " << chrono.diff()
855 <<
" s. ( " << numIter <<
" iterations. ) \n" 889 template<
typename Mesh,
typename SolverType>
895 if ( !BCh.bdUpdateDone() )
897 BCh.bdUpdate ( *M_pFESpace.mesh(), M_pFESpace.feBd(), M_pFESpace.dof() );
918 template<
typename Mesh,
typename SolverType>
921 Real meanExtraPotential (0.);
922 x.epetraVector().MeanValue (&meanExtraPotential);
923 return meanExtraPotential;
926 template<
typename Mesh,
typename SolverType>
929 for (
Int i = 0 ; i < x.epetraVector().MyLength() ; i++ )
931 Int ig = x.blockMap().MyGlobalElements() [i];
void initialize(const Function &, const Function &)
bool M_verbose
Boolean that indicates if output is sent to cout.
void initialize(const source_Type &, const source_Type &)
Initialize.
HeartBidomainData data_type
double operator()(const char *VarName, const double &Default) const
SolverType::vector_type vector_Type
SolverType M_linearSolver
Solver.
bool M_updated
Boolean that indicates if the matrix is updated for the current iteration.
void removeValue(vector_Type &x, Real &value)
removes a scalar from each entry of vector x
void setBC(BCHandler &BCh_u)
Sets Bidomain BCs.
MatrixElemental M_elmatStiff
Elementary matrices.
const bool & hasFibers() const
const vector_Type & residual() const
Returns the local residual vector.
Int M_maxIterSolver
Integer storing the max number of solver iteration with prec recomputing.
MatrixElemental M_elmatMass
virtual void setup(const GetPot &dataFile)
Sets up the system solver.
BCHandler - class for handling boundary conditions.
vector_Type M_solutionExtraPotential
const Real & membraneCapacitance() const
Cm.
FESpace< Mesh, MapEpetra > & M_pFESpace
u FE space
const vector_Type & solutionExtraPotential() const
int32_type Int
Generic integer data.
bool M_recomputeMatrix
Boolean that indicates if the matrix has to be recomputed.
std::function< Real(const Real &, const Real &, const Real &, const Real &, const ID &) > source_Type
bool hasOnlyEssential() const
Determine whether all the stored boundary conditions have EssentialXXX type.
vector_Type M_solutionTransmembranePotentialExtrapolated
FESpace< Mesh, MapEpetra > & potentialFESpace()
Returns u FE space.
matrixPtr_Type M_matrNoBC
matrixPtr_Type M_matrMass
mass matrix
void resetPreconditioner()
TimeAdvanceBDF< vector_Type > M_BDFIntraExtraPotential
virtual void buildSystem()
Builds time independent parts of PDE system.
Epetra_Import const & importer()
Getter for the Epetra_Import.
const Real & volumeSurfaceRatio() const
Chi.
HeartBidomainSolver(const data_type &dataType, FESpace< Mesh, MapEpetra > &pFESpace, FESpace< Mesh, MapEpetra > &uFESpace, BCHandler &bcHandler, std::shared_ptr< Epetra_Comm > &comm)
Constructor.
const data_type & M_data
Data.
virtual void PDEiterate(bchandlerRaw_Type &bch)
Updates sources, bc treatment and solve the bidomain system.
const std::shared_ptr< Epetra_Comm > M_comm
MPI communicator.
bool M_resetPreconditioner
vector_Type M_solutionIntraExtraPotential
Global solution _u.
const vector_Type & solutionIntraExtraPotential() const
vector_Type M_solutionTransmembranePotential
class TimeAdvanceBDF - Backward differencing formula time discretization for the first and the second...
void solveSystem(matrixPtr_Type matrFull, vector_Type &rhsFull)
Solves PDE system.
virtual void updatePDESystem(vector_Type &sourceVec)
Updates time dependent parts of PDE system.
const bool & fibersFormat() const
format vct
double Real
Generic real data.
bool M_reusePrec
Boolean that indicates if the precond has to be recomputed.
int operator()(const char *VarName, int Default) const
SolverType::prec_raw_type precRaw_Type
matrixPtr_Type M_matrStiff
Stiff matrix: D*stiff.
virtual ~HeartBidomainSolver()
Destructor.
virtual void updatePDESystem(Real alpha, vector_Type &sourceVec)
Updates time dependent parts of PDE system.
const std::string operator()(const char *VarName, const char *Default) const
vector_Type M_rhsNoBC
Right hand side for the PDE.
vector_Type M_solutionIntraExtraPotentialExtrapolated
SolverType::matrix_type matrix_Type
UInt potentialFESpaceDimension() const
BCHandler bchandlerRaw_Type
BCHandler * M_BCh_electric
Bidomain BC.
bool operator()(const char *VarName, bool Default) const
vector_Type M_residual
residual
FESpace< Mesh, MapEpetra > & M_uFESpace
void initialize(const vector_Type &, const vector_Type &)
vector_Type M_fiberVector
Local fibers vector.
const vector_Type & fiberVector() const
const UInt nbComp
BidomainSolver - This class implements a bidomain solver.
std::shared_ptr< matrix_Type > matrixPtr_Type
Real computeMean(vector_Type &x)
compute mean of vector x
SolverType::prec_type prec_Type
uint32_type UInt
generic unsigned integer (used mainly for addressing)
const vector_Type & solutionTransmembranePotentialExtrapolated() const
const Int & heartDiffusionFactor() const
const vector_Type & solutionTransmembranePotential() const
Returns the local solution vector.
void applyBoundaryConditions(matrix_Type &matrix, vector_Type &rhs, bchandlerRaw_Type &BCh)
Apply BC.