OdeSolution.cpp
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
00030
00031
00032
00033
00034
00035
00036 #include "OdeSolution.hpp"
00037
00038 #include <sstream>
00039
00040 #include "ColumnDataWriter.hpp"
00041 #include "Exception.hpp"
00042 #include "PetscTools.hpp"
00043 #include "VectorHelperFunctions.hpp"
00044
00045 OdeSolution::OdeSolution()
00046 : mNumberOfTimeSteps(0u),
00047 mpOdeSystemInformation()
00048 {
00049 }
00050
00051
00052 unsigned OdeSolution::GetNumberOfTimeSteps() const
00053 {
00054 return mNumberOfTimeSteps;
00055 }
00056
00057
00058 void OdeSolution::SetNumberOfTimeSteps(unsigned numTimeSteps)
00059 {
00060 mNumberOfTimeSteps = numTimeSteps;
00061 mTimes.reserve(numTimeSteps+1);
00062 mSolutions.reserve(numTimeSteps);
00063 }
00064
00065
00066 void OdeSolution::SetOdeSystemInformation(boost::shared_ptr<const AbstractOdeSystemInformation> pOdeSystemInfo)
00067 {
00068 mpOdeSystemInformation = pOdeSystemInfo;
00069 }
00070
00071 std::vector<double> OdeSolution::GetVariableAtIndex(unsigned index) const
00072 {
00073 std::vector<double> answer;
00074 answer.reserve(mTimes.size());
00075 double temp_number;
00076 for (unsigned i=0; i< mTimes.size(); ++i)
00077 {
00078 if (index < mSolutions[0].size())
00079 {
00080 temp_number = mSolutions[i][index];
00081 }
00082 else
00083 {
00084 unsigned offset = mSolutions[0].size();
00085 if (index - offset < mParameters.size())
00086 {
00087 temp_number = mParameters[index - offset];
00088 }
00089 else
00090 {
00091 offset += mParameters.size();
00092 if (index - offset < mDerivedQuantities[0].size())
00093 {
00094 temp_number = mDerivedQuantities[i][index - offset];
00095 }
00096 else
00097 {
00098 EXCEPTION("Invalid index passed to ""GetVariableAtIndex()"".");
00099 }
00100 }
00101 }
00102 answer.push_back(temp_number);
00103 }
00104 return answer;
00105 }
00106
00107 std::vector<double> OdeSolution::GetAnyVariable(const std::string& rName) const
00108 {
00109 return GetVariableAtIndex(mpOdeSystemInformation->GetAnyVariableIndex(rName));
00110 }
00111
00112 std::vector<double>& OdeSolution::rGetTimes()
00113 {
00114 return mTimes;
00115 }
00116
00117 const std::vector<double>& OdeSolution::rGetTimes() const
00118 {
00119 return mTimes;
00120 }
00121
00122 std::vector<std::vector<double> >& OdeSolution::rGetSolutions()
00123 {
00124 return mSolutions;
00125 }
00126
00127 const std::vector<std::vector<double> >& OdeSolution::rGetSolutions() const
00128 {
00129 return mSolutions;
00130 }
00131
00132
00133 template<typename VECTOR>
00134 void OdeSolution::CalculateDerivedQuantitiesAndParameters(AbstractParameterisedSystem<VECTOR>* pOdeSystem)
00135 {
00136 assert(pOdeSystem->GetSystemInformation() == mpOdeSystemInformation);
00137 rGetParameters(pOdeSystem);
00138 rGetDerivedQuantities(pOdeSystem);
00139 }
00140
00141
00142 template<typename VECTOR>
00143 std::vector<double>& OdeSolution::rGetParameters(AbstractParameterisedSystem<VECTOR>* pOdeSystem)
00144 {
00145 mParameters.clear();
00146 const unsigned num_params = pOdeSystem->GetNumberOfParameters();
00147 if (num_params > 0)
00148 {
00149 mParameters.reserve(num_params);
00150 for (unsigned i=0; i<num_params; ++i)
00151 {
00152 mParameters.push_back(pOdeSystem->GetParameter(i));
00153 }
00154 }
00155 return mParameters;
00156 }
00157
00158
00159 std::vector<std::vector<double> >& OdeSolution::rGetDerivedQuantities(AbstractParameterisedSystem<std::vector<double> >* pOdeSystem)
00160 {
00161 assert(pOdeSystem != NULL);
00162 if (mDerivedQuantities.empty() && pOdeSystem->GetNumberOfDerivedQuantities() > 0)
00163 {
00164 assert(mTimes.size() == mSolutions.size());
00165 mDerivedQuantities.reserve(mTimes.size());
00166 for (unsigned i=0; i<mTimes.size(); i++)
00167 {
00168 mDerivedQuantities.push_back(pOdeSystem->ComputeDerivedQuantities(mTimes[i], mSolutions[i]));
00169 }
00170 }
00171 return mDerivedQuantities;
00172 }
00173
00174 #ifdef CHASTE_CVODE
00175 std::vector<std::vector<double> >& OdeSolution::rGetDerivedQuantities(AbstractParameterisedSystem<N_Vector>* pOdeSystem)
00176 {
00177 assert(pOdeSystem != NULL);
00178 if (mDerivedQuantities.empty() && pOdeSystem->GetNumberOfDerivedQuantities() > 0)
00179 {
00180 const unsigned num_solutions = mSolutions.size();
00181 assert(mTimes.size() == num_solutions);
00182 mDerivedQuantities.resize(mTimes.size());
00183 N_Vector state_vars = num_solutions > 0 ? N_VNew_Serial(mSolutions[0].size()) : NULL;
00184 for (unsigned i=0; i<num_solutions; i++)
00185 {
00186 CopyFromStdVector(mSolutions[i], state_vars);
00187 N_Vector dqs = pOdeSystem->ComputeDerivedQuantities(mTimes[i], state_vars);
00188 CopyToStdVector(dqs, mDerivedQuantities[i]);
00189 DeleteVector(dqs);
00190 }
00191 DeleteVector(state_vars);
00192 }
00193 assert(mDerivedQuantities.size()==mTimes.size());
00194 return mDerivedQuantities;
00195 }
00196 #endif // CHASTE_CVODE
00197
00198
00199 void OdeSolution::WriteToFile(std::string directoryName,
00200 std::string baseResultsFilename,
00201 std::string timeUnits,
00202 unsigned stepsPerRow,
00203 bool cleanDirectory,
00204 unsigned precision,
00205 bool includeDerivedQuantities)
00206 {
00207 assert(stepsPerRow > 0);
00208 assert(mTimes.size() > 0);
00209 assert(mTimes.size() == mSolutions.size());
00210 assert(mpOdeSystemInformation.get() != NULL);
00211 if (mpOdeSystemInformation->GetNumberOfParameters()==0 && mpOdeSystemInformation->GetNumberOfDerivedQuantities() == 0)
00212 {
00213 includeDerivedQuantities = false;
00214 }
00215
00216 if (includeDerivedQuantities)
00217 {
00218 if ((mDerivedQuantities.empty() || mDerivedQuantities.size()!=mTimes.size()) && mParameters.empty())
00219 {
00220 EXCEPTION("You must first call ""CalculateDerivedQuantitiesAndParameters()"" in order to write derived quantities.");
00221 }
00222 }
00223
00224
00225 ColumnDataWriter writer(directoryName, baseResultsFilename, cleanDirectory, precision);
00226
00227 if (!PetscTools::AmMaster())
00228 {
00229
00230 return;
00231 }
00232
00233 int time_var_id = writer.DefineUnlimitedDimension("Time", timeUnits);
00234
00235
00236
00237 assert( mpOdeSystemInformation->rGetStateVariableNames().size()==0 ||
00238 (mpOdeSystemInformation->rGetStateVariableNames().size()==mSolutions[0].size()) );
00239
00240 unsigned num_vars = mSolutions[0].size();
00241 unsigned num_params = mpOdeSystemInformation->GetNumberOfParameters();
00242 unsigned num_derived_quantities = mpOdeSystemInformation->GetNumberOfDerivedQuantities();
00243
00244 std::vector<int> var_ids;
00245 var_ids.reserve(num_vars);
00246 if (mpOdeSystemInformation->rGetStateVariableNames().size() > 0)
00247 {
00248 for (unsigned i=0; i<num_vars; i++)
00249 {
00250 var_ids.push_back(writer.DefineVariable(mpOdeSystemInformation->rGetStateVariableNames()[i],
00251 mpOdeSystemInformation->rGetStateVariableUnits()[i]));
00252 }
00253 }
00254 else
00255 {
00256 for (unsigned i=0; i<num_vars; i++)
00257 {
00258 std::stringstream string_stream;
00259 string_stream << "var_" << i;
00260 var_ids.push_back(writer.DefineVariable(string_stream.str(), ""));
00261 }
00262 }
00263
00264 if (includeDerivedQuantities)
00265 {
00266 var_ids.reserve(num_vars + num_params + num_derived_quantities);
00267 for (unsigned i=0; i<num_params; ++i)
00268 {
00269 var_ids.push_back(writer.DefineVariable(mpOdeSystemInformation->rGetParameterNames()[i],
00270 mpOdeSystemInformation->rGetParameterUnits()[i]));
00271 }
00272 for (unsigned i=0; i<num_derived_quantities; i++)
00273 {
00274 var_ids.push_back(writer.DefineVariable(mpOdeSystemInformation->rGetDerivedQuantityNames()[i],
00275 mpOdeSystemInformation->rGetDerivedQuantityUnits()[i]));
00276 }
00277 }
00278
00279 if (mSolverName != "")
00280 {
00281 writer.SetCommentForInfoFile("ODE SOLVER: " + mSolverName);
00282 }
00283
00284 writer.EndDefineMode();
00285
00286 for (unsigned i=0; i<mSolutions.size(); i+=stepsPerRow)
00287 {
00288 writer.PutVariable(time_var_id, mTimes[i]);
00289 for (unsigned j=0; j<num_vars; j++)
00290 {
00291 writer.PutVariable(var_ids[j], mSolutions[i][j]);
00292 }
00293 if (includeDerivedQuantities)
00294 {
00295 for (unsigned j=0; j<num_params; ++j)
00296 {
00297 writer.PutVariable(var_ids[j+num_vars], mParameters[j]);
00298 }
00299 for (unsigned j=0; j<num_derived_quantities; j++)
00300 {
00301 writer.PutVariable(var_ids[j+num_params+num_vars], mDerivedQuantities[i][j]);
00302 }
00303 }
00304 writer.AdvanceAlongUnlimitedDimension();
00305 }
00306 writer.Close();
00307 }
00308
00309
00310
00311
00312
00317 template std::vector<double>& OdeSolution::rGetParameters(AbstractParameterisedSystem<std::vector<double> >* pOdeSystem);
00318 template void OdeSolution::CalculateDerivedQuantitiesAndParameters(AbstractParameterisedSystem<std::vector<double> >* pOdeSystem);
00319
00320 #ifdef CHASTE_CVODE
00321 template std::vector<double>& OdeSolution::rGetParameters(AbstractParameterisedSystem<N_Vector>* pOdeSystem);
00322 template void OdeSolution::CalculateDerivedQuantitiesAndParameters(AbstractParameterisedSystem<N_Vector>* pOdeSystem);
00323 #endif // CHASTE_CVODE
00324