40 #pragma GCC diagnostic ignored "-Wunused-variable" 41 #pragma GCC diagnostic ignored "-Wunused-parameter" 43 #include <Epetra_ConfigDefs.h> 46 #include <Epetra_MpiComm.h> 48 #include <Epetra_SerialComm.h> 52 #pragma GCC diagnostic warning "-Wunused-variable" 53 #pragma GCC diagnostic warning "-Wunused-parameter" 60 #include <lifev/core/array/VectorSmall.hpp> 62 #include <lifev/core/array/VectorEpetra.hpp> 63 #include <lifev/core/array/MatrixEpetra.hpp> 64 #include <lifev/core/array/MapEpetra.hpp> 65 #include <lifev/core/mesh/MeshData.hpp> 66 #include <lifev/core/mesh/MeshPartitioner.hpp> 67 #include <lifev/core/filter/ExporterEnsight.hpp> 68 #include <lifev/core/filter/ExporterHDF5.hpp> 69 #include <lifev/core/filter/ExporterEmpty.hpp> 71 #include <lifev/core/algorithm/LinearSolver.hpp> 72 #include <lifev/electrophysiology/solver/ElectroETAMonodomainSolver.hpp> 74 #include <lifev/core/filter/ExporterEnsight.hpp> 76 #include <lifev/core/filter/ExporterHDF5.hpp> 78 #include <lifev/core/filter/ExporterEmpty.hpp> 80 #include <lifev/electrophysiology/solver/IonicModels/IonicMinimalModel.hpp> 81 #include <lifev/electrophysiology/solver/IonicModels/IonicLuoRudyI.hpp> 82 #include <lifev/electrophysiology/solver/IonicModels/IonicTenTusscher06.hpp> 83 #include <lifev/electrophysiology/solver/IonicModels/IonicHodgkinHuxley.hpp> 84 #include <lifev/electrophysiology/solver/IonicModels/IonicNoblePurkinje.hpp> 85 #include <lifev/electrophysiology/util/ElectrophysiologyUtility.hpp> 86 #include <lifev/core/LifeV.hpp> 88 #include <Teuchos_RCP.hpp> 89 #include <Teuchos_ParameterList.hpp> 90 #include "Teuchos_XMLParameterListHelpers.hpp" 94 using namespace LifeV;
99 Real pacingSite_X = 0.0;
100 Real pacingSite_Y = 0.0;
101 Real pacingSite_Z = 0.0;
102 Real stimulusRadius = 0.15;
103 Real stimulusValue = 10;
107 if ( std::abs ( x - pacingSite_X ) <= stimulusRadius
109 std::abs ( z - pacingSite_Z ) <= stimulusRadius
111 std::abs ( y - pacingSite_Y ) <= stimulusRadius
115 returnValue = stimulusValue;
128 Real pacingSite_X = 0.0;
129 Real pacingSite_Y = 0.0;
130 Real pacingSite_Z = 0.0;
131 Real stimulusRadius = 0.15;
132 Real stimulusValue = 500.;
136 if ( std::abs ( x - pacingSite_X ) <= stimulusRadius
138 std::abs ( z - pacingSite_Z ) <= stimulusRadius
140 std::abs ( y - pacingSite_Y ) <= stimulusRadius
144 returnValue = stimulusValue;
157 Real pacingSite_X = 0.0;
158 Real pacingSite_Y = 0.0;
159 Real pacingSite_Z = 0.0;
160 Real stimulusRadius = 0.15;
161 Real stimulusValue = 50;
165 if ( std::abs ( x - pacingSite_X ) <= stimulusRadius
167 std::abs ( z - pacingSite_Z ) <= stimulusRadius
169 std::abs ( y - pacingSite_Y ) <= stimulusRadius
173 returnValue = stimulusValue;
188 MPI_Init (&argc, &argv);
189 std::shared_ptr<Epetra_Comm> Comm (
new Epetra_MpiComm (MPI_COMM_WORLD) );
190 if ( Comm->MyPID() == 0 )
192 std::cout <<
"% using MPI" << std::endl;
199 std::string problemFolder = commandLine.follow (
"Output", 2,
"-o",
"--output" );
201 if ( problemFolder.compare (
"./") )
203 problemFolder +=
"/";
205 if ( Comm->MyPID() == 0 )
207 mkdir ( problemFolder.c_str(), 0777 );
215 typedef RegionMesh<LinearTetra> mesh_Type;
216 typedef std::function < Real (
const Real& ,
220 const ID& ) > function_Type;
223 typedef std::shared_ptr<ionicModel_Type> ionicModelPtr_Type;
225 typedef std::shared_ptr< monodomainSolver_Type > monodomainSolverPtr_Type;
228 typedef std::shared_ptr<vector_Type> vectorPtr_Type;
231 LifeChrono chronoinitialsettings;
233 if ( Comm->MyPID() == 0 )
235 chronoinitialsettings.start();
244 if ( Comm->MyPID() == 0 )
246 std::cout <<
"Importing parameters list...";
248 Teuchos::ParameterList monodomainList = * ( Teuchos::getParametersFromXmlFile (
"MonodomainSolverParamList.xml" ) );
249 if ( Comm->MyPID() == 0 )
251 std::cout <<
" Done!" << std::endl;
254 std::string ionic_model ( monodomainList.get (
"ionic_model",
"minimalModel") );
255 if ( Comm->MyPID() == 0 )
257 std::cout <<
"\nIonic_Model:" << ionic_model;
268 if ( Comm->MyPID() == 0 )
270 std::cout <<
"\nBuilding Constructor for " << ionic_model <<
" Model with parameters ... ";
272 ionicModelPtr_Type model;
273 std::shared_ptr<IonicNoblePurkinje> excitationModel (
new IonicNoblePurkinje() );
275 if ( ionic_model ==
"LuoRudyI" )
277 model.reset (
new IonicLuoRudyI() );
279 if ( ionic_model ==
"TenTusscher06")
281 model.reset (
new IonicTenTusscher06() );
283 if ( ionic_model ==
"HodgkinHuxley")
285 model.reset (
new IonicHodgkinHuxley() );
287 if ( ionic_model ==
"NoblePurkinje")
289 model.reset (
new IonicNoblePurkinje() );
291 if ( ionic_model ==
"MinimalModel")
293 model.reset (
new IonicMinimalModel() );
296 if ( Comm->MyPID() == 0 )
298 std::cout <<
" Done!" << std::endl;
308 std::string meshName = monodomainList.get (
"mesh_name",
"lid16.mesh");
309 std::string meshPath = monodomainList.get (
"mesh_path",
"./");
316 const std::string data_file_name = command_line.follow (
"data", 2,
"-f",
"--file");
317 GetPot dataFile (data_file_name);
325 if ( Comm->MyPID() == 0 )
327 std::cout <<
"Building Monodomain Solvers... ";
330 monodomainSolverPtr_Type solver (
new monodomainSolver_Type ( meshName, meshPath, dataFile, model ) );
331 if ( Comm->MyPID() == 0 )
333 std::cout <<
" solver done... ";
343 if ( Comm->MyPID() == 0 )
345 std::cout <<
"\nInitializing potential and gating variables: " ;
349 solver -> initializePotential();
350 solver -> initializeAppliedCurrent();
351 solver -> setInitialConditions();
353 if ( Comm->MyPID() == 0 )
355 std::cout <<
"\nDone. " << std::flush ;
362 std::vector<Real> junction (3, 0.0);
364 UInt numberOfSources (4);
365 UInt numberLocalSources (numberOfSources / Comm->NumProc() );
366 if ( Comm->MyPID() == 0 )
368 numberLocalSources += numberOfSources % Comm->NumProc();
371 std::vector<ID> containerPointsGivenFlag, containerPointsWithAppliedCurrent;
372 std::vector<Real> activationTime;
374 ElectrophysiologyUtility::allIdsPointsWithGivenFlag<mesh_Type> (containerPointsGivenFlag, flag, solver -> appliedCurrentPtr(), solver -> fullMeshPtr() );
375 ElectrophysiologyUtility::randomNPointsInSetAndNeighborhood<mesh_Type> (containerPointsGivenFlag, containerPointsWithAppliedCurrent, activationTime, deltaT, numberLocalSources, * (solver -> fullMeshPtr() ), Comm );
382 solver -> setParameters ( monodomainList );
387 if ( Comm->MyPID() == 0 )
389 std::cout <<
"\nSetting fibers: " ;
396 solver -> setupFibers ( fibers );
398 if ( Comm->MyPID() == 0 )
400 std::cout <<
"Done! \n" ;
406 if ( Comm->MyPID() == 0 )
408 std::cout <<
"\nSetup operators: " ;
411 bool lumpedMass = monodomainList.get (
"LumpedMass",
true);
414 solver -> setupLumpedMassMatrix();
418 solver -> setupMassMatrix();
422 solver -> setupStiffnessMatrix ( solver -> diffusionTensor() );
423 solver -> setupGlobalMatrix();
424 if ( Comm->MyPID() == 0 )
426 std::cout <<
"Done! \n" ;
432 ExporterHDF5< RegionMesh <LinearTetra> > exporter;
434 solver -> setupExporter ( exporter, monodomainList.get (
"OutputFile",
"Solution") );
435 exporter.setPostDir (problemFolder);
436 solver -> exportSolution ( exporter, 0);
441 vectorPtr_Type activationTimeVector (
new vector_Type ( solver -> potentialPtr() -> map() ) );
442 *activationTimeVector = -1.0;
444 ExporterHDF5< RegionMesh <LinearTetra> > activationTimeExporter;
445 activationTimeExporter.setMeshProcId (solver -> localMeshPtr(), solver -> commPtr() ->MyPID() );
446 activationTimeExporter.addVariable (ExporterData<mesh_Type>::ScalarField,
"Activation Time",
447 solver -> feSpacePtr(), activationTimeVector, UInt (0) );
448 activationTimeExporter.setPrefix (
"ActivationTime");
449 activationTimeExporter.setPostDir (problemFolder);
454 if ( Comm->MyPID() == 0 )
456 std::cout <<
"\nstart solving: " ;
459 Real dt = monodomainList.get (
"timeStep", 0.1);
460 Real TF = monodomainList.get (
"endTime", 150.0);
461 Int iter = monodomainList.get (
"saveStep", 1.0) / dt;
466 Real timeReacDiff = 0.0;
469 std::string solutionMethod = monodomainList.get (
"solutionMethod",
"splitting");
471 std::vector<Real> statesExcitationModel (excitationModel->Size(), 0);
472 std::vector<Real> rhsExcitationModel (excitationModel->Size(), 0);
473 std::vector<Real> valueAppliedCurrent (TF / dt, 0);
474 std::vector<UInt> shiftVector (TF / dt, -1);
475 excitationModel->initialize (statesExcitationModel);
476 statesExcitationModel[0] = -70.0;
477 statesExcitationModel[1] = excitationModel->mInf (-70.0);
478 statesExcitationModel[2] = excitationModel->nInf (-70.0);
479 statesExcitationModel[3] = excitationModel->hInf (-70.0);
480 int localIndexTime (0);
481 for (
Real t = 0.0; t < TF; )
486 excitationModel->computeGatingVariablesWithRushLarsen (statesExcitationModel, dt);
487 statesExcitationModel.at (0) = statesExcitationModel.at (0) + dt * (excitationModel->computeLocalPotentialRhs ( statesExcitationModel) );
488 valueAppliedCurrent[localIndexTime] = excitationModel->Itotal();
494 ElectrophysiologyUtility::applyCurrentGivenSetOfPoints<ID> (containerPointsWithAppliedCurrent, activationTime, solver -> appliedCurrentPtr(), valueAppliedCurrent, shiftVector, t);
495 if ( solutionMethod ==
"splitting" )
499 if (ionic_model !=
"MinimalModel" && ionic_model !=
"HodgkinHuxley")
501 solver->solveOneReactionStepRL();
505 solver->solveOneReactionStepFE();
509 timeReac += chrono.globalDiff ( *Comm );
511 (*solver->rhsPtrUnique() ) *= 0.0;
516 solver->solveOneDiffusionStepBE();
518 timeDiff += chrono.globalDiff ( *Comm );
520 else if ( solutionMethod ==
"ICI" )
524 if (ionic_model !=
"MinimalModel" && ionic_model !=
"HodgkinHuxley")
526 solver -> solveOneStepGatingVariablesRL();
530 solver -> solveOneStepGatingVariablesFE();
532 solver -> solveOneICIStep();
534 timeReacDiff += chrono.globalDiff ( *Comm );
536 else if ( solutionMethod ==
"SVI" )
540 if (ionic_model !=
"MinimalModel" && ionic_model !=
"HodgkinHuxley")
542 solver -> solveOneStepGatingVariablesRL();
546 solver -> solveOneStepGatingVariablesFE();
548 solver -> solveOneSVIStep();
550 timeReacDiff += chrono.globalDiff ( *Comm );
556 solver -> registerActivationTime (*activationTimeVector, t, 0.95);
560 solver -> exportSolution (exporter, t);
562 if ( Comm->MyPID() == 0 )
564 std::cout <<
"\n\n\nActual time : " << t << std::endl << std::endl << std::endl;
568 Real normSolution = ( ( solver -> globalSolution().at (0) )->norm2() );
569 if ( Comm->MyPID() == 0 )
571 std::cout <<
"2-norm of potential solution: " << normSolution << std::endl;
574 exporter.closeFile();
575 activationTimeExporter.postProcess (0);
576 activationTimeExporter.closeFile();
578 if ( Comm->MyPID() == 0 )
580 std::cout <<
"Exporting fibers: " << std::endl;
586 solver -> exportFiberDirection();
589 if ( Comm->MyPID() == 0 )
591 chronoinitialsettings.stop();
592 std::cout <<
"\n\n\nTotal lapsed time : " << chronoinitialsettings.diff() << std::endl;
593 if ( solutionMethod ==
"splitting" )
595 std::cout <<
"Diffusion time : " << timeDiff << std::endl;
596 std::cout <<
"Reaction time : " << timeReac << std::endl;
598 else if ( solutionMethod ==
"ICI" )
600 std::cout <<
"Solution time : " << timeReacDiff << std::endl;
602 else if ( solutionMethod ==
"SVI" )
604 std::cout <<
"Solution time : " << timeReacDiff << std::endl;
607 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 " ;
609 MPI_Barrier (MPI_COMM_WORLD);
612 return ( EXIT_SUCCESS );
VectorEpetra - The Epetra Vector format Wrapper.
void assignFunction(bcBase_Type &base)
Assign the function to the base of the BCHandler.
int main(int argc, char **argv)
GetPot(const int argc_, char **argv_, const char *FieldSeparator=0x0)
virtual std::vector< std::vector< Real > > getJac(const std::vector< Real > &v, Real h=1.0e-8)
This methods computes the Jacobian numerically.
int32_type Int
Generic integer data.
Real PacingProtocolMM(const Real &t, const Real &x, const Real &y, const Real &z, const ID &)
Real & operator[](UInt const &i)
Operator [].
double Real
Generic real data.
Real PacingProtocolHH(const Real &t, const Real &x, const Real &y, const Real &z, const ID &)
ExporterHDF5< mesh_Type > hdf5IOFile_Type
Real PacingProtocol(const Real &, const Real &x, const Real &y, const Real &z, const ID &)
uint32_type UInt
generic unsigned integer (used mainly for addressing)