• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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