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