39 #pragma GCC diagnostic ignored "-Wunused-variable" 40 #pragma GCC diagnostic ignored "-Wunused-parameter" 42 #include <Epetra_ConfigDefs.h> 45 #include <Epetra_MpiComm.h> 47 #include <Epetra_SerialComm.h> 51 #pragma GCC diagnostic warning "-Wunused-variable" 52 #pragma GCC diagnostic warning "-Wunused-parameter" 59 #include <lifev/core/array/VectorSmall.hpp> 61 #include <lifev/core/array/VectorEpetra.hpp> 62 #include <lifev/core/array/MatrixEpetra.hpp> 63 #include <lifev/core/array/MapEpetra.hpp> 64 #include <lifev/core/mesh/MeshData.hpp> 65 #include <lifev/core/mesh/MeshPartitioner.hpp> 66 #include <lifev/core/filter/ExporterEnsight.hpp> 67 #include <lifev/core/filter/ExporterHDF5.hpp> 68 #include <lifev/core/filter/ExporterEmpty.hpp> 70 #include <lifev/core/algorithm/LinearSolver.hpp> 71 #include <lifev/electrophysiology/solver/ElectroETAMonodomainSolver.hpp> 73 #include <lifev/core/filter/ExporterEnsight.hpp> 75 #include <lifev/core/filter/ExporterHDF5.hpp> 77 #include <lifev/core/filter/ExporterEmpty.hpp> 79 #include <lifev/electrophysiology/solver/IonicModels/IonicAlievPanfilov.hpp> 80 #include <lifev/electrophysiology/solver/IonicModels/IonicMinimalModel.hpp> 81 #include <lifev/core/LifeV.hpp> 83 #include <Teuchos_RCP.hpp> 84 #include <Teuchos_ParameterList.hpp> 85 #include "Teuchos_XMLParameterListHelpers.hpp" 92 #include <lifev/eta/fem/ETFESpace.hpp> 93 #include <lifev/eta/expression/Integrate.hpp> 98 #include <lifev/electrophysiology/examples/example_ECG/Norm.hpp> 99 #include <lifev/core/solver/ADRAssembler.hpp> 100 #include <lifev/core/algorithm/LinearSolver.hpp> 101 #include <lifev/core/algorithm/PreconditionerML.hpp> 114 using namespace LifeV;
119 Teuchos::ParameterList monodomainList = * ( Teuchos::getParametersFromXmlFile (
"MonodomainSolverParamList.xml" ) );
121 Real zmax = monodomainList.get (
"domain_Z", 1. );
122 Real L = zmax - zmin;
126 Real ztheta = (L - z) / L;
127 Real theta = (thetamax - thetamin) * ztheta + thetamin;
132 return std::cos (theta);
135 return std::sin (theta);
148 Teuchos::ParameterList monodomainList = * ( Teuchos::getParametersFromXmlFile (
"MonodomainSolverParamList.xml" ) );
149 Real pacingSite_X = monodomainList.get (
"pacingSite_X", 0.);
150 Real pacingSite_Y = monodomainList.get (
"pacingSite_Y", 0.);
151 Real pacingSite_Z = monodomainList.get (
"pacingSite_Z", 0. );
152 Real stimulusRadius = 0.1;
154 if ( ( ( x - pacingSite_X ) * ( x - pacingSite_X ) + ( y - pacingSite_Y ) * ( y - pacingSite_Y ) + ( z - pacingSite_Z ) * ( z - pacingSite_Z ) )
155 <= ( stimulusRadius * stimulusRadius ) )
168 Teuchos::ParameterList monodomainList = * ( Teuchos::getParametersFromXmlFile (
"MonodomainSolverParamList.xml" ) );
169 Real pacingSite_X = monodomainList.get (
"pacingSite_X", 0.);
170 Real pacingSite_Y = monodomainList.get (
"pacingSite_Y", 0.);
171 Real pacingSite_Z = monodomainList.get (
"pacingSite_Z", 1.);
172 Real stimulusRadius = monodomainList.get (
"stimulusRadius", 0.1);
173 Real stimulusValue = monodomainList.get (
"stimulusValue", 1.);
179 std::vector<
double> returnPeriods;
180 std::vector<
double> returnStimulusTime;
182 if ( ( ( x - pacingSite_X ) * ( x - pacingSite_X ) + ( y - pacingSite_Y ) * ( y - pacingSite_Y ) + ( z - pacingSite_Z ) * ( z - pacingSite_Z ) )
183 <= ( stimulusRadius * stimulusRadius ) )
185 returnValue1 = stimulusValue;
192 Real returnValue = returnValue1;
200 MPI_Init (&argc, &argv);
202 std::shared_ptr<Epetra_Comm> Comm (
new Epetra_MpiComm (MPI_COMM_WORLD) );
203 if ( Comm->MyPID() == 0 )
205 std::cout <<
"% using MPI" << std::endl;
214 typedef RegionMesh<LinearTetra> mesh_Type;
215 typedef std::shared_ptr<mesh_Type> meshPtr_Type;
216 typedef std::shared_ptr<VectorEpetra> vectorPtr_Type;
218 typedef std::shared_ptr<feSpace_Type> feSpacePtr_Type;
219 typedef std::function < Real (
const Real& ,
223 const ID& ) > function_Type;
226 typedef LifeV::Preconditioner basePrec_Type;
227 typedef std::shared_ptr<basePrec_Type> basePrecPtr_Type;
228 typedef LifeV::PreconditionerML prec_Type;
229 typedef std::shared_ptr<prec_Type> precPtr_Type;
231 typedef std::shared_ptr< monodomainSolver_Type > monodomainSolverPtr_Type;
233 typedef std::shared_ptr< LifeV::Exporter<LifeV::RegionMesh<LifeV::LinearTetra> > > filterPtr_Type;
234 typedef LifeV::ExporterHDF5< RegionMesh<LinearTetra> > hdf5Filter_Type;
235 typedef std::shared_ptr<hdf5Filter_Type> hdf5FilterPtr_Type;
236 typedef ExporterData<mesh_Type> exporterData_Type;
237 typedef Exporter< mesh_Type > IOFile_Type;
238 typedef std::shared_ptr< IOFile_Type > IOFilePtr_Type;
239 typedef ExporterHDF5< mesh_Type > hdf5IOFile_Type;
247 if ( Comm->MyPID() == 0 )
249 std::cout <<
"Importing parameters list...";
251 Teuchos::ParameterList monodomainList = * ( Teuchos::getParametersFromXmlFile (
"MonodomainSolverParamList.xml" ) );
252 if ( Comm->MyPID() == 0 )
254 std::cout <<
" Done!" << std::endl;
263 if ( Comm->MyPID() == 0 )
265 std::cout <<
"Building Constructor for Aliev Panfilov Model with parameters ... ";
267 std::shared_ptr<IonicMinimalModel> model (
new IonicMinimalModel() );
268 if ( Comm->MyPID() == 0 )
270 std::cout <<
" Done!" << std::endl;
277 std::string meshName = monodomainList.get (
"mesh_name",
"lid16.mesh");
278 std::string meshPath = monodomainList.get (
"mesh_path",
"./");
285 const std::string data_file_name = command_line.follow (
"data", 2,
"-f",
"--file");
286 GetPot dataFile (data_file_name);
291 if ( Comm->MyPID() == 0 )
293 std::cout << std::endl <<
"[Loading the mesh]" << std::endl;
296 meshPtr_Type fullMeshPtr (
new mesh_Type ( Comm ) );
298 std::vector<Real> meshDim (3, 0);
299 meshDim[0] = monodomainList.get (
"meshDim_X", 10 );
300 meshDim[1] = monodomainList.get (
"meshDim_Y", 10 );
301 meshDim[2] = monodomainList.get (
"meshDim_Z", 10 );
302 std::vector<Real> domain (3, 0);
303 domain[0] = monodomainList.get (
"domain_X", 1. );
304 domain[1] = monodomainList.get (
"domain_Y", 1. );
305 domain[2] = monodomainList.get (
"domain_Z", 1. );
308 regularMesh3D ( *fullMeshPtr,
310 meshDim[0], meshDim[1], meshDim[2],
312 domain[0], domain[1], domain[2],
315 if ( Comm->MyPID() == 0 )
317 std::cout <<
"Mesh size : " << MeshUtility::MeshStatistics::computeSize ( *fullMeshPtr ).maxH << std::endl;
319 if ( Comm->MyPID() == 0 )
321 std::cout <<
"Partitioning the mesh ... " << std::endl;
323 meshPtr_Type meshPtr;
326 meshPtr = meshPart.meshPartition();
334 if ( Comm->MyPID() == 0 )
336 std::cout <<
"Building Monodomain Solvers... ";
339 monodomainSolverPtr_Type splitting (
new monodomainSolver_Type ( dataFile, model, meshPtr ) );
340 const feSpacePtr_Type FESpacePtr = splitting->feSpacePtr();
342 if ( Comm->MyPID() == 0 )
344 std::cout <<
" Splitting solver done... ";
347 function_Type pacing = &PacingProtocol;
348 function_Type f = &Stimulus2;
416 if ( Comm->MyPID() == 0 )
418 std::cout <<
"\nInitializing potential: " ;
422 splitting -> setPotentialFromFunction ( f );
424 * ( splitting -> globalSolution().at (1) ) = 1.0;
425 * ( splitting -> globalSolution().at (2) ) = 1.0;
426 * ( splitting -> globalSolution().at (3) ) = 0.021553043080281;
430 sz = (* (splitting->globalSolution().at (0) ) ).size();
431 Real threshold = monodomainList.get (
"threshold", 0.1);
433 vector_Type tact = (* (splitting->globalSolution().at (0) ) );
435 vector_Type apd = tact;
436 vector_Type delta_apd = tact;
437 vector_Type previouspotential = (* (splitting->globalSolution().at (0) ) );
441 if ( Comm->MyPID() == 0 )
443 std::cout <<
"Done! \n" ;
449 bool PacingProtocol = monodomainList.get (
"pacingProtocol",
false);
450 std::vector<
double> returnStimulusTime;
451 std::vector<
double> returnPeriods;
453 Real stimulusStart = monodomainList.get (
"stimulusStart", 0.);
454 Real stimulusStop = monodomainList.get (
"stimulusStop", 0.05);
456 Int NumberPacingPeriods;
462 Real pacingPeriod = monodomainList.get (
"pacingPeriod", 500.);
463 Real pacingPeriodMin = monodomainList.get (
"pacingPeriodMin", 400.);
464 Real pacingDelta = monodomainList.get (
"pacingDelta", 0.);
465 stimulusNumber = monodomainList.get (
"stimulusNumber", 1);
466 NumberPacingPeriods = (pacingPeriod - pacingPeriodMin) / pacingDelta;
468 if ( pacingDelta > 0 )
470 for (
int k = 0; k <= NumberPacingPeriods - 1; k++ )
472 for (i = stimulusNumber * k; i <= stimulusNumber * (k + 1) - 1; i++)
474 returnPeriods.push_back ( pacingPeriod - k * pacingDelta );
477 returnStimulusTime.push_back ( returnPeriods[0] );
481 returnStimulusTime.push_back ( returnStimulusTime[i - 1] + returnPeriods[i] );
489 returnPeriods.push_back ( monodomainList.get (
"stimulus0", 500.) );
490 returnPeriods.push_back ( monodomainList.get (
"stimulus1", 450.) );
491 returnPeriods.push_back ( monodomainList.get (
"stimulus2", 425.) );
492 returnPeriods.push_back ( monodomainList.get (
"stimulus3", 400.) );
493 returnPeriods.push_back ( monodomainList.get (
"stimulus4", 375.) );
494 returnPeriods.push_back ( monodomainList.get (
"stimulus5", 350.) );
495 returnPeriods.push_back ( monodomainList.get (
"stimulus6", 325.) );
496 returnPeriods.push_back ( monodomainList.get (
"stimulus7", 300.) );
497 returnPeriods.push_back ( monodomainList.get (
"stimulus8", 275.) );
498 returnPeriods.push_back ( monodomainList.get (
"stimulus9", 275.) );
499 returnPeriods.push_back ( monodomainList.get (
"stimulus10", 275.) );
500 returnPeriods.push_back ( monodomainList.get (
"stimulus11", 275.) );
501 returnPeriods.push_back ( monodomainList.get (
"stimulus12", 450.) );
502 returnPeriods.push_back ( monodomainList.get (
"stimulus13", 400.) );
503 returnPeriods.push_back ( monodomainList.get (
"stimulus14", 375.) );
504 returnPeriods.push_back ( monodomainList.get (
"stimulus15", 350.) );
505 returnPeriods.push_back ( monodomainList.get (
"stimulus16", 325.) );
506 returnPeriods.push_back ( monodomainList.get (
"stimulus17", 300.) );
507 returnPeriods.push_back ( monodomainList.get (
"stimulus18", 275.) );
508 returnPeriods.push_back ( monodomainList.get (
"stimulus19", 275.) );
509 returnPeriods.push_back ( monodomainList.get (
"stimulus20", 275.) );
510 returnPeriods.push_back ( monodomainList.get (
"stimulus21", 275.) );
511 returnPeriods.push_back ( monodomainList.get (
"stimulus22", 450.) );
512 returnPeriods.push_back ( monodomainList.get (
"stimulus23", 400.) );
513 returnPeriods.push_back ( monodomainList.get (
"stimulus24", 375.) );
514 returnPeriods.push_back ( monodomainList.get (
"stimulus25", 350.) );
515 returnPeriods.push_back ( monodomainList.get (
"stimulus26", 325.) );
516 returnPeriods.push_back ( monodomainList.get (
"stimulus27", 300.) );
517 returnPeriods.push_back ( monodomainList.get (
"stimulus28", 275.) );
518 returnPeriods.push_back ( monodomainList.get (
"stimulus29", 275.) );
519 returnPeriods.push_back ( monodomainList.get (
"stimulus30", 275.) );
521 NumberPacingPeriods = monodomainList.get (
"NbStimulusPeriod", 12);
524 for (
int k = 0; k <= NumberPacingPeriods - 1; k++ )
528 returnStimulusTime.push_back ( returnPeriods[0] );
532 returnStimulusTime.push_back ( returnStimulusTime[k - 1] + returnPeriods[k] );
539 Real ecg_position_X = monodomainList.get (
"ecg_position_X", 1.);
540 Real ecg_position_Y = monodomainList.get (
"ecg_position_Y", 1.);
541 Real ecg_position_Z = monodomainList.get (
"ecg_position_Z", 0.5);
542 vector_Type ecgDistance = (* (splitting->globalSolution().at (0) ) ) ;
544 FESpacePtr->interpolate (
static_cast<function_Type> ( Norm::f ), ecgDistance, 0.0 );
547 Real pseudoEcgReal (0.);
548 Real Global_pseudoEcgReal (0.);
549 vector_Type solutionLaplacian = ( (* (splitting->globalSolution().at (0) ) ) );
550 vector_Type pseudoEcgVec = ( (* (splitting->globalSolution().at (0) ) ) );
554 ADRAssembler<mesh_Type, matrix_Type, vector_Type> adrAssembler;
555 adrAssembler.setup ( FESpacePtr, FESpacePtr );
557 std::shared_ptr<matrix_Type> systemMatrixL (
new matrix_Type ( FESpacePtr->map() ) );
558 std::shared_ptr<matrix_Type> systemMatrixM (
new matrix_Type ( FESpacePtr->map() ) );
559 std::shared_ptr<vector_Type> rhs_Laplacian (
new vector_Type ( FESpacePtr->map() ) );
560 std::shared_ptr<vector_Type> pseudoEcgVec_ptr (
new vector_Type ( FESpacePtr->map() ) );
563 adrAssembler.addDiffusion ( systemMatrixL, -1.0 );
564 adrAssembler.addMass ( systemMatrixM, 1.0 );
566 systemMatrixL->globalAssemble();
567 systemMatrixM->globalAssemble();
577 splitting -> setParameters ( monodomainList );
583 fibers[0] = monodomainList.get (
"fiber_X", std::sqrt (2.0) / 2.0 );
584 fibers[1] = monodomainList.get (
"fiber_Y", std::sqrt (2.0) / 2.0 );
585 fibers[2] = monodomainList.get (
"fiber_Z", 0.0 );
587 splitting ->setupFibers (fibers);
592 splitting -> setupLumpedMassMatrix();
593 splitting -> setupStiffnessMatrix();
594 splitting -> setupGlobalMatrix();
599 ExporterHDF5< RegionMesh <LinearTetra> > exporterSplitting;
600 std::string filenameSplitting = monodomainList.get (
"OutputFile",
"MinMod" );
601 filenameSplitting +=
"Splitting";
602 splitting -> setupPotentialExporter ( exporterSplitting, filenameSplitting );
604 ExporterHDF5< RegionMesh <LinearTetra> > exporterSplittingRestart;
605 std::string filenameSplittingLast = monodomainList.get (
"OutputFile",
"MinMod" );
606 filenameSplittingLast +=
"RESTART";
607 splitting -> setupExporter ( exporterSplittingRestart, filenameSplittingLast );
609 vectorPtr_Type APDptr (
new vector_Type (apd, Repeated ) );
610 exporterSplitting.addVariable ( ExporterData<mesh_Type>::ScalarField,
"apd", FESpacePtr,
613 vectorPtr_Type DELTA_APDptr (
new vector_Type (delta_apd, Repeated ) );
614 exporterSplitting.addVariable ( ExporterData<mesh_Type>::ScalarField,
"delta_apd", FESpacePtr,
615 DELTA_APDptr, UInt (0) );
618 *DELTA_APDptr = delta_apd;
620 std::ofstream output (
"ecg_output.txt");
625 if ( Comm->MyPID() == 0 )
627 std::cout << std::endl <<
"[Solvers initialization]" << std::endl;
629 prec_Type* precRawPtr;
630 basePrecPtr_Type precPtr;
631 precRawPtr =
new prec_Type;
632 precRawPtr->setDataFromGetPot ( dataFile,
"prec" );
633 precPtr.reset ( precRawPtr );
634 if ( Comm->MyPID() == 0 )
636 std::cout <<
"Setting up LinearSolver (Belos)... " << std::flush;
638 Teuchos::RCP< Teuchos::ParameterList > belosList2 = Teuchos::rcp (
new Teuchos::ParameterList );
639 belosList2 = Teuchos::getParametersFromXmlFile (
"SolverParamList2.xml" );
640 LinearSolver linearSolver2;
641 linearSolver2.setCommunicator ( Comm );
642 linearSolver2.setParameters ( *belosList2 );
643 linearSolver2.setPreconditioner ( precPtr );
644 if ( Comm->MyPID() == 0 )
646 std::cout <<
"done" << std::endl;
648 linearSolver2.showMe();
653 if ( Comm->MyPID() == 0 )
655 std::cout <<
"\nstart solving: " ;
658 Real Savedt = monodomainList.get (
"saveStep", 0.1);
659 Real timeStep = monodomainList.get (
"timeStep", 0.01);
660 Real endTime = monodomainList.get (
"endTime", 10.);
661 Real initialTime = monodomainList.get (
"initialTime", 0.);
663 vectorPtr_Type previousPotential0Ptr (
new vector_Type ( FESpacePtr->map() ) );
664 * (previousPotential0Ptr) = * (splitting->globalSolution().at (0) );
666 int iter ( (Savedt / timeStep) + 1e-9);
667 int iterRestart ( (500 / timeStep) + 1e-9);
670 if (endTime > timeStep)
672 for (Real t = initialTime; t < endTime;)
676 previouspotential = (* (splitting->globalSolution().at (0) ) );
680 pseudoEcgVec_ptr.reset (
new vector_Type ( FESpacePtr->map(), Unique ) );
681 rhs_Laplacian.reset (
new vector_Type ( FESpacePtr->map(), Unique ) );
687 for (i = 0; i <= NumberPacingPeriods * stimulusNumber - 1; i++)
691 if ( (t >= (returnStimulusTime[i] + stimulusStart) && t <= (returnStimulusTime[i] + stimulusStop + timeStep) ) )
693 splitting -> setAppliedCurrentFromFunction ( pacing );
694 std::cout <<
"stim_time " << t << std::endl;
695 control = control + 1;
699 splitting -> initializeAppliedCurrent();
707 splitting->solveOneReactionStepFE();
708 (* (splitting->rhsPtrUnique() ) ) *= 0;
709 splitting->updateRhs();
710 splitting->solveOneDiffusionStepBE();
711 splitting->exportSolution (exporterSplitting, t);
715 * (previousPotential0Ptr) = * (splitting->globalSolution().at (0) );
716 splitting->solveOneReactionStepFE (2);
717 (* (splitting->rhsPtrUnique() ) ) *= 0;
718 splitting->updateRhs();
719 splitting->solveOneDiffusionStepBDF2 (previousPotential0Ptr);
720 splitting->solveOneReactionStepFE (2);
723 splitting->exportSolution (exporterSplitting, t);
725 if (k % iterRestart == 0)
727 splitting->exportSolution (exporterSplittingRestart, t);
733 (*rhs_Laplacian) = (*systemMatrixL) * (* (splitting->globalSolution().at (0) ) );
735 linearSolver2.setOperator ( systemMatrixM );
736 linearSolver2.setRightHandSide ( rhs_Laplacian );
737 linearSolver2.solve ( pseudoEcgVec_ptr );
739 pseudoEcgVec = (*pseudoEcgVec_ptr) / ecgDistance;
742 for (
int i = 0; i <= sz - 1; i++)
744 if ( (* (splitting->globalSolution().at (0) ) ).isGlobalIDPresent (i) )
747 if ( ( previouspotential[i] < threshold ) && ( (* (splitting->globalSolution().at (0) ) ) [i] >= threshold ) )
749 tact[i] = t - ( (-threshold + previouspotential[i]) / ( (* (splitting->globalSolution().at (0) ) ) [i] - previouspotential[i]) ) * timeStep;
751 else if ( ( previouspotential[i] >= threshold ) && ( (* (splitting->globalSolution().at (0) ) ) [i] < threshold ) )
753 trep = t - ( (-threshold + previouspotential[i]) / ( (* (splitting->globalSolution().at (0) ) ) [i] - previouspotential[i]) ) * timeStep;
754 delta_apd[i] = (trep - tact[i]) - apd[i];
755 apd[i] = trep - tact[i];
759 pseudoEcgReal += pseudoEcgVec[i];
763 *DELTA_APDptr = delta_apd;
765 MPI_Allreduce (&pseudoEcgReal, &Global_pseudoEcgReal, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
767 if ( Comm->MyPID() == 0 )
769 output << Global_pseudoEcgReal <<
"\n";
773 splitting->exportSolution (exporterSplittingRestart, endTime);
774 exporterSplitting.closeFile();
779 splitting -> exportFiberDirection();
781 if ( Comm->MyPID() == 0 )
783 std::cout <<
"\nThank you for using ETA_MonodomainSolver.\nI hope to meet you again soon!\n All the best for your simulation :P\n " ;
785 MPI_Barrier (MPI_COMM_WORLD);
788 return ( EXIT_SUCCESS );
VectorEpetra - The Epetra Vector format Wrapper.
void assignFunction(bcBase_Type &base)
Assign the function to the base of the BCHandler.
Real Stimulus2(const Real &, const Real &x, const Real &y, const Real &z, const ID &)
Real Fibers(const Real &, const Real &, const Real &, const Real &z, const ID &i)
FESpace - Short description here please!
int main(int argc, char **argv)
GetPot(const int argc_, char **argv_, const char *FieldSeparator=0x0)
void importFromHDF5(std::string const &fileName, std::string const &matrixName="matrix")
Read a matrix from a HDF5 (.h5) file.
static void setPosition(const Real &xPosition, const Real &yPosition, const Real &zPosition)
IonicModel - This class implements an ionic model.
int32_type Int
Generic integer data.
Epetra_Import const & importer()
Getter for the Epetra_Import.
std::shared_ptr< std::vector< Int > > M_isOnProc
double Real
Generic real data.
ExporterHDF5< mesh_Type > hdf5IOFile_Type
Real PacingProtocol(const Real &, const Real &x, const Real &y, const Real &z, const ID &)
VectorEpetra & operator*=(const data_type &scalar)
Multiplication operator.