70 #include <lifev/electrophysiology/solver/ElectroETAMonodomainSolver.hpp> 96 #include <lifev/electrophysiology/testsuite/test_benchmark/benchmarkUtility.hpp> 106 #include <sys/stat.h> 112 using namespace LifeV;
121 #define finalActivationTime 53.1
132 MPI_Init (&argc, &argv);
133 std::shared_ptr<Epetra_Comm> Comm (
new Epetra_MpiComm (MPI_COMM_WORLD) );
134 if ( Comm->MyPID() == 0 )
136 std::cout <<
"% using MPI" << std::endl;
147 std::string problemFolder = commandLine.follow (
"Output", 2,
"-o",
"--output" );
149 if ( problemFolder.compare (
"./") )
151 problemFolder +=
"/";
153 if ( Comm->MyPID() == 0 )
155 mkdir ( problemFolder.c_str(), 0777 );
165 typedef RegionMesh<LinearTetra> mesh_Type;
168 typedef std::shared_ptr<vector_Type> vectorPtr_Type;
171 typedef std::shared_ptr<matrix_Type> matrixPtr_Type;
173 typedef std::function < Real (
const Real& ,
177 const ID& ) > function_Type;
179 typedef ElectroIonicModel ionicModel_Type;
180 typedef std::shared_ptr<ionicModel_Type> ionicModelPtr_Type;
182 typedef ElectroETAMonodomainSolver< mesh_Type, ionicModel_Type > monodomainSolver_Type;
183 typedef std::shared_ptr< monodomainSolver_Type > monodomainSolverPtr_Type;
193 if ( Comm->MyPID() == 0 )
202 if ( Comm->MyPID() == 0 )
204 std::cout <<
"Importing parameters list...";
206 Teuchos::ParameterList monodomainList = * ( Teuchos::getParametersFromXmlFile (
"MonodomainSolverParamList.xml" ) );
207 if ( Comm->MyPID() == 0 )
209 std::cout <<
" Done!" << std::endl;
233 std::string ionic_model ( monodomainList.get (
"ionic_model",
"minimalModel") );
234 if ( Comm->MyPID() == 0 )
236 std::cout <<
"\nIonic_Model:" << ionic_model;
238 ionicModelPtr_Type model;
239 Real activationThreshold = BenchmarkUtility::chooseIonicModel (model, ionic_model, *Comm );
249 std::string meshName = monodomainList.get (
"mesh_name",
"");
250 std::string meshPath = monodomainList.get (
"mesh_path",
"./");
273 if ( Comm->MyPID() == 0 )
275 std::cout <<
"\nBuilding Monodomain Solver ... \n";
278 monodomainSolverPtr_Type solver (
new monodomainSolver_Type ( meshName, meshPath, dataFile , model ) );
279 if ( Comm->MyPID() == 0 )
281 std::cout <<
"\t... solver created!";
293 if ( Comm->MyPID() == 0 )
295 std::cout <<
"\nInitializing potential and gating variables ... " ;
297 solver -> setInitialConditions();
298 if ( Comm->MyPID() == 0 )
300 std::cout <<
"Done!" ;
319 solver -> setParameters ( monodomainList );
331 if ( Comm->MyPID() == 0 )
333 std::cout <<
"\nSetting fibers ... " ;
340 solver -> setupFibers ( fibers );
342 if ( Comm->MyPID() == 0 )
344 std::cout <<
"Done!" ;
356 std::string solutionMethod = monodomainList.get (
"solutionMethod",
"splitting");
358 if ( Comm->MyPID() == 0 )
360 std::cout <<
"\nSolving the monodomain using " << solutionMethod;
380 if ( Comm->MyPID() == 0 )
382 std::cout <<
"\nSetup operators: \n" ;
387 bool lumpedMass = solver -> lumpedMassMatrix();
392 if (solutionMethod ==
"L-ICI" && !lumpedMass)
394 std::cout <<
"===============================================\n";
395 std::cout <<
"You are using L-ICI without lumping! You can't!\n";
396 std::cout <<
"This time I'm fixing it for you ... be careful.\n";
397 std::cout <<
"===============================================\n";
398 solver -> setLumpedMassMatrix (
true);
402 matrixPtr_Type fullMass;
406 if ( lumpedMass && solutionMethod ==
"ICI")
408 solver -> setLumpedMassMatrix (
false);
409 solver -> setupMassMatrix();
410 fullMass.reset (
new matrix_Type ( * (solver -> massMatrixPtr() ) ) );
411 solver -> setFullMassMatrixPtr (fullMass);
412 solver -> setLumpedMassMatrix (lumpedMass);
416 solver -> setupMassMatrix();
422 if ( !lumpedMass && solutionMethod ==
"ICI")
424 solver -> setFullMassMatrixPtr (solver -> massMatrixPtr() );
428 solver -> setupStiffnessMatrix ();
429 solver -> setupGlobalMatrix();
431 if ( Comm->MyPID() == 0 )
433 std::cout <<
"Done!" ;
448 if ( Comm->MyPID() == 0 )
450 std::cout <<
"\nSetting up the exporter ... " ;
452 ExporterHDF5< RegionMesh <LinearTetra> > exporter;
453 solver -> setupExporter ( exporter, monodomainList.get (
"OutputFile",
"Solution") , problemFolder);
454 if ( Comm->MyPID() == 0 )
456 std::cout <<
" exporting initial solution ... " ;
458 solver -> exportSolution ( exporter, 0);
471 vectorPtr_Type activationTimeVector (
new vector_Type ( solver -> potentialPtr() -> map() ) );
472 *activationTimeVector = -1.0;
474 ExporterHDF5< RegionMesh <LinearTetra> > activationTimeExporter;
475 activationTimeExporter.setMeshProcId (solver -> localMeshPtr(), solver -> commPtr() ->MyPID() );
476 activationTimeExporter.addVariable (ExporterData<mesh_Type>::ScalarField,
"Activation Time",
477 solver -> feSpacePtr(), activationTimeVector, UInt (0) );
478 activationTimeExporter.setPrefix (
"ActivationTime");
479 activationTimeExporter.setPostDir (problemFolder);
489 Real dt (solver -> timeStep() );
490 Int iter = monodomainList.get (
"saveStep", 1.0) / dt;
491 Int subiter = monodomainList.get (
"subiter", 10);
496 Real timeReacDiff = 0.0;
508 if ( Comm->MyPID() == 0 )
510 std::cout <<
"\nSetting up the external stimulus ... " ;
512 function_Type stimulus;
513 BenchmarkUtility::setStimulus (stimulus, ionic_model);
514 if ( Comm->MyPID() == 0 )
516 std::cout <<
"Done!" ;
525 if ( Comm->MyPID() == 0 )
527 std::cout <<
"\nMonodomain solver setup done in " << chronoinitialsettings.diff() <<
" s.";
535 if ( Comm->MyPID() == 0 )
537 std::cout <<
"\nstart solving: " ;
540 for ( Real t = solver -> initialTime(); t < solver -> endTime(); )
549 solver -> setAppliedCurrentFromFunction ( stimulus, t );
558 if ( solutionMethod ==
"splitting" )
572 if (ionic_model !=
"MinimalModel" && ionic_model !=
"AlievPanfilov" && ionic_model !=
"Fox")
574 solver->solveOneReactionStepRL();
578 for (
int j = 0; j < subiter; j++)
580 solver->solveOneReactionStepFE (subiter);
585 timeReac += chrono.globalDiff ( *Comm );
593 (*solver->rhsPtrUnique() ) *= 0.0;
598 solver->solveOneDiffusionStepBE();
600 timeDiff += chrono.globalDiff ( *Comm );
607 else if ( solutionMethod ==
"L-ICI" )
621 if (ionic_model !=
"MinimalModel" && ionic_model !=
"AlievPanfilov" && ionic_model !=
"Fox")
623 solver -> solveOneStepGatingVariablesRL();
627 solver -> solveOneStepGatingVariablesFE();
636 solver -> solveOneICIStep();
638 timeReacDiff += chrono.globalDiff ( *Comm );
644 else if ( solutionMethod ==
"ICI" )
657 if (ionic_model !=
"MinimalModel" && ionic_model !=
"AlievPanfilov" && ionic_model !=
"Fox")
659 solver -> solveOneStepGatingVariablesRL();
663 solver -> solveOneStepGatingVariablesFE();
674 solver -> solveOneICIStepWithFullMass();
676 timeReacDiff += chrono.globalDiff ( *Comm );
683 else if ( solutionMethod ==
"SVI" )
697 if (ionic_model !=
"MinimalModel" && ionic_model !=
"AlievPanfilov" && ionic_model !=
"Fox")
699 solver -> solveOneStepGatingVariablesRL();
703 solver -> solveOneStepGatingVariablesFE();
711 solver -> solveOneSVIStep();
713 timeReacDiff += chrono.globalDiff ( *Comm );
727 solver -> registerActivationTime (*activationTimeVector, t, activationThreshold);
735 if ( Comm->MyPID() == 0 )
737 std::cout <<
"\nTime : " << t;
739 solver -> exportSolution (exporter, t);
749 exporter.closeFile();
750 activationTimeExporter.postProcess (0);
751 activationTimeExporter.closeFile();
757 if ( Comm->MyPID() == 0 )
759 std::cout <<
"\nExporting fibers ... ";
761 solver -> exportFiberDirection (problemFolder);
774 if ( Comm->MyPID() == 0 )
777 std::cout <<
"\n\n\nTotal lapsed time : " << chronoinitialsettings.diff() << std::endl;
778 if ( solutionMethod ==
"splitting" )
780 std::cout <<
"Diffusion time : " << timeDiff << std::endl;
781 std::cout <<
"Reaction time : " << timeReac << std::endl;
785 std::cout <<
"Solution time : " << timeReacDiff << std::endl;
788 std::cout <<
"\n\nThank you for using ETA_MonodomainSolver.\nI hope to meet you again soon!\n All the best for your simulation :P\n " ;
796 Real fullActivationTime = activationTimeVector -> maxValue();
797 activationTimeVector.reset();
802 if ( Comm->MyPID() == 0 )
804 std::cout <<
"\nError: " << err <<
"\n" <<
"\nActivation time: " << fullActivationTime <<
"\n";
807 MPI_Barrier (MPI_COMM_WORLD);
811 if ( Comm->MyPID() == 0 )
813 std::cout <<
"\nTest failed!\n";
815 returnValue = EXIT_FAILURE;
819 returnValue = EXIT_SUCCESS;
824 return ( returnValue );
VectorEpetra - The Epetra Vector format Wrapper.
void start()
Start the timer.
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.
#define finalActivationTime
int32_type Int
Generic integer data.
Real & operator[](UInt const &i)
Operator [].
double Real
Generic real data.
void stop()
Stop the timer.
int main(int argc, char **argv)