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 #include "AbstractOneStepIvpOdeSolver.hpp"
00031 #include "TimeStepper.hpp"
00032 #include <cassert>
00033 #include <cmath>
00034
00035
00036 const double smidge=1e-10;
00037
00038 OdeSolution AbstractOneStepIvpOdeSolver::Solve(AbstractOdeSystem* pOdeSystem,
00039 std::vector<double>& rYValues,
00040 double startTime,
00041 double endTime,
00042 double timeStep,
00043 double timeSampling)
00044 {
00045 assert(rYValues.size()==pOdeSystem->GetNumberOfStateVariables());
00046 assert(endTime > startTime);
00047 assert(timeStep > 0.0);
00048 assert(timeSampling >= timeStep);
00049
00050 mStoppingEventOccurred = false;
00051 if ( pOdeSystem->CalculateStoppingEvent(startTime, rYValues) == true )
00052 {
00053 EXCEPTION("(Solve with sampling) Stopping event is true for initial condition");
00054 }
00055 TimeStepper stepper(startTime, endTime, timeSampling);
00056
00057
00058 OdeSolution solutions;
00059 solutions.SetNumberOfTimeSteps(stepper.EstimateTimeSteps());
00060 solutions.rGetSolutions().push_back(rYValues);
00061 solutions.rGetTimes().push_back(startTime);
00062
00063 mWorkingMemory.resize(rYValues.size());
00064
00065
00066 while ( !stepper.IsTimeAtEnd() && !mStoppingEventOccurred )
00067 {
00068 InternalSolve(pOdeSystem, rYValues, mWorkingMemory, stepper.GetTime(), stepper.GetNextTime(), timeStep);
00069 stepper.AdvanceOneTimeStep();
00070
00071 solutions.rGetSolutions().push_back(rYValues);
00072
00073 if ( mStoppingEventOccurred )
00074 {
00075 solutions.rGetTimes().push_back(mStoppingTime);
00076 }
00077 else
00078 {
00079 solutions.rGetTimes().push_back(stepper.GetTime());
00080 }
00081 }
00082
00083
00084 solutions.SetNumberOfTimeSteps(stepper.GetTimeStepsElapsed());
00085 return solutions;
00086 }
00087
00088 void AbstractOneStepIvpOdeSolver::Solve(AbstractOdeSystem* pOdeSystem,
00089 std::vector<double>& rYValues,
00090 double startTime,
00091 double endTime,
00092 double timeStep)
00093 {
00094 assert(rYValues.size()==pOdeSystem->GetNumberOfStateVariables());
00095 assert(endTime > startTime);
00096 assert(timeStep > 0.0);
00097
00098 mStoppingEventOccurred = false;
00099 if ( pOdeSystem->CalculateStoppingEvent(startTime, rYValues) == true )
00100 {
00101 EXCEPTION("(Solve without sampling) Stopping event is true for initial condition");
00102 }
00103
00104
00105 mWorkingMemory.resize(rYValues.size());
00106
00107 InternalSolve(pOdeSystem, rYValues, mWorkingMemory, startTime, endTime, timeStep);
00108 }
00109
00110
00111 void AbstractOneStepIvpOdeSolver::InternalSolve(AbstractOdeSystem* pOdeSystem,
00112 std::vector<double>& rYValues,
00113 std::vector<double>& rWorkingMemory,
00114 double startTime,
00115 double endTime,
00116 double timeStep)
00117 {
00118 TimeStepper stepper(startTime, endTime, timeStep);
00119
00120
00121
00122
00123 bool curr_is_curr = false;
00124
00125
00126 assert(!mStoppingEventOccurred);
00127 while ( !stepper.IsTimeAtEnd() && !mStoppingEventOccurred )
00128 {
00129 curr_is_curr = not curr_is_curr;
00130
00131 CalculateNextYValue(pOdeSystem,
00132 stepper.GetNextTimeStep(),
00133 stepper.GetTime(),
00134 curr_is_curr ? rYValues : rWorkingMemory,
00135 curr_is_curr ? rWorkingMemory : rYValues);
00136 stepper.AdvanceOneTimeStep();
00137 if ( pOdeSystem->CalculateStoppingEvent(stepper.GetTime(),
00138 curr_is_curr ? rWorkingMemory : rYValues) == true )
00139 {
00140 mStoppingTime = stepper.GetTime();
00141 mStoppingEventOccurred = true;
00142 }
00143 }
00144
00145 if (curr_is_curr)
00146 {
00147 rYValues.assign(rWorkingMemory.begin(), rWorkingMemory.end());
00148 }
00149 }