CardiacSimulation.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2011
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 #ifndef CARDIACSIMULATION_HPP_
00030 #define CARDIACSIMULATION_HPP_
00031 
00032 #include <vector>
00033 #include <ctime>
00034 #include <memory>
00035 
00036 #include "UblasIncludes.hpp"
00037 
00038 #include "AbstractCardiacProblem.hpp"
00039 #include "MonodomainProblem.hpp"
00040 #include "BidomainProblem.hpp"
00041 #include "BidomainWithBathProblem.hpp"
00042 #include "CardiacSimulationArchiver.hpp"
00043 #include "PetscTools.hpp"
00044 #include "TimeStepper.hpp"
00045 #include "Exception.hpp"
00046 
00047 #include "HeartConfig.hpp"
00048 #include "HeartConfigRelatedCellFactory.hpp"
00049 #include "HeartFileFinder.hpp"
00050 
00051 #include "TetrahedralMesh.hpp"
00052 #include "NonCachedTetrahedralMesh.hpp"
00053 #include "ChastePoint.hpp"
00054 #include "ChasteCuboid.hpp"
00055 #include "MeshalyzerMeshWriter.hpp"
00056 #include "TrianglesMeshWriter.hpp"
00057 
00058 #include "OrthotropicConductivityTensors.hpp"
00059 
00060 #include "Hdf5ToMeshalyzerConverter.hpp"
00061 #include "PostProcessingWriter.hpp"
00062 
00063 #include "OutputDirectoryFifoQueue.hpp"
00064 #include "ExecutableSupport.hpp"
00065 
00076 class CardiacSimulation
00077 {
00078 private:
00084     void ReadParametersFromFile(std::string parameterFileName);
00085 
00090     template<class Problem, unsigned SPACE_DIM>
00091     void CreateAndRun()
00092     {
00093         std::auto_ptr<Problem> p_problem;
00094 
00095         if (HeartConfig::Instance()->IsSimulationDefined())
00096         {
00097             HeartConfigRelatedCellFactory<SPACE_DIM> cell_factory;
00098             p_problem.reset(new Problem(&cell_factory));
00099 
00100             p_problem->Initialise();
00101         }
00102         else // (HeartConfig::Instance()->IsSimulationResumed())
00103         {
00104             p_problem.reset(CardiacSimulationArchiver<Problem>::Load(HeartConfig::Instance()->GetArchivedSimulationDir()));
00105             // Any changes to parameters that normally only take effect at problem creation time...
00106             HeartConfigRelatedCellFactory<SPACE_DIM> cell_factory;
00107             cell_factory.SetMesh(&(p_problem->rGetMesh()));
00108             AbstractCardiacTissue<SPACE_DIM, SPACE_DIM>* p_tissue = p_problem->GetTissue();
00109             DistributedVectorFactory* p_vector_factory = p_problem->rGetMesh().GetDistributedVectorFactory();
00110             for (unsigned node_global_index = p_vector_factory->GetLow();
00111                  node_global_index < p_vector_factory->GetHigh();
00112                  node_global_index++)
00113             {
00114                 // Overwrite any previous stimuli if new ones are defined
00115                 cell_factory.SetCellIntracellularStimulus(p_tissue->GetCardiacCell(node_global_index), node_global_index);
00116                 // Modify cell model parameters
00117                 cell_factory.SetCellParameters(p_tissue->GetCardiacCell(node_global_index), node_global_index);
00118             }
00119         }
00120 
00121         if (HeartConfig::Instance()->GetCheckpointSimulation())
00122         {
00123             // Create the checkpoints directory and set up a fifo queue of subdirectory names
00124             OutputDirectoryFifoQueue directory_queue(HeartConfig::Instance()->GetOutputDirectory() + "_checkpoints/",
00125                                                      HeartConfig::Instance()->GetMaxCheckpointsOnDisk());
00126 
00127             TimeStepper checkpoint_stepper(p_problem->GetCurrentTime(), HeartConfig::Instance()->GetSimulationDuration(), HeartConfig::Instance()->GetCheckpointTimestep());
00128             while ( !checkpoint_stepper.IsTimeAtEnd() )
00129             {
00130                 // Solve checkpoint timestep
00131                 HeartConfig::Instance()->SetSimulationDuration(checkpoint_stepper.GetNextTime());
00132                 p_problem->Solve();
00133 
00134                 // Create directory that will contain archive and partial results for this checkpoint timestep.
00135                 std::stringstream checkpoint_id;
00136                 checkpoint_id << HeartConfig::Instance()->GetSimulationDuration() << "ms/";
00137                 std::string checkpoint_dir_basename = directory_queue.CreateNextDir(checkpoint_id.str());
00138 
00139                 // Archive simulation (in a subdirectory of checkpoint_dir_basename).
00140                 std::stringstream archive_foldername;
00141                 archive_foldername << HeartConfig::Instance()->GetOutputDirectory() << "_" << HeartConfig::Instance()->GetSimulationDuration() << "ms";
00142                 CardiacSimulationArchiver<Problem>::Save(*(p_problem.get()), checkpoint_dir_basename + archive_foldername.str(), false);
00143 
00144                 // Put a copy of the partial results aside (in a subdirectory of checkpoint_dir_basename).
00145                 OutputFileHandler checkpoint_dir_basename_handler(checkpoint_dir_basename, false);
00146                 OutputFileHandler partial_output_dir_handler(HeartConfig::Instance()->GetOutputDirectory(), false);
00147                 if (PetscTools::AmMaster())
00148                 {
00149                     ABORT_IF_NON0(system, "cp -r " + partial_output_dir_handler.GetOutputDirectoryFullPath() + " " + checkpoint_dir_basename_handler.GetOutputDirectoryFullPath());
00150                 }
00151 
00152                 // Create an XML file to help in resuming
00153                 CreateResumeXmlFile(checkpoint_dir_basename, archive_foldername.str());
00154 
00155                 // Advance time stepper
00156                 checkpoint_stepper.AdvanceOneTimeStep();
00157             }
00158         }
00159         else
00160         {
00161             p_problem->Solve();
00162         }
00163         if (mSaveProblemInstance)
00164         {
00165             mSavedProblem = p_problem;
00166         }
00167     }
00168 
00174     void Run();
00175 
00185     void CreateResumeXmlFile(const std::string& rOutputDirectory, const std::string& rArchiveDirectory);
00186 
00191     std::string BoolToString(bool yesNo);
00192 public:
00202     CardiacSimulation(std::string parameterFileName,
00203                       bool writeProvenanceInfo=false,
00204                       bool saveProblemInstance=false);
00205 
00210     boost::shared_ptr<AbstractUntemplatedCardiacProblem> GetSavedProblem();
00211 private:
00213     bool mSaveProblemInstance;
00214 
00216     boost::shared_ptr<AbstractUntemplatedCardiacProblem> mSavedProblem;
00217 };
00218 
00219 #endif /*CARDIACSIMULATION_HPP_*/
Generated on Thu Dec 22 13:00:06 2011 for Chaste by  doxygen 1.6.3