1 /* 2 [auto_generated] 3 boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp 4 5 [begin_description] 6 Implementation of the Adams-Bashforth-Moulton method, a predictor-corrector multistep method. 7 [end_description] 8 9 Copyright 2011-2013 Karsten Ahnert 10 Copyright 2011-2013 Mario Mulansky 11 Copyright 2012 Christoph Koke 12 13 Distributed under the Boost Software License, Version 1.0. 14 (See accompanying file LICENSE_1_0.txt or 15 copy at http://www.boost.org/LICENSE_1_0.txt) 16 */ 17 18 19 #ifndef BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED 20 #define BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED 21 22 23 #include <boost/numeric/odeint/util/bind.hpp> 24 25 #include <boost/numeric/odeint/stepper/stepper_categories.hpp> 26 #include <boost/numeric/odeint/algebra/range_algebra.hpp> 27 #include <boost/numeric/odeint/algebra/default_operations.hpp> 28 #include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp> 29 #include <boost/numeric/odeint/algebra/operations_dispatcher.hpp> 30 31 #include <boost/numeric/odeint/util/state_wrapper.hpp> 32 #include <boost/numeric/odeint/util/resizer.hpp> 33 34 #include <boost/numeric/odeint/stepper/adams_bashforth.hpp> 35 #include <boost/numeric/odeint/stepper/adams_moulton.hpp> 36 37 38 39 namespace boost { 40 namespace numeric { 41 namespace odeint { 42 43 44 template< 45 size_t Steps , 46 class State , 47 class Value = double , 48 class Deriv = State , 49 class Time = Value , 50 class Algebra = typename algebra_dispatcher< State >::algebra_type , 51 class Operations = typename operations_dispatcher< State >::operations_type , 52 class Resizer = initially_resizer, 53 class InitializingStepper = runge_kutta4< State , Value , Deriv , Time , Algebra , Operations, Resizer > 54 > 55 class adams_bashforth_moulton 56 { 57 58 #ifndef DOXYGEN_SKIP 59 BOOST_STATIC_ASSERT(( Steps > 0 )); 60 BOOST_STATIC_ASSERT(( Steps < 9 )); 61 #endif 62 63 public : 64 65 typedef State state_type; 66 typedef state_wrapper< state_type > wrapped_state_type; 67 typedef Value value_type; 68 typedef Deriv deriv_type; 69 typedef state_wrapper< deriv_type > wrapped_deriv_type; 70 typedef Time time_type; 71 typedef Algebra algebra_type; 72 typedef Operations operations_type; 73 typedef Resizer resizer_type; 74 typedef stepper_tag stepper_category; 75 typedef InitializingStepper initializing_stepper_type; 76 77 static const size_t steps = Steps; 78 #ifndef DOXYGEN_SKIP 79 typedef adams_bashforth< steps , state_type , value_type , deriv_type , time_type , algebra_type , operations_type , resizer_type, initializing_stepper_type > adams_bashforth_type; 80 typedef adams_moulton< steps , state_type , value_type , deriv_type , time_type , algebra_type , operations_type , resizer_type > adams_moulton_type; 81 typedef adams_bashforth_moulton< steps , state_type , value_type , deriv_type , time_type , algebra_type , operations_type , resizer_type , initializing_stepper_type> stepper_type; 82 #endif //DOXYGEN_SKIP 83 typedef unsigned short order_type; 84 static const order_type order_value = steps; 85 86 /** \brief Constructs the adams_bashforth class. */ adams_bashforth_moulton(void)87 adams_bashforth_moulton( void ) 88 : m_adams_bashforth() , m_adams_moulton( m_adams_bashforth.algebra() ) 89 , m_x() , m_resizer() 90 { } 91 adams_bashforth_moulton(const algebra_type & algebra)92 adams_bashforth_moulton( const algebra_type &algebra ) 93 : m_adams_bashforth( algebra ) , m_adams_moulton( m_adams_bashforth.algebra() ) 94 , m_x() , m_resizer() 95 { } 96 order(void) const97 order_type order( void ) const { return order_value; } 98 99 template< class System , class StateInOut > do_step(System system,StateInOut & x,time_type t,time_type dt)100 void do_step( System system , StateInOut &x , time_type t , time_type dt ) 101 { 102 do_step_impl1( system , x , t , dt ); 103 } 104 105 /** 106 * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateInOut. 107 */ 108 template< class System , class StateInOut > do_step(System system,const StateInOut & x,time_type t,time_type dt)109 void do_step( System system , const StateInOut &x , time_type t , time_type dt ) 110 { 111 do_step_impl1( system , x , t , dt ); 112 } 113 114 template< class System , class StateIn , class StateOut > do_step(System system,const StateIn & in,time_type t,const StateOut & out,time_type dt)115 void do_step( System system , const StateIn &in , time_type t , const StateOut &out , time_type dt ) 116 { 117 do_step_impl2( system , in , t , out , dt ); 118 } 119 120 /** 121 * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateOut. 122 */ 123 template< class System , class StateIn , class StateOut > do_step(System system,const StateIn & in,time_type t,StateOut & out,time_type dt)124 void do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt ) 125 { 126 do_step_impl2( system , in ,t , out , dt ); 127 } 128 129 130 template< class StateType > adjust_size(const StateType & x)131 void adjust_size( const StateType &x ) 132 { 133 m_adams_bashforth.adjust_size( x ); 134 m_adams_moulton.adjust_size( x ); 135 resize_impl( x ); 136 } 137 138 139 template< class ExplicitStepper , class System , class StateIn > initialize(ExplicitStepper explicit_stepper,System system,StateIn & x,time_type & t,time_type dt)140 void initialize( ExplicitStepper explicit_stepper , System system , StateIn &x , time_type &t , time_type dt ) 141 { 142 m_adams_bashforth.initialize( explicit_stepper , system , x , t , dt ); 143 } 144 145 146 template< class System , class StateIn > initialize(System system,StateIn & x,time_type & t,time_type dt)147 void initialize( System system , StateIn &x , time_type &t , time_type dt ) 148 { 149 m_adams_bashforth.initialize( system , x , t , dt ); 150 } 151 152 reset(void)153 void reset(void) 154 { 155 m_adams_bashforth.reset(); 156 } 157 158 159 160 private: 161 162 template< typename System , typename StateInOut > do_step_impl1(System system,StateInOut & x,time_type t,time_type dt)163 void do_step_impl1( System system , StateInOut &x , time_type t , time_type dt ) 164 { 165 if( m_adams_bashforth.is_initialized() ) 166 { 167 m_resizer.adjust_size( x , detail::bind( &stepper_type::template resize_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) ); 168 m_adams_bashforth.do_step( system , x , t , m_x.m_v , dt ); 169 m_adams_moulton.do_step( system , x , m_x.m_v , t+dt , x , dt , m_adams_bashforth.step_storage() ); 170 } 171 else 172 { 173 m_adams_bashforth.do_step( system , x , t , dt ); 174 } 175 } 176 177 template< typename System , typename StateIn , typename StateInOut > do_step_impl2(System system,StateIn const & in,time_type t,StateInOut & out,time_type dt)178 void do_step_impl2( System system , StateIn const &in , time_type t , StateInOut & out , time_type dt ) 179 { 180 if( m_adams_bashforth.is_initialized() ) 181 { 182 m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) ); 183 m_adams_bashforth.do_step( system , in , t , m_x.m_v , dt ); 184 m_adams_moulton.do_step( system , in , m_x.m_v , t+dt , out , dt , m_adams_bashforth.step_storage() ); 185 } 186 else 187 { 188 m_adams_bashforth.do_step( system , in , t , out , dt ); 189 } 190 } 191 192 193 template< class StateIn > resize_impl(const StateIn & x)194 bool resize_impl( const StateIn &x ) 195 { 196 return adjust_size_by_resizeability( m_x , x , typename is_resizeable< state_type >::type() ); 197 } 198 199 adams_bashforth_type m_adams_bashforth; 200 adams_moulton_type m_adams_moulton; 201 wrapped_state_type m_x; 202 resizer_type m_resizer; 203 }; 204 205 206 /********* DOXYGEN ********/ 207 208 /** 209 * \class adams_bashforth_moulton 210 * \brief The Adams-Bashforth-Moulton multistep algorithm. 211 * 212 * The Adams-Bashforth method is a multi-step predictor-corrector algorithm 213 * with configurable step number. The step number is specified as template 214 * parameter Steps and it then uses the result from the previous Steps steps. 215 * See also 216 * <a href="http://en.wikipedia.org/wiki/Linear_multistep_method">en.wikipedia.org/wiki/Linear_multistep_method</a>. 217 * Currently, a maximum of Steps=8 is supported. 218 * The method is explicit and fulfills the Stepper concept. Step size control 219 * or continuous output are not provided. 220 * 221 * This class derives from algebra_base and inherits its interface via 222 * CRTP (current recurring template pattern). For more details see 223 * algebra_stepper_base. 224 * 225 * \tparam Steps The number of steps (maximal 8). 226 * \tparam State The state type. 227 * \tparam Value The value type. 228 * \tparam Deriv The type representing the time derivative of the state. 229 * \tparam Time The time representing the independent variable - the time. 230 * \tparam Algebra The algebra type. 231 * \tparam Operations The operations type. 232 * \tparam Resizer The resizer policy type. 233 * \tparam InitializingStepper The stepper for the first two steps. 234 */ 235 236 /** 237 * \fn adams_bashforth_moulton::adams_bashforth_moulton( const algebra_type &algebra ) 238 * \brief Constructs the adams_bashforth class. This constructor can be used as a default 239 * constructor if the algebra has a default constructor. 240 * \param algebra A copy of algebra is made and stored. 241 */ 242 243 /** 244 * \fn adams_bashforth_moulton::order( void ) const 245 * \brief Returns the order of the algorithm, which is equal to the number of steps+1. 246 * \return order of the method. 247 */ 248 249 /** 250 * \fn adams_bashforth_moulton::do_step( System system , StateInOut &x , time_type t , time_type dt ) 251 * \brief This method performs one step. It transforms the result in-place. 252 * 253 * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the 254 * Simple System concept. 255 * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x. 256 * \param t The value of the time, at which the step should be performed. 257 * \param dt The step size. 258 */ 259 260 261 /** 262 * \fn adams_bashforth_moulton::do_step( System system , const StateIn &in , time_type t , const StateOut &out , time_type dt ) 263 * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place. 264 * 265 * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the 266 * Simple System concept. 267 * \param in The state of the ODE which should be solved. in is not modified in this method 268 * \param t The value of the time, at which the step should be performed. 269 * \param out The result of the step is written in out. 270 * \param dt The step size. 271 */ 272 273 /** 274 * \fn adams_bashforth_moulton::adjust_size( const StateType &x ) 275 * \brief Adjust the size of all temporaries in the stepper manually. 276 * \param x A state from which the size of the temporaries to be resized is deduced. 277 */ 278 279 /** 280 * \fn adams_bashforth_moulton::initialize( ExplicitStepper explicit_stepper , System system , StateIn &x , time_type &t , time_type dt ) 281 * \brief Initialized the stepper. Does Steps-1 steps with the explicit_stepper to fill the buffer. 282 * \note The state x and time t are updated to the values after Steps-1 initial steps. 283 * \param explicit_stepper the stepper used to fill the buffer of previous step results 284 * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the 285 * Simple System concept. 286 * \param x The initial state of the ODE which should be solved, updated after in this method. 287 * \param t The initial time, updated in this method. 288 * \param dt The step size. 289 */ 290 291 /** 292 * \fn adams_bashforth_moulton::initialize( System system , StateIn &x , time_type &t , time_type dt ) 293 * \brief Initialized the stepper. Does Steps-1 steps using the standard initializing stepper 294 * of the underlying adams_bashforth stepper. 295 * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the 296 * Simple System concept. 297 * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x. 298 * \param t The value of the time, at which the step should be performed. 299 * \param dt The step size. 300 */ 301 302 /** 303 * \fn adams_bashforth_moulton::reset( void ) 304 * \brief Resets the internal buffers of the stepper. 305 */ 306 307 308 } // odeint 309 } // numeric 310 } // boost 311 312 313 314 #endif // BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED 315