Tudat/Mathematics/NumericalIntegrators/UnitTests/unitTestRungeKuttaFehlberg56Integrator.cpp
//! Compare with analytical solution of Fehlberg
Compare with analytical solution of Fehlberg
Compare with analytical solution of Fehlberg
BOOST_AUTO_TEST_CASE( test_RungeKuttaFehlberg56_Integrator_Fehlberg_Benchmark )
{
    RungeKuttaCoefficients coeff56 =
        RungeKuttaCoefficients::get( RungeKuttaCoefficients::rungeKuttaFehlberg56);
    double minimumStepSize   = std::numeric_limits< double >::epsilon( );
    double maximumStepSize   = std::numeric_limits< double >::infinity( );
    double initialStepSize   = 1E-6; 
    double relativeTolerance = 1E-16;
    double absoluteTolerance = 1E-16;
    double initialTime = 0.0;
    double finalTime   = 5.0;
    Eigen::Vector2d initialState( exp( 1.0 ), 1.0);
    RungeKuttaVariableStepSizeIntegratorXd integrator56(
                coeff56, computeFehlbergLogirithmicTestODEStateDerivative,
                initialTime, initialState, minimumStepSize,
                maximumStepSize, relativeTolerance, absoluteTolerance );
    Eigen::Vector2d numericalSolution = integrator56.integrateTo( finalTime, initialStepSize );
    Eigen::Vector2d analyticalSolution =
        computeAnalyticalStateFehlbergODE( finalTime, initialState );
    Eigen::Vector2d computedError = numericalSolution - analyticalSolution;
    BOOST_CHECK_SMALL( std::fabs( computedError( 0 ) ), 1E-12 );
    BOOST_CHECK_SMALL( std::fabs( computedError( 1 ) ), 1E-12 );
    Eigen::VectorXd fehlbergError( 2 );
    fehlbergError << 0.1072E-12, -0.2190E-12;
    BOOST_CHECK_SMALL( std::fabs( computedError( 0 ) / fehlbergError( 0 ) ), 3.0);
    BOOST_CHECK_SMALL( std::fabs( computedError( 1 ) / fehlbergError( 1 ) ), 1.0);
}
BOOST_AUTO_TEST_CASE ( test_RungeKuttaFehlberg56_Integrator_Fehlberg_Benchmark ) { RungeKuttaCoefficients coeff56 = RungeKuttaCoefficients :: get ( RungeKuttaCoefficients :: rungeKuttaFehlberg56 ) ; double minimumStepSize = std :: numeric_limits < double > :: epsilon ( ) ; double maximumStepSize = std :: numeric_limits < double > :: infinity ( ) ; double initialStepSize = 1E-6 ; double relativeTolerance = 1E-16 ; double absoluteTolerance = 1E-16 ; double initialTime = 0.0 ; double finalTime = 5.0 ; Eigen :: Vector2d initialState ( exp ( 1.0 ) , 1.0 ) ; RungeKuttaVariableStepSizeIntegratorXd integrator56 ( coeff56 , computeFehlbergLogirithmicTestODEStateDerivative , initialTime , initialState , minimumStepSize , maximumStepSize , relativeTolerance , absoluteTolerance ) ; Eigen :: Vector2d numericalSolution = integrator56 . integrateTo ( finalTime , initialStepSize ) ; Eigen :: Vector2d analyticalSolution = computeAnalyticalStateFehlbergODE ( finalTime , initialState ) ; Eigen :: Vector2d computedError = numericalSolution - analyticalSolution ; BOOST_CHECK_SMALL ( std :: fabs ( computedError ( 0 ) ) , 1E-12 ) ; BOOST_CHECK_SMALL ( std :: fabs ( computedError ( 1 ) ) , 1E-12 ) ; Eigen :: VectorXd fehlbergError ( 2 ) ; fehlbergError << 0.1072E-12 , -0.2190E-12 ; BOOST_CHECK_SMALL ( std :: fabs ( computedError ( 0 ) / fehlbergError ( 0 ) ) , 3.0 ) ; BOOST_CHECK_SMALL ( std :: fabs ( computedError ( 1 ) / fehlbergError ( 1 ) ) , 1.0 ) ; }
Compare with analytical solution of Fehlberg
Compare with analytical solution of Fehlberg
// Integrator settings // Don't make this too small // Initial conditions // Setup integrator // Obtain numerical solution // Analytical solution // (page 30, Fehlberg, E. (1968). Classical Fifth-, Sixth-, Seventh- and Eigth-Order Runge-Kutta // Formulas with Stepsize Control) // Error calculated by -> Fehlberg, E. (1968) page 30 // Initial stepsize unknown.. // Sign check // Not always same sign -> initial step size = 1 or 1E-2, failure: computedError( 1 ),fehlbergError( 1 ) not same sign //    BOOST_CHECK_GE( computedError( 0 ) / fehlbergError( 0 ), 0.0 ); //    BOOST_CHECK_GE( computedError( 1 ) / fehlbergError( 1 ), 0.0 ); // Check error is similar in magnitude