Chaste Release::3.1
CardiacSimulation.cpp
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 #include "CardiacSimulationArchiver.hpp"  // Must go first
00037 #include "CardiacSimulation.hpp"
00038 
00039 
00040 boost::shared_ptr<AbstractUntemplatedCardiacProblem> CardiacSimulation::GetSavedProblem()
00041 {
00042     return mSavedProblem;
00043 }
00044 
00045 std::string CardiacSimulation::BoolToString(bool yesNo)
00046 {
00047     std::string result;
00048     if (yesNo)
00049     {
00050         result = "yes";
00051     }
00052     else
00053     {
00054         result = "no";
00055     }
00056     return result;
00057 }
00058 
00059 void CardiacSimulation::CreateResumeXmlFile(const std::string& rOutputDirectory, const std::string& rArchiveDirectory)
00060 {
00061     OutputFileHandler handler(rOutputDirectory, false);
00062     if (PetscTools::AmMaster())
00063     {
00064         out_stream p_file = handler.OpenOutputFile("ResumeParameters.xml");
00065         (*p_file) << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl;
00066         (*p_file) << "<ChasteParameters xmlns='https://chaste.comlab.ox.ac.uk/nss/parameters/3_0' "
00067                   << "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
00068                   << "xsi:schemaLocation='https://chaste.comlab.ox.ac.uk/nss/parameters/3_0 ChasteParameters_3_0.xsd'>" << std::endl;
00069         (*p_file) << std::endl;
00070         (*p_file) << "    <ResumeSimulation>" << std::endl;
00071         (*p_file) << "        <ArchiveDirectory relative_to='this_file'>" << rArchiveDirectory << "</ArchiveDirectory>" << std::endl;
00072         (*p_file) << "        <SpaceDimension>" << HeartConfig::Instance()->GetSpaceDimension() << "</SpaceDimension>" << std::endl;
00073         (*p_file) << "        <SimulationDuration unit='ms'>0.0</SimulationDuration> <!-- Edit with new simulation duration. Please "
00074                   << "note that the simulation does not restart at t=0 but at the time where the checkpoint was created.-->" << std::endl;
00075         (*p_file) << "        <Domain>" << HeartConfig::Instance()->GetDomain() << "</Domain>" << std::endl;
00076         (*p_file) << "        <CheckpointSimulation timestep='" << HeartConfig::Instance()->GetCheckpointTimestep()
00077                   << "' unit='ms' max_checkpoints_on_disk='" << HeartConfig::Instance()->GetMaxCheckpointsOnDisk()
00078                   << "'/> <!-- This is optional; if not given, the loaded simulation will NOT itself be checkpointed -->" << std::endl;
00079         (*p_file) << "        <OutputVisualizer meshalyzer='" << BoolToString(HeartConfig::Instance()->GetVisualizeWithMeshalyzer())
00080                   << "' vtk='" << BoolToString(HeartConfig::Instance()->GetVisualizeWithVtk())
00081                   << "' parallel_vtk='" << BoolToString(HeartConfig::Instance()->GetVisualizeWithParallelVtk())
00082                   << "' cmgui='" << BoolToString(HeartConfig::Instance()->GetVisualizeWithCmgui()) << "'/>" << std::endl;
00083         (*p_file) << "    </ResumeSimulation>" << std::endl;
00084         (*p_file) << std::endl;
00085         (*p_file) << "    <!-- These elements must exist, but their contents are ignored -->" << std::endl;
00086         (*p_file) << "    <Physiological/>" << std::endl;
00087         (*p_file) << "    <Numerical/>" << std::endl;
00088         (*p_file) << "</ChasteParameters>" << std::endl;
00089         p_file->close();
00090     }
00091     HeartConfig::Instance()->CopySchema(handler.GetOutputDirectoryFullPath());
00092 }
00093 
00094 CardiacSimulation::CardiacSimulation(std::string parameterFileName,
00095                                      bool writeProvenanceInfo,
00096                                      bool saveProblemInstance)
00097     : mSaveProblemInstance(saveProblemInstance)
00098 {
00099     // If we have been passed an XML file then parse the XML file, otherwise throw
00100     if (parameterFileName == "")
00101     {
00102         EXCEPTION("No XML file name given");
00103     }
00104     ReadParametersFromFile(parameterFileName);
00105     Run();
00106     HeartEventHandler::Headings();
00107     HeartEventHandler::Report();
00108     if (writeProvenanceInfo)
00109     {
00110         ExecutableSupport::SetOutputDirectory(HeartConfig::Instance()->GetOutputDirectory());
00111         ExecutableSupport::WriteProvenanceInfoFile();
00112         ExecutableSupport::WriteMachineInfoFile("machine_info");
00113     }
00114 }
00115 
00116 void CardiacSimulation::ReadParametersFromFile(std::string parameterFileName)
00117 {
00118     // Ensure the singleton is in a clean state
00119     HeartConfig::Reset();
00120     try
00121     {
00122         // Try the hardcoded schema location first
00123         HeartConfig::Instance()->SetUseFixedSchemaLocation(true);
00124         HeartConfig::Instance()->SetParametersFile(parameterFileName);
00125     }
00126     catch (Exception& e)
00127     {
00128         if (e.CheckShortMessageContains("Missing file parsing configuration") == "")
00129         {
00130             // Try using the schema location given in the XML
00131             HeartConfig::Reset();
00132             HeartConfig::Instance()->SetUseFixedSchemaLocation(false);
00133             HeartConfig::Instance()->SetParametersFile(parameterFileName);
00134         }
00135         else
00136         {
00137             throw e;
00138         }
00139     }
00140 }
00141 
00142 
00143 #define DOMAIN_CASE(VALUE, CLASS, DIM)    \
00144     case VALUE:                           \
00145     {                                     \
00146         CreateAndRun<CLASS<DIM>, DIM>();  \
00147         break;                            \
00148     }
00149 
00150 #define DOMAIN_SWITCH(DIM)                                                     \
00151     switch (HeartConfig::Instance()->GetDomain())                              \
00152     {                                                                          \
00153         DOMAIN_CASE(cp::domain_type::Mono, MonodomainProblem, DIM)             \
00154         DOMAIN_CASE(cp::domain_type::Bi, BidomainProblem, DIM)                 \
00155         DOMAIN_CASE(cp::domain_type::BiWithBath, BidomainWithBathProblem, DIM) \
00156         default:                                                               \
00157             NEVER_REACHED;                                                     \
00158     }                                                                          \
00159     break
00160 // Note that if the domain is not set correctly then the XML parser will have picked it up before now!
00161 // Missing semi-colon after break so we can put it after the macro call.
00162 
00163 void CardiacSimulation::Run()
00164 {
00165     switch (HeartConfig::Instance()->GetSpaceDimension())
00166     {
00167         case 3:
00168         {
00169             DOMAIN_SWITCH(3);
00170         }
00171         case 2:
00172         {
00173             DOMAIN_SWITCH(2);
00174         }
00175         case 1:
00176         {
00177             DOMAIN_SWITCH(1);
00178         }
00179         default:
00180             // We could check for this too in the XML Schema...
00181             EXCEPTION("Space dimension not supported: should be 1, 2 or 3");
00182     }
00183 }
00184 
00185 // These aren't needed externally
00186 #undef DOMAIN_SWITCH
00187 #undef DOMAIN_CASE
00188