00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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());
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);
00126 }
00127
00128
00129 ColumnDataWriter writer(directoryName, baseResultsFilename, cleanDirectory, precision);
00130
00131 if (!PetscTools::AmMaster())
00132 {
00133
00134 return;
00135 }
00136
00137 int time_var_id = writer.DefineUnlimitedDimension("Time", timeUnits);
00138
00139
00140
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 }