The best way to compute long pieces of trajectory is to use two classes together: DOdeSolver with DTimeMap or LDOdeSolver with LDTimeMap. The class [L]DTimeMap provides interface for computing trajectories over time range and/or variational equations hiding all technical details. Using this approach one can
- manage parameters of step control methods (like relative and absolute tolerances)
- compute intermediate points that appeared during integration (we will call this dense output)
- compute solutions to IVPs as functional objects
Computing solution after fixed time
This is the simplest and perhaps most often used feature of class TimeMap. In order to compute a solution to ODE after a specified time T
one should
- create an instance of ODE solver as described in section One-step Taylor method
capd::dynsys::BasicOdeSolver< capd::DMap > DOdeSolver
Definition: typedefs.h:26
- create an instance of DTimeMap
TimeMap class provides methods for transport of sets (or points) by a given flow over some time inter...
Definition: TimeMap.h:34
- specify initial condition and integrate over the given time
double initialTime = ....;
double finalTime = ...;
DVector y = timeMap(finalTime,u,initialTime);
After the last call we obtain where is local flow induced by our ODE. Complete example will be given in section Error tolerance and step control
- Note
- After integration
initialTime
will be updated to finalTime
- Attention
- This is integration over time
finalTime-initialTIme
and not over finalTime
.
- Note
- For autonomous systems the last argument (
initialTime
) can be skipped.
Computing intermediate points on the trajectory
One can stop long-time integration after each performed time step. This can be obtained by the following request before starting integration
timeMap.stopAfterStep(true);
Then we can use the following loop to integrate over a given time
double initialTime = ....;
double finalTime = ...;
do{
DVector y = timeMap(finalTime,u,initialTime);
cout << "current time=" << timeMap.getCurrentTime() << ", y=" << y << endl;
}while(!timeMap.completed());
Complete example (from examples/odes/DTimeMapExample.cpp):
#include <cstdio>
DMap pendulum(
"time:t;par:omega;var:x,dx;fun:dx,sin(omega*t)-sin(x);");
pendulum.setParameter("omega",1.);
u[0] = 1.;
u[1] = 2.;
double initTime = 4;
double finalTime = 8;
timeMap.stopAfterStep(true);
do{
u = timeMap(finalTime,u,initTime);
printf("t=%6f, x=%6f, dx=%6f\n",initTime,u[0],u[1]);
}while(!timeMap.completed());
return 0;
}
This class is used to represent a map .
Definition: Map.h:125
int main(int argc, char *argv[])
Definition: argdemo.cpp:81
int order
Definition: tayltst.cpp:31
Definition: ApplicationDesc.h:23
Error tolerance and step control
Let be the error of numerical method that approximates exact solution . The class [L]DOdeSolver makes a prediction of time step subject to fix constrains on local errors per unit step. These constraints are standard
- absolute tolerance - we require that is smaller than this quantity (usually we require that the max norm of the Lagrange remainder in the Taylor series is less than absolute tolerance).
- relative tolerance - we require that . This condition is technically difficult to check in the prediction of the time step.
Therefore we assume that the denominator is evaluated for t=0 only, and compute time step subject to constrain
Eventually, the time step is computed subject to
The user can change default values of tolerances or even turn off step control by means of the following methods
double timeStep = ...;
solver.setStep(timeStep);
solver.turnOnStepControl();
double absoluteTolerance = ...;
double relativeTolerance = ...;
solver.setAbsoluteTolerance(absoluteTolerance);
solver.setRelativeTolerance(relativeTolerance);
- Attention
- Using low orders of the Taylor method with very small tolerances usually forces very small time steps and thus integration might be slow.
Complete example (from examples/odes/DTimeMapStepControlExample.cpp):
#include <cstdio>
u[0] = 1.;
u[1] = 2.;
double initTime = 0;
double finalTime = 100;
int stepsCounter = 0;
do{
u = timeMap(finalTime,u,initTime);
stepsCounter++;
printf("x=%.10f, dx=%.10f\n",u[0],u[1]);
printf(
"order=%d, steps=%d\n\n",timeMap.
getSolver().getOrder(),stepsCounter);
}
DMap pendulum(
"time:t;par:omega;var:x,dx;fun:dx,sin(omega*t)-sin(x);");
pendulum.setParameter("omega",1.);
printf("------- Integration of pendulum over time range 0-100 -----------------\n\n");
printf(
"Constant time step %f:\n",
step);
printf("Default step control and default tolerance:\n");
solver.setOrder(10);
printf("Default step control and default tolerance:\n");
double tol = 1e-8;
solver.setAbsoluteTolerance(tol);
solver.setRelativeTolerance(tol);
printf("Default step control with absolute and relative tolerances set to %.1e:\n",tol);
solver.setOrder(20);
printf("Default step control with absolute and relative tolerances set to %.1e:\n",tol);
return 0;
}
void integrate(DTimeMap &timeMap)
Definition: DTimeMapStepControlExample.cpp:6
bool completed() const
For dense output. Returns true if the trajectory has been integrated to the requested time.
Definition: TimeMap_inline.h:114
void turnOnStepControl()
Disables automatic step control.
Definition: TimeMap_inline.h:90
const Solver & getSolver() const
Returns read-only reference to solver used to integrate the system.
Definition: TimeMap_inline.h:44
void stopAfterStep(bool b)
For dense output. If true, integration procedure returns after each successful step....
Definition: TimeMap_inline.h:108
double step
Definition: tayltst.cpp:30