Chaste Commit::baa90ac2819b962188b7562f2326be23c47859a7
CardiacSimulation.hpp
1/*
2
3Copyright (c) 2005-2024, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, are permitted provided that the following conditions are met:
14 * Redistributions of source code must retain the above copyright notice,
15 this list of conditions and the following disclaimer.
16 * Redistributions in binary form must reproduce the above copyright notice,
17 this list of conditions and the following disclaimer in the documentation
18 and/or other materials provided with the distribution.
19 * Neither the name of the University of Oxford nor the names of its
20 contributors may be used to endorse or promote products derived from this
21 software without specific prior written permission.
22
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36#ifndef CARDIACSIMULATION_HPP_
37#define CARDIACSIMULATION_HPP_
38
39#include <vector>
40#include <memory>
41
42#include "UblasIncludes.hpp"
43
44#include "AbstractCardiacProblem.hpp"
45#include "MonodomainProblem.hpp"
46#include "BidomainProblem.hpp"
47#include "BidomainWithBathProblem.hpp"
48#include "CardiacSimulationArchiver.hpp"
49#include "PetscTools.hpp"
50#include "TimeStepper.hpp"
51#include "Exception.hpp"
52
53#include "HeartConfig.hpp"
54#include "HeartConfigRelatedCellFactory.hpp"
55#include "HeartFileFinder.hpp"
56
57#include "TetrahedralMesh.hpp"
58#include "NonCachedTetrahedralMesh.hpp"
59#include "ChastePoint.hpp"
60#include "ChasteCuboid.hpp"
61#include "MeshalyzerMeshWriter.hpp"
62#include "TrianglesMeshWriter.hpp"
63
64#include "OrthotropicConductivityTensors.hpp"
65#include "PostProcessingWriter.hpp"
66
67#include "OutputDirectoryFifoQueue.hpp"
68#include "ExecutableSupport.hpp"
69
81{
82private:
88 void ReadParametersFromFile(std::string parameterFileName);
89
94 template<class Problem, unsigned SPACE_DIM>
96 {
97 boost::shared_ptr<Problem> p_problem;
98
99 if (HeartConfig::Instance()->IsSimulationDefined())
100 {
102 p_problem.reset(new Problem(&cell_factory));
103
104 p_problem->Initialise();
105 }
106 else // (HeartConfig::Instance()->IsSimulationResumed())
107 {
108 p_problem.reset(CardiacSimulationArchiver<Problem>::Load(HeartConfig::Instance()->GetArchivedSimulationDir()));
109 // Any changes to parameters that normally only take effect at problem creation time...
111 cell_factory.SetMesh(&(p_problem->rGetMesh()));
112 AbstractCardiacTissue<SPACE_DIM, SPACE_DIM>* p_tissue = p_problem->GetTissue();
113 DistributedVectorFactory* p_vector_factory = p_problem->rGetMesh().GetDistributedVectorFactory();
114 for (unsigned node_global_index = p_vector_factory->GetLow();
115 node_global_index < p_vector_factory->GetHigh();
116 node_global_index++)
117 {
118 // Overwrite any previous stimuli if new ones are defined
119 cell_factory.SetCellIntracellularStimulus(p_tissue->GetCardiacCell(node_global_index), node_global_index);
120 // Modify cell model parameters
121 cell_factory.SetCellParameters(p_tissue->GetCardiacCell(node_global_index), node_global_index);
122 }
123 }
124
126 {
127 // Create the checkpoints directory and set up a fifo queue of subdirectory names
128 OutputDirectoryFifoQueue directory_queue(HeartConfig::Instance()->GetOutputDirectory() + "_checkpoints/",
129 HeartConfig::Instance()->GetMaxCheckpointsOnDisk());
130
131 TimeStepper checkpoint_stepper(p_problem->GetCurrentTime(), HeartConfig::Instance()->GetSimulationDuration(), HeartConfig::Instance()->GetCheckpointTimestep());
132 while ( !checkpoint_stepper.IsTimeAtEnd() )
133 {
134 // Solve checkpoint timestep
136 p_problem->Solve();
137
138 // Create directory that will contain archive and partial results for this checkpoint timestep.
139 std::stringstream checkpoint_id;
140 checkpoint_id << HeartConfig::Instance()->GetSimulationDuration() << "ms/";
141 std::string checkpoint_dir_basename = directory_queue.CreateNextDir(checkpoint_id.str());
142
143 // Archive simulation (in a subdirectory of checkpoint_dir_basename).
144 char time_stamp[60]; // Write out without scientific notation in time - ticket 2861
145
146 // Here we cope with times of up to 16 significant figures, which should be OK without floating-point crazy decimal places like 1.000000000000000000000000000000000001
147 std::sprintf(time_stamp,"%0.16g",HeartConfig::Instance()->GetSimulationDuration());
148
149 std::stringstream archive_foldername;
150 archive_foldername << HeartConfig::Instance()->GetOutputDirectory() << "_" << time_stamp << "ms";
151
152 CardiacSimulationArchiver<Problem>::Save(*(p_problem.get()), checkpoint_dir_basename + archive_foldername.str(), false);
153
154 // Put a copy of the partial results aside (in a subdirectory of checkpoint_dir_basename).
155 OutputFileHandler checkpoint_dir_basename_handler(checkpoint_dir_basename, false);
156 OutputFileHandler partial_output_dir_handler(HeartConfig::Instance()->GetOutputDirectory(), false);
157
159 partial_output_dir_handler.FindFile("").CopyTo(checkpoint_dir_basename_handler.FindFile(""));
160 );
161
162 // Create an XML file to help in resuming
163 CreateResumeXmlFile(checkpoint_dir_basename, archive_foldername.str());
164
165 // Advance time stepper
166 checkpoint_stepper.AdvanceOneTimeStep();
167 }
168 }
169 else
170 {
171 p_problem->Solve();
172 }
174 {
175 mSavedProblem = p_problem;
176 }
177 }
178
184 void Run();
185
195 void CreateResumeXmlFile(const std::string& rOutputDirectory, const std::string& rArchiveDirectory);
196
202 std::string BoolToString(bool yesNo);
203public:
213 CardiacSimulation(std::string parameterFileName,
214 bool writeProvenanceInfo=false,
215 bool saveProblemInstance=false);
216
221 boost::shared_ptr<AbstractUntemplatedCardiacProblem> GetSavedProblem();
222private:
225
227 boost::shared_ptr<AbstractUntemplatedCardiacProblem> mSavedProblem;
228};
229
230#endif /*CARDIACSIMULATION_HPP_*/
#define TRY_IF_MASTER(method)
virtual void SetMesh(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > *pMesh)
AbstractCardiacCellInterface * GetCardiacCell(unsigned globalIndex)
static void Save(PROBLEM_CLASS &rSimulationToArchive, const std::string &rDirectory, bool clearDirectory=true)
void CreateResumeXmlFile(const std::string &rOutputDirectory, const std::string &rArchiveDirectory)
boost::shared_ptr< AbstractUntemplatedCardiacProblem > mSavedProblem
void ReadParametersFromFile(std::string parameterFileName)
boost::shared_ptr< AbstractUntemplatedCardiacProblem > GetSavedProblem()
std::string BoolToString(bool yesNo)
FileFinder CopyTo(const FileFinder &rDest) const
void SetCellIntracellularStimulus(AbstractCardiacCellInterface *pCell, unsigned nodeIndex)
void SetCellParameters(AbstractCardiacCellInterface *pCell, unsigned nodeIndex)
double GetSimulationDuration() const
void SetSimulationDuration(double simulationDuration)
double GetCheckpointTimestep() const
std::string GetOutputDirectory() const
bool GetCheckpointSimulation() const
static HeartConfig * Instance()
std::string CreateNextDir(const std::string &rSubdirectoryName)
FileFinder FindFile(std::string leafName) const
bool IsTimeAtEnd() const
void AdvanceOneTimeStep()
double GetNextTime() const