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