Click here to Skip to main content
15,885,882 members
Articles / Programming Languages / CUDA

odeint v2 - Solving ordinary differential equations in C++

Rate me:
Please Sign up or sign in to vote.
4.64/5 (18 votes)
19 Oct 2011CPOL19 min read 129.1K   2.8K   34  
odeint v2 - Solving ordinary differential equations in C++
/*
 [auto_generated]
 boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp

 [begin_description]
 Default Integrate adaptive implementation.
 [end_description]

 Copyright 2009-2011 Karsten Ahnert
 Copyright 2009-2011 Mario Mulansky

 Distributed under the Boost Software License, Version 1.0.
 (See accompanying file LICENSE_1_0.txt or
 copy at http://www.boost.org/LICENSE_1_0.txt)
 */


#ifndef BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_ADAPTIVE_HPP_INCLUDED
#define BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_ADAPTIVE_HPP_INCLUDED

#include <stdexcept>

#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
#include <boost/numeric/odeint/integrate/detail/integrate_const.hpp>

#include <boost/ref.hpp>

namespace boost {
namespace numeric {
namespace odeint {
namespace detail {

/*
 * integrate_adaptive for simple stepper is basically an integrate_const + some last step
 */
template< class Stepper , class System , class State , class Time , class Observer >
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 = integrate_const( stepper , system , start_state ,
            start_time , end_time , dt , observer );
    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;
}


/*
 * classical integrate adpative
 */
template< class Stepper , class System , class State , class Time , class Observer >
size_t integrate_adaptive(
        Stepper stepper , System system , State &start_state ,
        Time &start_time , Time end_time , Time &dt ,
        Observer observer , controlled_stepper_tag
)
{
    typename boost::unwrap_reference< Observer >::type &obs = observer;

    const size_t max_attempts = 1000;
    const char *error_string = "Integrate adaptive : Maximal number of iterations reached. A step size could not be found.";
    size_t count = 0;
    while( start_time < end_time )
    {
        obs( start_state , start_time );
        if( ( start_time + dt ) > end_time )
        {
            dt = end_time - start_time;
        }

        size_t trials = 0;
        controlled_step_result res = success;
        do
        {
            res = stepper.try_step( system , start_state , start_time , dt );
            ++trials;
        }
        while( ( res == fail ) && ( trials < max_attempts ) );
        if( trials == max_attempts ) throw std::overflow_error( error_string );

        ++count;
    }
    obs( start_state , start_time );
    return count;
}


/*
 * integrate adaptive for dense output steppers
 *
 * step size control is used if the stepper supports it
 */
template< class Stepper , class System , class State , class Time , class Observer >
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;
}




} // namespace detail
} // namespace odeint
} // namespace numeric
} // namespace boost


#endif // BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_ADAPTIVE_HPP_INCLUDED

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions