CardiacSimulation.hpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef CARDIACSIMULATION_HPP_
00030 #define CARDIACSIMULATION_HPP_
00031
00032
00033 #include "CardiacSimulationArchiver.hpp"
00034
00035
00036
00037
00038
00039
00040 #include <vector>
00041 #include <ctime>
00042 #include <memory>
00043
00044 #include "UblasIncludes.hpp"
00045
00046 #include "MonodomainProblem.hpp"
00047 #include "BidomainProblem.hpp"
00048 #include "PetscTools.hpp"
00049 #include "TimeStepper.hpp"
00050 #include "Exception.hpp"
00051
00052 #include "HeartConfig.hpp"
00053 #include "HeartConfigRelatedCellFactory.hpp"
00054
00055 #include "TetrahedralMesh.hpp"
00056 #include "NonCachedTetrahedralMesh.hpp"
00057 #include "ChastePoint.hpp"
00058 #include "ChasteCuboid.hpp"
00059 #include "MeshalyzerMeshWriter.hpp"
00060 #include "TrianglesMeshWriter.hpp"
00061
00062 #include "OrthotropicConductivityTensors.hpp"
00063
00064 #include "Hdf5ToMeshalyzerConverter.hpp"
00065 #include "PostProcessingWriter.hpp"
00066
00067 #include "OutputDirectoryFifoQueue.hpp"
00068
00079 class CardiacSimulation
00080 {
00081 private:
00087 void ReadParametersFromFile(std::string parameterFileName);
00088
00093 template<class Problem, unsigned SPACE_DIM>
00094 void CreateAndRun()
00095 {
00096 std::auto_ptr<Problem> p_problem;
00097
00098 if (HeartConfig::Instance()->IsSimulationDefined())
00099 {
00100 HeartConfigRelatedCellFactory<SPACE_DIM> cell_factory;
00101 p_problem.reset(new Problem(&cell_factory));
00102
00103 p_problem->Initialise();
00104 }
00105 else
00106 {
00107 p_problem.reset(CardiacSimulationArchiver<Problem>::Load(HeartConfig::Instance()->GetArchivedSimulationDir()));
00108 }
00109
00110 if (HeartConfig::Instance()->GetCheckpointSimulation())
00111 {
00112
00113 OutputDirectoryFifoQueue directory_queue(HeartConfig::Instance()->GetOutputDirectory() + "_checkpoints/",
00114 HeartConfig::Instance()->GetMaxCheckpointsOnDisk());
00115
00116 TimeStepper checkpoint_stepper(p_problem->GetCurrentTime(), HeartConfig::Instance()->GetSimulationDuration(), HeartConfig::Instance()->GetCheckpointTimestep());
00117 while ( !checkpoint_stepper.IsTimeAtEnd() )
00118 {
00119
00120 HeartConfig::Instance()->SetSimulationDuration(checkpoint_stepper.GetNextTime());
00121 p_problem->Solve();
00122
00123
00124 std::stringstream checkpoint_id;
00125 checkpoint_id << HeartConfig::Instance()->GetSimulationDuration() << "ms/";
00126 std::string checkpoint_dir_basename = directory_queue.CreateNextDir(checkpoint_id.str());
00127
00128
00129 std::stringstream archive_foldername;
00130 archive_foldername << HeartConfig::Instance()->GetOutputDirectory() << "_" << HeartConfig::Instance()->GetSimulationDuration() << "ms";
00131 CardiacSimulationArchiver<Problem>::Save(*(p_problem.get()), checkpoint_dir_basename + archive_foldername.str(), false);
00132
00133
00134 OutputFileHandler checkpoint_dir_basename_handler(checkpoint_dir_basename, false);
00135 OutputFileHandler partial_output_dir_handler(HeartConfig::Instance()->GetOutputDirectory(), false);
00136 if (PetscTools::AmMaster())
00137 {
00138 EXPECT0(system, "cp -r " + partial_output_dir_handler.GetOutputDirectoryFullPath() + " " + checkpoint_dir_basename_handler.GetOutputDirectoryFullPath());
00139 }
00140
00141
00142 CreateResumeXmlFile(checkpoint_dir_basename, archive_foldername.str());
00143
00144
00145 checkpoint_stepper.AdvanceOneTimeStep();
00146 }
00147 }
00148 else
00149 {
00150 p_problem->Solve();
00151 }
00152 }
00153
00159 void Run();
00160
00170 void CreateResumeXmlFile(const std::string& rOutputDirectory, const std::string& rArchiveDirectory);
00171
00176 std::string BoolToString(bool yesNo);
00177 public:
00185 CardiacSimulation(std::string parameterFileName);
00186 };
00187
00188
00189
00190
00191
00192 std::string CardiacSimulation::BoolToString(bool yesNo)
00193 {
00194 std::string result;
00195 if (yesNo)
00196 {
00197 result = "yes";
00198 }
00199 else
00200 {
00201 result = "no";
00202 }
00203 return result;
00204 }
00205
00206 void CardiacSimulation::CreateResumeXmlFile(const std::string& rOutputDirectory, const std::string& rArchiveDirectory)
00207 {
00208 OutputFileHandler handler(rOutputDirectory, false);
00209 out_stream p_file = handler.OpenOutputFile("ResumeParameters.xml");
00210 (*p_file) << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl;
00211 (*p_file) << "<ChasteParameters xmlns='https://chaste.comlab.ox.ac.uk/nss/parameters/2_0'>" << std::endl;
00212 (*p_file) << std::endl;
00213 (*p_file) << " <ResumeSimulation>" << std::endl;
00214 (*p_file) << " <ArchiveDirectory>" << rArchiveDirectory << "</ArchiveDirectory>" << std::endl;
00215 (*p_file) << " <SpaceDimension>" << HeartConfig::Instance()->GetSpaceDimension() << "</SpaceDimension>" << std::endl;
00216 (*p_file) << " <SimulationDuration unit='ms'>0.0</SimulationDuration>" << std::endl;
00217 (*p_file) << " <Domain>" << HeartConfig::Instance()->GetDomain() << "</Domain>" << std::endl;
00218 (*p_file) << " <CheckpointSimulation timestep='" << HeartConfig::Instance()->GetCheckpointTimestep()
00219 << "' unit='ms' max_checkpoints_on_disk='" << HeartConfig::Instance()->GetMaxCheckpointsOnDisk()
00220 << "'/> <!-- This is optional; if not given, the loaded simulation will NOT itself be checkpointed -->" << std::endl;
00221 (*p_file) << " <OutputVisualizer meshalyzer='" << BoolToString(HeartConfig::Instance()->GetVisualizeWithMeshalyzer())
00222 << "' vtk='" << BoolToString(HeartConfig::Instance()->GetVisualizeWithVtk())
00223 << "' cmgui='" << BoolToString(HeartConfig::Instance()->GetVisualizeWithCmgui()) << "'/>" << std::endl;
00224 (*p_file) << " </ResumeSimulation>" << std::endl;
00225 (*p_file) << std::endl;
00226 (*p_file) << " <!-- These elements must exist, but their contents are ignored -->" << std::endl;
00227 (*p_file) << " <Physiological/>" << std::endl;
00228 (*p_file) << " <Numerical/>" << std::endl;
00229 (*p_file) << "</ChasteParameters>" << std::endl;
00230 p_file->close();
00231 }
00232
00233 CardiacSimulation::CardiacSimulation(std::string parameterFileName)
00234 {
00235
00236 if (parameterFileName == "")
00237 {
00238 EXCEPTION("No XML file name given");
00239 }
00240 ReadParametersFromFile(parameterFileName);
00241 Run();
00242 HeartEventHandler::Headings();
00243 HeartEventHandler::Report();
00244 }
00245
00246
00247 void CardiacSimulation::ReadParametersFromFile(std::string parameterFileName)
00248 {
00249
00250 HeartConfig::Reset();
00251 try
00252 {
00253
00254 HeartConfig::Instance()->SetUseFixedSchemaLocation(true);
00255 HeartConfig::Instance()->SetParametersFile(parameterFileName);
00256 }
00257 catch (Exception& e)
00258 {
00259 if (e.CheckShortMessageContains("Missing file parsing configuration") == "")
00260 {
00261
00262 HeartConfig::Reset();
00263 HeartConfig::Instance()->SetUseFixedSchemaLocation(false);
00264 HeartConfig::Instance()->SetParametersFile(parameterFileName);
00265 }
00266 else
00267 {
00268 throw e;
00269 }
00270 }
00271 }
00272
00273
00274 void CardiacSimulation::Run()
00275 {
00276 switch (HeartConfig::Instance()->GetDomain())
00277 {
00278 case cp::domain_type::Mono :
00279 {
00280 switch (HeartConfig::Instance()->GetSpaceDimension())
00281 {
00282 case 3:
00283 {
00284 CreateAndRun<MonodomainProblem<3>,3>();
00285 break;
00286 }
00287
00288 case 2:
00289 {
00290 CreateAndRun<MonodomainProblem<2>,2>();
00291 break;
00292 }
00293
00294 case 1:
00295 {
00296 CreateAndRun<MonodomainProblem<1>,1>();
00297 break;
00298 }
00299 default :
00300 EXCEPTION("Monodomain space dimension not supported: should be 1, 2 or 3");
00301 }
00302 break;
00303 }
00304
00305 case cp::domain_type::Bi :
00306 {
00307 switch (HeartConfig::Instance()->GetSpaceDimension())
00308 {
00309 case 3:
00310 {
00311 CreateAndRun<BidomainProblem<3>,3>();
00312 break;
00313 }
00314 case 2:
00315 {
00316 CreateAndRun<BidomainProblem<2>,2>();
00317 break;
00318 }
00319 case 1:
00320 {
00321 CreateAndRun<BidomainProblem<1>,1>();
00322 break;
00323 }
00324 default :
00325 {
00326 EXCEPTION("Bidomain space dimension not supported: should be 1, 2 or 3");
00327 }
00328 }
00329 break;
00330 }
00331 default :
00332 {
00333
00334 NEVER_REACHED;
00335 }
00336 }
00337 }
00338
00339
00340
00341 #endif