void operator()( void )
    {

        Stepper stepper;
        const int o = stepper.order()+1; //order of the error is order of approximation + 1

        const state_type x0 = {{ 0.0 , 1.0 }};
        state_type x1;
        const double t = 0.0;
        /* do a first step with dt=0.1 to get an estimate on the prefactor of the error dx = f * dt^(order+1) */
        double dt = 0.5;
        stepper.do_step( osc() , x0 , t , x1 , dt );
        const double f = 2.0 * std::abs( sin(dt) - x1[0] ) / std::pow( dt , o ); // upper bound

        std::cout << o << " , " << f << std::endl;

        /* as long as we have errors above machine precision */
        while( f*std::pow( dt , o ) > 1E-16 )
        {
            // reset stepper which require resetting (fsal steppers)
            resetter< typename Stepper::stepper_category >::reset( stepper );

            stepper.do_step( osc() , x0 , t , x1 , dt );
            std::cout << "Testing dt=" << dt << std::endl;
            BOOST_CHECK_LT( std::abs( sin(dt) - x1[0] ) , f*std::pow( dt , o ) );
            dt *= 0.5;
        }
    }
Exemple #2
0
    void operator()( void )
    {
   
        Stepper stepper;
        const int o = stepper.order()+1; //order of the error is order of approximation + 1

        const state_type q0 = {{ 0.0 }};
        const state_type p0 = {{ 1.0 }};
        state_type q1,p1;
        std::pair< state_type , state_type >x1( q1 , p1 );
        const double t = 0.0;
        /* do a first step with dt=0.1 to get an estimate on the prefactor of the error dx = f * dt^(order+1) */
        double dt = 0.5;
        stepper.do_step( osc() , std::make_pair( q0 , p0 ) , t , x1 , dt );
        const double f = 2.0 * std::abs( sin(dt) - x1.first[0] ) / std::pow( dt , o );

        std::cout << o << " , " << f << std::endl;

        /* as long as we have errors above machine precision */
        while( f*std::pow( dt , o ) > 1E-16 )
        {
            stepper.do_step( osc() , std::make_pair( q0 , p0 ) , t , x1 , dt );
            std::cout << "Testing dt=" << dt << std::endl;
            BOOST_CHECK_SMALL( std::abs( sin(dt) - x1.first[0] ) , f*std::pow( dt , o ) );
            dt *= 0.5;
        }
    }
void check_stepper( Stepper &stepper )
{
    typedef Stepper stepper_type;
    typedef typename stepper_type::state_type state_type;
    typedef typename stepper_type::value_type value_type;
    typedef typename stepper_type::deriv_type deriv_type;
    typedef typename stepper_type::time_type time_type;
    typedef typename stepper_type::order_type order_type;
    typedef typename stepper_type::algebra_type algebra_type;
    typedef typename stepper_type::operations_type operations_type;

    const time_type t( 0.0 * si::second );
    time_type dt( 0.1 * si::second );
    state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second );

    // test call method one
    stepper.do_step( oscillator , x , t , dt );

    // test call method two
    stepper.do_step( oscillator , x , t , x , dt );

    // test call method three
    deriv_type dxdt;
    oscillator( x , dxdt , t );
    stepper.do_step( oscillator , x , dxdt , t , dt );

    // test call method four
    oscillator( x , dxdt , t );
    stepper.do_step( oscillator , x , dxdt , t , x , dt );
}
void check_error_stepper_concept( Stepper &stepper , System system , typename Stepper::state_type &x , typename Stepper::state_type &xerr )
{
    typedef Stepper stepper_type;
    typedef typename stepper_type::deriv_type container_type;
    typedef typename stepper_type::order_type order_type;
    typedef typename stepper_type::time_type time_type;

    stepper.do_step( system , x , static_cast<time_type>(0.0) , static_cast<time_type>(0.1) );
    stepper.do_step( system , x , static_cast<time_type>(0.0) , static_cast<time_type>(0.1) , xerr );
}
void check_error_stepper_concept( Stepper &stepper , System system , typename Stepper::state_type &x , typename Stepper::state_type &xerr )
{
    typedef Stepper stepper_type;
    typedef typename stepper_type::deriv_type container_type;
    typedef typename stepper_type::order_type order_type;
    typedef typename stepper_type::time_type time_type;

    stepper.do_step( system , typename boost::add_reference< container_type>::type( x ), 0.0 , 0.1 );
    stepper.do_step( system , typename boost::add_reference< container_type>::type( x ), 0.0 , 0.1 ,  typename boost::add_reference< container_type>::type( xerr ) );

}
Time integrate_n_steps(
        Stepper stepper , System system , State &start_state ,
        Time start_time , Time dt , size_t num_of_steps ,
        Observer observer , dense_output_stepper_tag )
{
    typename odeint::unwrap_reference< Observer >::type &obs = observer;

    Time time = start_time;
    const Time end_time = start_time + static_cast< typename unit_value_type<Time>::type >(num_of_steps) * dt;

    stepper.initialize( start_state , time , dt );

    size_t step = 0;

    while( step < num_of_steps )
    {
        while( less_with_sign( time , stepper.current_time() , stepper.current_time_step() ) )
        {
            stepper.calc_state( time , start_state );
            obs( start_state , time );
            ++step;
            // direct computation of the time avoids error propagation happening when using time += dt
            // we need clumsy type analysis to get boost units working here
            time = start_time + static_cast< typename unit_value_type<Time>::type >(step) * dt;
        }

        // we have not reached the end, do another real step
        if( less_with_sign( stepper.current_time()+stepper.current_time_step() ,
                            end_time ,
                            stepper.current_time_step() ) )
        {
            stepper.do_step( system );
        }
        else if( less_with_sign( stepper.current_time() , end_time , stepper.current_time_step() ) )
        { // do the last step ending exactly on the end point
            stepper.initialize( stepper.current_state() , stepper.current_time() , end_time - stepper.current_time() );
            stepper.do_step( system );
        }
    }

    while( stepper.current_time() < end_time )
    {
        if( less_with_sign( end_time ,
                            stepper.current_time()+stepper.current_time_step() ,
                            stepper.current_time_step() ) )
            stepper.initialize( stepper.current_state() , stepper.current_time() , end_time - stepper.current_time() );
        stepper.do_step( system );
    }

    // observation at end point, only if we ended exactly on the end-point (or above due to finite precision)
    obs( stepper.current_state() , end_time );

    return time;
}
void run( Stepper &stepper , const size_t num_of_steps = 20000000 , const double dt = 1E-10 )
{
    const size_t loops = 20;

    accumulator_type acc;
    timer_type timer;

    srand( 12312354 );

    // transient
    //stepper.reset_init_cond( );
    //for( size_t i = 0 ; i < num_of_steps ; ++i )
    //    stepper.do_step( dt );

    for( size_t n=0 ; n<loops+1 ; ++n )
    {
        stepper.reset_init_cond( );

        timer.restart();
        for( size_t i = 0 ; i < num_of_steps ; ++i )
            stepper.do_step( dt );
        if( n>0 )
        {   // take first run as transient
            acc(timer.elapsed());
            clog.precision(8);
            clog.width(10);
            clog << acc << " " << stepper.state(0) << endl;
        }
    }
    cout << acc << endl;
}
size_t integrate_adaptive(
        Stepper stepper , System system , State &start_state ,
        Time start_time , Time end_time , Time dt ,
        Observer observer , dense_output_stepper_tag )
{
    typename omplext_odeint::unwrap_reference< Observer >::type &obs = observer;

    size_t count = 0;
    stepper.initialize( start_state , start_time , dt );

    while( less_with_sign( stepper.current_time() , end_time , stepper.current_time_step() ) )
    {
        while( less_eq_with_sign( stepper.current_time() + stepper.current_time_step() ,
               end_time ,
               stepper.current_time_step() ) )
        {   //make sure we don't go beyond the end_time
            obs( stepper.current_state() , stepper.current_time() );
            stepper.do_step( system );
            ++count;
        }
        stepper.initialize( stepper.current_state() , stepper.current_time() , end_time - stepper.current_time() );
    }
    obs( stepper.current_state() , stepper.current_time() );
    // overwrite start_state with the final point
    boost::numeric::omplext_odeint::copy( stepper.current_state() , start_state );
    return count;
}
void check_stepper_concept( Stepper &stepper , System system , typename Stepper::deriv_type &x )
{
    typedef Stepper stepper_type;
    typedef typename stepper_type::deriv_type container_type;
    typedef typename stepper_type::order_type order_type;
    typedef typename stepper_type::time_type time_type;

    stepper.do_step( system , x , 0.0 , 0.1 );
}
    void operator()( void )
    {
        Stepper stepper;
        initializing_stepper init_stepper;
        const int o = stepper.order()+1; //order of the error is order of approximation + 1

        const state_type x0 = {{ 0.0 , 1.0 }};
        state_type x1 = x0;
        double t = 0.0;
        double dt = 0.2;
        // initialization, does a number of steps already to fill internal buffer, t is increased
        // we use the rk78 as initializing stepper
        stepper.initialize( boost::ref(init_stepper) , osc() , x1 , t , dt );
        double A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] );
        double phi = std::asin(x1[0]/A) - t;
        // do a number of steps to fill the buffer with results from adams bashforth
        for( size_t n=0 ; n < stepper.steps ; ++n )
        {
            stepper.do_step( osc() , x1 , t , dt );
            t += dt;
        }
        // now we do the actual step
        stepper.do_step( osc() , x1 , t , dt );
        // only examine the error of the adams-bashforth step, not the initialization
        const double f = 2.0 * std::abs( A*sin(t+dt+phi) - x1[0] ) / std::pow( dt , o ); // upper bound
        
        std::cout << o << " , " << f << std::endl;

        /* as long as we have errors above machine precision */
        while( f*std::pow( dt , o ) > 1E-16 )
        {
            x1 = x0;
            t = 0.0;
            stepper.initialize( boost::ref(init_stepper) , osc() , x1 , t , dt );
            A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] );
            phi = std::asin(x1[0]/A) - t;
            // now we do the actual step
            stepper.do_step( osc() , x1 , t , dt );
            // only examine the error of the adams-bashforth step, not the initialization
            std::cout << "Testing dt=" << dt << " , " << std::abs( A*sin(t+dt+phi) - x1[0] ) << std::endl;
            BOOST_CHECK_LT( std::abs( A*sin(t+dt+phi) - x1[0] ) , f*std::pow( dt , o ) );
            dt *= 0.5;
        }
    }
/*!
Returns propagated state and max relative errors in
kinetic energy and magnetic moment of particle.
*/
template<class Stepper> std::tuple<state_t, double, double> trace_trajectory(
	state_t state,
	const double time_step
) {
	using std::fabs;
	using std::max;

	constexpr double propagation_time = 424.1; // seconds, 1/100 of doi above

	Particle_Propagator propagator(proton_charge_mass_ratio);

	const double
		initial_energy = 0.5 * proton_mass * state[1].squaredNorm(),
		initial_magnetic_moment
			= proton_mass
			* std::pow(state[1][1], 2)
			/ (2 * get_earth_dipole(state[0]).norm());

	Stepper stepper;
	double nrj_error = 0, mom_error = 0;
	for (double time = 0; time < propagation_time; time += time_step) {
		stepper.do_step(propagator, state, time, time_step);

		const Eigen::Vector3d
			v(state[1]),
			b(get_earth_dipole(state[0])),
			v_perp_b(v - (v.dot(b) / b.squaredNorm()) * b);

		const double
			current_energy
				= 0.5 * proton_mass * state[1].squaredNorm(),
			current_magnetic_moment
				= proton_mass * v_perp_b.squaredNorm() / (2 * b.norm());

		nrj_error = max(
			nrj_error,
			fabs(current_energy - initial_energy) / initial_energy
		);
		mom_error = max(
			mom_error,
			fabs(current_magnetic_moment - initial_magnetic_moment)
				/ initial_magnetic_moment
		);
	}

	return std::make_tuple(state, nrj_error, mom_error);
}
void check_dense_output_stepper( Stepper &stepper )
{
    typedef Stepper stepper_type;
    typedef typename stepper_type::state_type state_type;
    typedef typename stepper_type::value_type value_type;
    typedef typename stepper_type::deriv_type deriv_type;
    typedef typename stepper_type::time_type time_type;
//    typedef typename stepper_type::order_type order_type;

    time_type t( 0.0 * si::second );
    time_type dt( 0.1 * si::second );
    state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ) , x2;

    stepper.initialize( x , t , dt );
    stepper.do_step( oscillator );
    stepper.calc_state( dt / 2.0 , x2 );
}
Exemple #13
0
size_t integrate_adaptive(
        Stepper stepper , System system , State &start_state ,
        Time start_time , Time end_time , Time dt ,
        Observer observer , stepper_tag
)
{
    size_t steps = boost::numeric::odeint::detail::integrate_const( 
                       stepper , system , start_state , start_time , 
                       end_time , dt , observer , stepper_tag() );
    if( steps*dt < end_time )
    {   //make a last step to end exactly at end_time
        stepper.do_step( system , start_state , steps*dt , end_time-steps*dt );
        steps++;
        typename boost::unwrap_reference< Observer >::type &obs = observer;
        obs( start_state , end_time );
    }
    return steps;
}
size_t integrate_adaptive(
        Stepper stepper , System system , State &start_state ,
        Time start_time , Time end_time , Time dt ,
        Observer observer , stepper_tag
)
{
    size_t steps = static_cast< size_t >( (end_time-start_time)/dt );
    Time end = detail::integrate_n_steps( stepper , system , start_state , start_time ,
                                          dt , steps , observer , stepper_tag() );
    if( less_with_sign( end , end_time , dt ) )
    {   //make a last step to end exactly at end_time
        stepper.do_step( system , start_state , end , end_time - end );
        steps++;
        typename omplext_odeint::unwrap_reference< Observer >::type &obs = observer;
        obs( start_state , end_time );
    }
    return steps;
}
Exemple #15
0
    void operator()( void )
    {
        /* We have to specify the desired precision in advance! */
        mpf_set_default_prec( precision );

        mpf_t eps_ , unity;
        mpf_init( eps_ ); mpf_init( unity );
        mpf_set_d( unity , 1.0 );
        mpf_div_2exp( eps_ , unity , precision-1 ); // 2^(-precision+1) : smallest number that can be represented with used precision
        value_type eps( eps_ );

        Stepper stepper;
        state_type x;
        x = 0.0;

        stepper.do_step( constant_system , x , 0.0 , 0.1 );

        BOOST_MESSAGE( eps );
        BOOST_CHECK_MESSAGE( abs( x - value_type( 0.1 , precision ) ) < eps , x - 0.1 );
    }
Time integrate_n_steps(
        Stepper stepper , System system , State &start_state ,
        Time start_time , Time dt , size_t num_of_steps ,
        Observer observer , stepper_tag )
{
    typename odeint::unwrap_reference< Observer >::type &obs = observer;

    Time time = start_time;

    for( size_t step = 0; step < num_of_steps ; ++step )
    {
        obs( start_state , time );
        stepper.do_step( system , start_state , time , dt );
        // direct computation of the time avoids error propagation happening when using time += dt
        // we need clumsy type analysis to get boost units working here
        time = start_time + static_cast< typename unit_value_type<Time>::type >( step+1 ) * dt;
    }
    obs( start_state , time );

    return time;
}
    typename Stepper::time_type integrate_const_steps(
	Stepper &stepper ,
	DynamicalSystem &system ,
	typename Stepper::container_type &state ,
	typename Stepper::time_type start_time ,
	typename Stepper::time_type dt ,
	size_t num_of_steps ,
	Observer &observer
	)
    {
        stepper.adjust_size( state );
	size_t iteration = 0;
        while( iteration < num_of_steps )
	{
	    observer( start_time , state , system );
            stepper.do_step( system , state , start_time , dt );
            start_time += dt;
	    ++iteration;
        }
	observer( start_time , state , system );

	return start_time;
    }
Exemple #18
0
size_t integrate_adaptive(
        Stepper stepper , System system , State &start_state ,
        Time start_time , Time end_time , Time dt ,
        Observer observer , dense_output_stepper_tag )
{
    typename boost::unwrap_reference< Observer >::type &obs = observer;

    size_t count = 0;
    stepper.initialize( start_state , start_time , dt );

    while( stepper.current_time() < end_time )
    {
        while( stepper.current_time() + stepper.current_time_step() <= end_time )
        {   //make sure we don't go beyond the end_time
            obs( stepper.current_state() , stepper.current_time() );
            stepper.do_step( system );
            ++count;
        }
        stepper.initialize( stepper.current_state() , stepper.current_time() , end_time - stepper.current_time() );
    }
    obs( stepper.current_state() , stepper.current_time() );
    return count;
}