The way error control is handled by the current implementation of the runge kutta variable stepsize integrator is not correct.
The implementation uses the relative error and the higher order estimate to compute an absolute error tolerance and adds the absolute error tolerance to obtain a total tolerance.
The implementation thus computes a total absolute tolerance based on the relative and absolute tolerance that are specified. The way this is implemented is incorrect. Some examples illustrate this:
state = 100 ;
absTol = 1E-5 , relTol = 1E-12 ; total abs tolerance = 1E-5 + 1E-12 * 100 approx equal to 1E-5 ;
absTol = 1E-12 , relTol = 1E-5 ; total abs tolerance = 1E-12 + 1E-5 * 100 approx equal to 1E-3 ;
This means that in case 2, the absolute tolerance is never satisfied and in case 1 the relative tolerance is never satisfied. Effectively, only the least constraining tolerance is used.
This code is used to calculate the total error tolerance:
// Compute error tolerance based on relative and absolute error tolerances. const StateType errorTolerance_ = ( higherOrderEstimate.array( ).abs( ) * relativeErrorTolerance.array( ) ).matrix( ) + absoluteErrorTolerance;
Furthermore, maybe it is better to put the error controler in a different class, such that different methods can be implement.
The way error control is handled by the current implementation of the runge kutta variable stepsize integrator is not correct.
The implementation uses the relative error and the higher order estimate to compute an absolute error tolerance and adds the absolute error tolerance to obtain a total tolerance.
The implementation thus computes a total absolute tolerance based on the relative and absolute tolerance that are specified. The way this is implemented is incorrect. Some examples illustrate this:
state = 100 ;
absTol = 1E-5 , relTol = 1E-12 ; total abs tolerance = 1E-5 + 1E-12 * 100 approx equal to 1E-5 ;
absTol = 1E-12 , relTol = 1E-5 ; total abs tolerance = 1E-12 + 1E-5 * 100 approx equal to 1E-3 ;
This means that in case 2, the absolute tolerance is never satisfied and in case 1 the relative tolerance is never satisfied. Effectively, only the least constraining tolerance is used.
This code is used to calculate the total error tolerance:
// Compute error tolerance based on relative and absolute error tolerances. const StateType errorTolerance_ = ( higherOrderEstimate.array( ).abs( ) * relativeErrorTolerance.array( ) ).matrix( ) + absoluteErrorTolerance;Furthermore, maybe it is better to put the error controler in a different class, such that different methods can be implement.