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