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