OdeSolution.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
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 #include "OdeSolution.hpp"
00030 #include "AbstractOdeSystem.hpp"
00031 #include "PetscTools.hpp"
00032 #include "ColumnDataWriter.hpp"
00033 #include "Exception.hpp"
00034 
00035 OdeSolution::OdeSolution()
00036    : mNumberOfTimeSteps(0u),
00037      mpOdeSystemInformation()
00038 {
00039 }
00040 
00041 unsigned OdeSolution::GetNumberOfTimeSteps() const
00042 {
00043     return mNumberOfTimeSteps;
00044 }
00045 
00046 void OdeSolution::SetNumberOfTimeSteps(unsigned numTimeSteps)
00047 {
00048     mNumberOfTimeSteps = numTimeSteps;
00049     mTimes.reserve(numTimeSteps+1);
00050     mSolutions.reserve(numTimeSteps);
00051 }
00052 
00053 void OdeSolution::SetOdeSystemInformation(boost::shared_ptr<const AbstractOdeSystemInformation> pOdeSystemInfo)
00054 {
00055     mpOdeSystemInformation = pOdeSystemInfo;
00056 }
00057 
00058 std::vector<double> OdeSolution::GetVariableAtIndex(unsigned index) const
00059 {
00060     std::vector<double> answer;
00061     answer.reserve(mSolutions.size());
00062     for (unsigned i=0; i<mSolutions.size(); i++)
00063     {
00064         answer.push_back(mSolutions[i][index]);
00065     }
00066     return answer;
00067 }
00068 
00069 
00070 
00071 std::vector<double>& OdeSolution::rGetTimes()
00072 {
00073     return mTimes;
00074 }
00075 
00076 const std::vector<double>& OdeSolution::rGetTimes() const
00077 {
00078     return mTimes;
00079 }
00080 
00081 std::vector<std::vector<double> >& OdeSolution::rGetSolutions()
00082 {
00083     return mSolutions;
00084 }
00085 
00086 const std::vector<std::vector<double> >& OdeSolution::rGetSolutions() const
00087 {
00088     return mSolutions;
00089 }
00090 
00091 std::vector<std::vector<double> >& OdeSolution::rGetDerivedQuantities(AbstractOdeSystem* pOdeSystem)
00092 {
00093     assert(pOdeSystem != NULL);
00094     if (mDerivedQuantities.empty() && pOdeSystem->GetNumberOfDerivedQuantities() > 0)
00095     {
00096         assert(mTimes.size() == mSolutions.size()); // Paranoia
00097         mDerivedQuantities.reserve(mTimes.size());
00098         for (unsigned i=0; i<mTimes.size(); i++)
00099         {
00100             mDerivedQuantities.push_back(pOdeSystem->ComputeDerivedQuantities(mTimes[i], mSolutions[i]));
00101         }
00102     }
00103     return mDerivedQuantities;
00104 }
00105 
00106 void OdeSolution::WriteToFile(std::string directoryName,
00107                               std::string baseResultsFilename,
00108                               std::string timeUnits,
00109                               unsigned stepsPerRow,
00110                               bool cleanDirectory,
00111                               unsigned precision,
00112                               bool includeDerivedQuantities,
00113                               AbstractOdeSystem* pOdeSystem)
00114 {
00115     assert(stepsPerRow > 0);
00116     assert(mTimes.size() > 0);
00117     assert(mTimes.size() == mSolutions.size());
00118     assert(mpOdeSystemInformation.get() != NULL);
00119     if (includeDerivedQuantities)
00120     {
00121         if (pOdeSystem == NULL)
00122         {
00123             EXCEPTION("You must provide an ODE system to compute derived quantities.");
00124         }
00125         assert(pOdeSystem->GetSystemInformation() == mpOdeSystemInformation); // Just in case...
00126     }
00127 
00128     // Write data to a file using ColumnDataWriter
00129     ColumnDataWriter writer(directoryName, baseResultsFilename, cleanDirectory, precision);
00130 
00131     if (!PetscTools::AmMaster())
00132     {
00133         //Only the master actually writes to file
00134         return;
00135     }
00136 
00137     int time_var_id = writer.DefineUnlimitedDimension("Time", timeUnits);
00138 
00139     // Either: the ODE system should have no names&units defined, or it should
00140     // the same number as the number of solutions per timestep.
00141     assert( mpOdeSystemInformation->rGetStateVariableNames().size()==0 ||
00142             (mpOdeSystemInformation->rGetStateVariableNames().size()==mSolutions[0].size()) );
00143 
00144     unsigned num_vars = mSolutions[0].size();
00145 
00146     std::vector<int> var_ids;
00147     var_ids.reserve(num_vars);
00148     if (mpOdeSystemInformation->rGetStateVariableNames().size() > 0)
00149     {
00150         for (unsigned i=0; i<num_vars; i++)
00151         {
00152             var_ids.push_back(writer.DefineVariable(mpOdeSystemInformation->rGetStateVariableNames()[i],
00153                                                     mpOdeSystemInformation->rGetStateVariableUnits()[i]));
00154         }
00155     }
00156     else
00157     {
00158         for (unsigned i=0; i<num_vars; i++)
00159         {
00160             std::stringstream string_stream;
00161             string_stream << "var_" << i;
00162             var_ids.push_back(writer.DefineVariable(string_stream.str(), ""));
00163         }
00164     }
00165     
00166     if (includeDerivedQuantities)
00167     {
00168         var_ids.reserve(num_vars + pOdeSystem->GetNumberOfDerivedQuantities());
00169         for (unsigned i=0; i<pOdeSystem->GetNumberOfDerivedQuantities(); i++)
00170         {
00171             var_ids.push_back(writer.DefineVariable(mpOdeSystemInformation->rGetDerivedQuantityNames()[i],
00172                                                     mpOdeSystemInformation->rGetDerivedQuantityUnits()[i]));
00173         }
00174     }
00175 
00176     writer.EndDefineMode();
00177 
00178     for (unsigned i=0; i<mSolutions.size(); i+=stepsPerRow)
00179     {
00180         writer.PutVariable(time_var_id, mTimes[i]);
00181         for (unsigned j=0; j<num_vars; j++)
00182         {
00183             writer.PutVariable(var_ids[j], mSolutions[i][j]);
00184         }
00185         if (includeDerivedQuantities)
00186         {
00187             for (unsigned j=0; j<pOdeSystem->GetNumberOfDerivedQuantities(); j++)
00188             {
00189                 writer.PutVariable(var_ids[j+num_vars], rGetDerivedQuantities(pOdeSystem)[i][j]);
00190             }
00191         }
00192         writer.AdvanceAlongUnlimitedDimension();
00193     }
00194     writer.Close();
00195 }

Generated on Mon Nov 1 12:35:24 2010 for Chaste by  doxygen 1.5.5