File indexing completed on 2025-07-05 08:40:09
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/unwrap_reference.hpp>
0027
0028 #include <boost/numeric/odeint/algebra/range_algebra.hpp>
0029 #include <boost/numeric/odeint/algebra/default_operations.hpp>
0030 #include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
0031 #include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
0032
0033 #include <boost/numeric/odeint/util/state_wrapper.hpp>
0034 #include <boost/numeric/odeint/util/is_resizeable.hpp>
0035 #include <boost/numeric/odeint/util/resizer.hpp>
0036
0037 #include <boost/numeric/odeint/stepper/stepper_categories.hpp>
0038 #include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
0039 #include <boost/numeric/odeint/stepper/extrapolation_stepper.hpp>
0040
0041 #include <boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp>
0042
0043 #include <boost/numeric/odeint/stepper/detail/adams_bashforth_coefficients.hpp>
0044 #include <boost/numeric/odeint/stepper/detail/adams_bashforth_call_algebra.hpp>
0045 #include <boost/numeric/odeint/stepper/detail/rotating_buffer.hpp>
0046
0047 #include <boost/mpl/arithmetic.hpp>
0048 #include <boost/mpl/min_max.hpp>
0049 #include <boost/mpl/equal_to.hpp>
0050
0051 namespace mpl = boost::mpl;
0052
0053
0054 namespace boost {
0055 namespace numeric {
0056 namespace odeint {
0057
0058 using mpl::int_;
0059
0060
0061 template < int N >
0062 struct order_helper
0063 : mpl::max< typename mpl::eval_if<
0064 mpl::equal_to< mpl::modulus< int_< N >, int_< 2 > >,
0065 int_< 0 > >,
0066 int_< N >, int_< N + 1 > >::type,
0067 int_< 4 > >::type
0068 { };
0069
0070 template<
0071 size_t Steps ,
0072 class State ,
0073 class Value = double ,
0074 class Deriv = State ,
0075 class Time = Value ,
0076 class Algebra = typename algebra_dispatcher< State >::algebra_type ,
0077 class Operations = typename operations_dispatcher< State >::operations_type ,
0078 class Resizer = initially_resizer ,
0079 class InitializingStepper = extrapolation_stepper< order_helper<Steps>::value,
0080 State, Value, Deriv, Time,
0081 Algebra, Operations, Resizer >
0082 >
0083 class adams_bashforth : public algebra_stepper_base< Algebra , Operations >
0084 {
0085
0086 #ifndef DOXYGEN_SKIP
0087 static_assert(( Steps > 0 && Steps < 9 ), "Must have between 1 and 8 steps inclusive");
0088 #endif
0089
0090 public :
0091
0092 typedef State state_type;
0093 typedef state_wrapper< state_type > wrapped_state_type;
0094 typedef Value value_type;
0095 typedef Deriv deriv_type;
0096 typedef state_wrapper< deriv_type > wrapped_deriv_type;
0097 typedef Time time_type;
0098 typedef Resizer resizer_type;
0099 typedef stepper_tag stepper_category;
0100
0101 typedef InitializingStepper initializing_stepper_type;
0102
0103 typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type;
0104 typedef typename algebra_stepper_base_type::algebra_type algebra_type;
0105 typedef typename algebra_stepper_base_type::operations_type operations_type;
0106 #ifndef DOXYGEN_SKIP
0107 typedef adams_bashforth< Steps , State , Value , Deriv , Time , Algebra , Operations , Resizer , InitializingStepper > stepper_type;
0108 #endif
0109 static const size_t steps = Steps;
0110
0111
0112
0113 typedef unsigned short order_type;
0114 static const order_type order_value = steps;
0115
0116 typedef detail::rotating_buffer< wrapped_deriv_type , steps > step_storage_type;
0117
0118
0119
0120 order_type order( void ) const { return order_value; }
0121
0122 adams_bashforth( const algebra_type &algebra = algebra_type() )
0123 : algebra_stepper_base_type( algebra ) ,
0124 m_step_storage() , m_resizer() , m_coefficients() ,
0125 m_steps_initialized( 0 ) , m_initializing_stepper()
0126 { }
0127
0128
0129
0130
0131
0132
0133
0134
0135 template< class System , class StateInOut >
0136 void do_step( System system , StateInOut &x , time_type t , time_type dt )
0137 {
0138 do_step( system , x , t , x , dt );
0139 }
0140
0141
0142
0143
0144 template< class System , class StateInOut >
0145 void do_step( System system , const StateInOut &x , time_type t , time_type dt )
0146 {
0147 do_step( system , x , t , x , dt );
0148 }
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158 template< class System , class StateIn , class StateOut >
0159 void do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
0160 {
0161 do_step_impl( system , in , t , out , dt );
0162 }
0163
0164
0165
0166
0167 template< class System , class StateIn , class StateOut >
0168 void do_step( System system , const StateIn &in , time_type t , const StateOut &out , time_type dt )
0169 {
0170 do_step_impl( system , in , t , out , dt );
0171 }
0172
0173
0174 template< class StateType >
0175 void adjust_size( const StateType &x )
0176 {
0177 resize_impl( x );
0178 }
0179
0180 const step_storage_type& step_storage( void ) const
0181 {
0182 return m_step_storage;
0183 }
0184
0185 step_storage_type& step_storage( void )
0186 {
0187 return m_step_storage;
0188 }
0189
0190 template< class ExplicitStepper , class System , class StateIn >
0191 void initialize( ExplicitStepper explicit_stepper , System system , StateIn &x , time_type &t , time_type dt )
0192 {
0193 typename odeint::unwrap_reference< ExplicitStepper >::type &stepper = explicit_stepper;
0194 typename odeint::unwrap_reference< System >::type &sys = system;
0195
0196 m_resizer.adjust_size(x, [this](auto&& arg) { return this->resize_impl<StateIn>(std::forward<decltype(arg)>(arg)); });
0197
0198 for( size_t i=0 ; i+1<steps ; ++i )
0199 {
0200 if( i != 0 ) m_step_storage.rotate();
0201 sys( x , m_step_storage[0].m_v , t );
0202 stepper.do_step_dxdt_impl( system, x, m_step_storage[0].m_v, t,
0203 dt );
0204 t += dt;
0205 }
0206 m_steps_initialized = steps;
0207 }
0208
0209 template< class System , class StateIn >
0210 void initialize( System system , StateIn &x , time_type &t , time_type dt )
0211 {
0212 initialize( std::ref( m_initializing_stepper ) , system , x , t , dt );
0213 }
0214
0215 void reset( void )
0216 {
0217 m_steps_initialized = 0;
0218 }
0219
0220 bool is_initialized( void ) const
0221 {
0222 return m_steps_initialized >= ( steps - 1 );
0223 }
0224
0225 const initializing_stepper_type& initializing_stepper( void ) const { return m_initializing_stepper; }
0226
0227 initializing_stepper_type& initializing_stepper( void ) { return m_initializing_stepper; }
0228
0229 private:
0230
0231 template< class System , class StateIn , class StateOut >
0232 void do_step_impl( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
0233 {
0234 typename odeint::unwrap_reference< System >::type &sys = system;
0235 if( m_resizer.adjust_size(in, [this](auto&& arg) { return this->resize_impl<StateIn>(std::forward<decltype(arg)>(arg)); } ) )
0236 {
0237 m_steps_initialized = 0;
0238 }
0239
0240 if( m_steps_initialized + 1 < steps )
0241 {
0242 if( m_steps_initialized != 0 ) m_step_storage.rotate();
0243 sys( in , m_step_storage[0].m_v , t );
0244 m_initializing_stepper.do_step_dxdt_impl(
0245 system, in, m_step_storage[0].m_v, t, out, dt );
0246 ++m_steps_initialized;
0247 }
0248 else
0249 {
0250 m_step_storage.rotate();
0251 sys( in , m_step_storage[0].m_v , t );
0252 detail::adams_bashforth_call_algebra< steps , algebra_type , operations_type >()( this->m_algebra , in , out , m_step_storage , m_coefficients , dt );
0253 }
0254 }
0255
0256
0257 template< class StateIn >
0258 bool resize_impl( const StateIn &x )
0259 {
0260 bool resized( false );
0261 for( size_t i=0 ; i<steps ; ++i )
0262 {
0263 resized |= adjust_size_by_resizeability( m_step_storage[i] , x , typename is_resizeable<deriv_type>::type() );
0264 }
0265 return resized;
0266 }
0267
0268 step_storage_type m_step_storage;
0269 resizer_type m_resizer;
0270 detail::adams_bashforth_coefficients< value_type , steps > m_coefficients;
0271 size_t m_steps_initialized;
0272 initializing_stepper_type m_initializing_stepper;
0273
0274 };
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 #endif