File indexing completed on 2025-01-18 09:42:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #ifndef BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_HPP_INCLUDED
0022 #define BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_HPP_INCLUDED
0023
0024 #include <boost/static_assert.hpp>
0025
0026 #include <boost/numeric/odeint/util/bind.hpp>
0027 #include <boost/numeric/odeint/util/unwrap_reference.hpp>
0028
0029 #include <boost/numeric/odeint/algebra/range_algebra.hpp>
0030 #include <boost/numeric/odeint/algebra/default_operations.hpp>
0031 #include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
0032 #include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
0033
0034 #include <boost/numeric/odeint/util/state_wrapper.hpp>
0035 #include <boost/numeric/odeint/util/is_resizeable.hpp>
0036 #include <boost/numeric/odeint/util/resizer.hpp>
0037
0038 #include <boost/numeric/odeint/stepper/stepper_categories.hpp>
0039 #include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
0040 #include <boost/numeric/odeint/stepper/extrapolation_stepper.hpp>
0041
0042 #include <boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp>
0043
0044 #include <boost/numeric/odeint/stepper/detail/adams_bashforth_coefficients.hpp>
0045 #include <boost/numeric/odeint/stepper/detail/adams_bashforth_call_algebra.hpp>
0046 #include <boost/numeric/odeint/stepper/detail/rotating_buffer.hpp>
0047
0048 #include <boost/mpl/arithmetic.hpp>
0049 #include <boost/mpl/min_max.hpp>
0050 #include <boost/mpl/equal_to.hpp>
0051
0052 namespace mpl = boost::mpl;
0053
0054
0055 namespace boost {
0056 namespace numeric {
0057 namespace odeint {
0058
0059 using mpl::int_;
0060
0061
0062 template < int N >
0063 struct order_helper
0064 : mpl::max< typename mpl::eval_if<
0065 mpl::equal_to< mpl::modulus< int_< N >, int_< 2 > >,
0066 int_< 0 > >,
0067 int_< N >, int_< N + 1 > >::type,
0068 int_< 4 > >::type
0069 { };
0070
0071 template<
0072 size_t Steps ,
0073 class State ,
0074 class Value = double ,
0075 class Deriv = State ,
0076 class Time = Value ,
0077 class Algebra = typename algebra_dispatcher< State >::algebra_type ,
0078 class Operations = typename operations_dispatcher< State >::operations_type ,
0079 class Resizer = initially_resizer ,
0080 class InitializingStepper = extrapolation_stepper< order_helper<Steps>::value,
0081 State, Value, Deriv, Time,
0082 Algebra, Operations, Resizer >
0083 >
0084 class adams_bashforth : public algebra_stepper_base< Algebra , Operations >
0085 {
0086
0087 #ifndef DOXYGEN_SKIP
0088 BOOST_STATIC_ASSERT(( Steps > 0 ));
0089 BOOST_STATIC_ASSERT(( Steps < 9 ));
0090 #endif
0091
0092 public :
0093
0094 typedef State state_type;
0095 typedef state_wrapper< state_type > wrapped_state_type;
0096 typedef Value value_type;
0097 typedef Deriv deriv_type;
0098 typedef state_wrapper< deriv_type > wrapped_deriv_type;
0099 typedef Time time_type;
0100 typedef Resizer resizer_type;
0101 typedef stepper_tag stepper_category;
0102
0103 typedef InitializingStepper initializing_stepper_type;
0104
0105 typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type;
0106 typedef typename algebra_stepper_base_type::algebra_type algebra_type;
0107 typedef typename algebra_stepper_base_type::operations_type operations_type;
0108 #ifndef DOXYGEN_SKIP
0109 typedef adams_bashforth< Steps , State , Value , Deriv , Time , Algebra , Operations , Resizer , InitializingStepper > stepper_type;
0110 #endif
0111 static const size_t steps = Steps;
0112
0113
0114
0115 typedef unsigned short order_type;
0116 static const order_type order_value = steps;
0117
0118 typedef detail::rotating_buffer< wrapped_deriv_type , steps > step_storage_type;
0119
0120
0121
0122 order_type order( void ) const { return order_value; }
0123
0124 adams_bashforth( const algebra_type &algebra = algebra_type() )
0125 : algebra_stepper_base_type( algebra ) ,
0126 m_step_storage() , m_resizer() , m_coefficients() ,
0127 m_steps_initialized( 0 ) , m_initializing_stepper()
0128 { }
0129
0130
0131
0132
0133
0134
0135
0136
0137 template< class System , class StateInOut >
0138 void do_step( System system , StateInOut &x , time_type t , time_type dt )
0139 {
0140 do_step( system , x , t , x , dt );
0141 }
0142
0143
0144
0145
0146 template< class System , class StateInOut >
0147 void do_step( System system , const StateInOut &x , time_type t , time_type dt )
0148 {
0149 do_step( system , x , t , x , dt );
0150 }
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 template< class System , class StateIn , class StateOut >
0161 void do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
0162 {
0163 do_step_impl( system , in , t , out , dt );
0164 }
0165
0166
0167
0168
0169 template< class System , class StateIn , class StateOut >
0170 void do_step( System system , const StateIn &in , time_type t , const StateOut &out , time_type dt )
0171 {
0172 do_step_impl( system , in , t , out , dt );
0173 }
0174
0175
0176 template< class StateType >
0177 void adjust_size( const StateType &x )
0178 {
0179 resize_impl( x );
0180 }
0181
0182 const step_storage_type& step_storage( void ) const
0183 {
0184 return m_step_storage;
0185 }
0186
0187 step_storage_type& step_storage( void )
0188 {
0189 return m_step_storage;
0190 }
0191
0192 template< class ExplicitStepper , class System , class StateIn >
0193 void initialize( ExplicitStepper explicit_stepper , System system , StateIn &x , time_type &t , time_type dt )
0194 {
0195 typename odeint::unwrap_reference< ExplicitStepper >::type &stepper = explicit_stepper;
0196 typename odeint::unwrap_reference< System >::type &sys = system;
0197
0198 m_resizer.adjust_size( x , detail::bind( &stepper_type::template resize_impl<StateIn> , detail::ref( *this ) , detail::_1 ) );
0199
0200 for( size_t i=0 ; i+1<steps ; ++i )
0201 {
0202 if( i != 0 ) m_step_storage.rotate();
0203 sys( x , m_step_storage[0].m_v , t );
0204 stepper.do_step_dxdt_impl( system, x, m_step_storage[0].m_v, t,
0205 dt );
0206 t += dt;
0207 }
0208 m_steps_initialized = steps;
0209 }
0210
0211 template< class System , class StateIn >
0212 void initialize( System system , StateIn &x , time_type &t , time_type dt )
0213 {
0214 initialize( detail::ref( m_initializing_stepper ) , system , x , t , dt );
0215 }
0216
0217 void reset( void )
0218 {
0219 m_steps_initialized = 0;
0220 }
0221
0222 bool is_initialized( void ) const
0223 {
0224 return m_steps_initialized >= ( steps - 1 );
0225 }
0226
0227 const initializing_stepper_type& initializing_stepper( void ) const { return m_initializing_stepper; }
0228
0229 initializing_stepper_type& initializing_stepper( void ) { return m_initializing_stepper; }
0230
0231 private:
0232
0233 template< class System , class StateIn , class StateOut >
0234 void do_step_impl( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
0235 {
0236 typename odeint::unwrap_reference< System >::type &sys = system;
0237 if( m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl<StateIn> , detail::ref( *this ) , detail::_1 ) ) )
0238 {
0239 m_steps_initialized = 0;
0240 }
0241
0242 if( m_steps_initialized + 1 < steps )
0243 {
0244 if( m_steps_initialized != 0 ) m_step_storage.rotate();
0245 sys( in , m_step_storage[0].m_v , t );
0246 m_initializing_stepper.do_step_dxdt_impl(
0247 system, in, m_step_storage[0].m_v, t, out, dt );
0248 ++m_steps_initialized;
0249 }
0250 else
0251 {
0252 m_step_storage.rotate();
0253 sys( in , m_step_storage[0].m_v , t );
0254 detail::adams_bashforth_call_algebra< steps , algebra_type , operations_type >()( this->m_algebra , in , out , m_step_storage , m_coefficients , dt );
0255 }
0256 }
0257
0258
0259 template< class StateIn >
0260 bool resize_impl( const StateIn &x )
0261 {
0262 bool resized( false );
0263 for( size_t i=0 ; i<steps ; ++i )
0264 {
0265 resized |= adjust_size_by_resizeability( m_step_storage[i] , x , typename is_resizeable<deriv_type>::type() );
0266 }
0267 return resized;
0268 }
0269
0270 step_storage_type m_step_storage;
0271 resizer_type m_resizer;
0272 detail::adams_bashforth_coefficients< value_type , steps > m_coefficients;
0273 size_t m_steps_initialized;
0274 initializing_stepper_type m_initializing_stepper;
0275
0276 };
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414 }
0415 }
0416 }
0417
0418
0419
0420 #endif