Chaste Release::3.1
CardiacSimulation.hpp
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #ifndef CARDIACSIMULATION_HPP_
00037 #define CARDIACSIMULATION_HPP_
00038 
00039 #include <vector>
00040 #include <ctime>
00041 #include <memory>
00042 
00043 #include "UblasIncludes.hpp"
00044 
00045 #include "AbstractCardiacProblem.hpp"
00046 #include "MonodomainProblem.hpp"
00047 #include "BidomainProblem.hpp"
00048 #include "BidomainWithBathProblem.hpp"
00049 #include "CardiacSimulationArchiver.hpp"
00050 #include "PetscTools.hpp"
00051 #include "TimeStepper.hpp"
00052 #include "Exception.hpp"
00053 
00054 #include "HeartConfig.hpp"
00055 #include "HeartConfigRelatedCellFactory.hpp"
00056 #include "HeartFileFinder.hpp"
00057 
00058 #include "TetrahedralMesh.hpp"
00059 #include "NonCachedTetrahedralMesh.hpp"
00060 #include "ChastePoint.hpp"
00061 #include "ChasteCuboid.hpp"
00062 #include "MeshalyzerMeshWriter.hpp"
00063 #include "TrianglesMeshWriter.hpp"
00064 
00065 #include "OrthotropicConductivityTensors.hpp"
00066 
00067 #include "Hdf5ToMeshalyzerConverter.hpp"
00068 #include "PostProcessingWriter.hpp"
00069 
00070 #include "OutputDirectoryFifoQueue.hpp"
00071 #include "ExecutableSupport.hpp"
00072 
00083 class CardiacSimulation
00084 {
00085 private:
00091     void ReadParametersFromFile(std::string parameterFileName);
00092 
00097     template<class Problem, unsigned SPACE_DIM>
00098     void CreateAndRun()
00099     {
00100         std::auto_ptr<Problem> p_problem;
00101 
00102         if (HeartConfig::Instance()->IsSimulationDefined())
00103         {
00104             HeartConfigRelatedCellFactory<SPACE_DIM> cell_factory;
00105             p_problem.reset(new Problem(&cell_factory));
00106 
00107             p_problem->Initialise();
00108         }
00109         else // (HeartConfig::Instance()->IsSimulationResumed())
00110         {
00111             p_problem.reset(CardiacSimulationArchiver<Problem>::Load(HeartConfig::Instance()->GetArchivedSimulationDir()));
00112             // Any changes to parameters that normally only take effect at problem creation time...
00113             HeartConfigRelatedCellFactory<SPACE_DIM> cell_factory;
00114             cell_factory.SetMesh(&(p_problem->rGetMesh()));
00115             AbstractCardiacTissue<SPACE_DIM, SPACE_DIM>* p_tissue = p_problem->GetTissue();
00116             DistributedVectorFactory* p_vector_factory = p_problem->rGetMesh().GetDistributedVectorFactory();
00117             for (unsigned node_global_index = p_vector_factory->GetLow();
00118                  node_global_index < p_vector_factory->GetHigh();
00119                  node_global_index++)
00120             {
00121                 // Overwrite any previous stimuli if new ones are defined
00122                 cell_factory.SetCellIntracellularStimulus(p_tissue->GetCardiacCell(node_global_index), node_global_index);
00123                 // Modify cell model parameters
00124                 cell_factory.SetCellParameters(p_tissue->GetCardiacCell(node_global_index), node_global_index);
00125             }
00126         }
00127 
00128         if (HeartConfig::Instance()->GetCheckpointSimulation())
00129         {
00130             // Create the checkpoints directory and set up a fifo queue of subdirectory names
00131             OutputDirectoryFifoQueue directory_queue(HeartConfig::Instance()->GetOutputDirectory() + "_checkpoints/",
00132                                                      HeartConfig::Instance()->GetMaxCheckpointsOnDisk());
00133 
00134             TimeStepper checkpoint_stepper(p_problem->GetCurrentTime(), HeartConfig::Instance()->GetSimulationDuration(), HeartConfig::Instance()->GetCheckpointTimestep());
00135             while ( !checkpoint_stepper.IsTimeAtEnd() )
00136             {
00137                 // Solve checkpoint timestep
00138                 HeartConfig::Instance()->SetSimulationDuration(checkpoint_stepper.GetNextTime());
00139                 p_problem->Solve();
00140 
00141                 // Create directory that will contain archive and partial results for this checkpoint timestep.
00142                 std::stringstream checkpoint_id;
00143                 checkpoint_id << HeartConfig::Instance()->GetSimulationDuration() << "ms/";
00144                 std::string checkpoint_dir_basename = directory_queue.CreateNextDir(checkpoint_id.str());
00145 
00146                 // Archive simulation (in a subdirectory of checkpoint_dir_basename).
00147                 std::stringstream archive_foldername;
00148                 archive_foldername << HeartConfig::Instance()->GetOutputDirectory() << "_" << HeartConfig::Instance()->GetSimulationDuration() << "ms";
00149                 CardiacSimulationArchiver<Problem>::Save(*(p_problem.get()), checkpoint_dir_basename + archive_foldername.str(), false);
00150 
00151                 // Put a copy of the partial results aside (in a subdirectory of checkpoint_dir_basename).
00152                 OutputFileHandler checkpoint_dir_basename_handler(checkpoint_dir_basename, false);
00153                 OutputFileHandler partial_output_dir_handler(HeartConfig::Instance()->GetOutputDirectory(), false);
00154                 if (PetscTools::AmMaster())
00155                 {
00156                     ABORT_IF_NON0(system, "cp -r " + partial_output_dir_handler.GetOutputDirectoryFullPath() + " " + checkpoint_dir_basename_handler.GetOutputDirectoryFullPath());
00157                 }
00158 
00159                 // Create an XML file to help in resuming
00160                 CreateResumeXmlFile(checkpoint_dir_basename, archive_foldername.str());
00161 
00162                 // Advance time stepper
00163                 checkpoint_stepper.AdvanceOneTimeStep();
00164             }
00165         }
00166         else
00167         {
00168             p_problem->Solve();
00169         }
00170         if (mSaveProblemInstance)
00171         {
00172             mSavedProblem = p_problem;
00173         }
00174     }
00175 
00181     void Run();
00182 
00192     void CreateResumeXmlFile(const std::string& rOutputDirectory, const std::string& rArchiveDirectory);
00193 
00198     std::string BoolToString(bool yesNo);
00199 public:
00209     CardiacSimulation(std::string parameterFileName,
00210                       bool writeProvenanceInfo=false,
00211                       bool saveProblemInstance=false);
00212 
00217     boost::shared_ptr<AbstractUntemplatedCardiacProblem> GetSavedProblem();
00218 private:
00220     bool mSaveProblemInstance;
00221 
00223     boost::shared_ptr<AbstractUntemplatedCardiacProblem> mSavedProblem;
00224 };
00225 
00226 #endif /*CARDIACSIMULATION_HPP_*/