File indexing completed on 2025-01-18 09:42:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_NUMERIC_ODEINT_STEPPER_BASE_SYMPLECTIC_RKN_STEPPER_BASE_HPP_INCLUDED
0020 #define BOOST_NUMERIC_ODEINT_STEPPER_BASE_SYMPLECTIC_RKN_STEPPER_BASE_HPP_INCLUDED
0021
0022 #include <boost/array.hpp>
0023
0024 #include <boost/numeric/odeint/util/bind.hpp>
0025 #include <boost/numeric/odeint/util/unwrap_reference.hpp>
0026
0027 #include <boost/numeric/odeint/util/copy.hpp>
0028 #include <boost/numeric/odeint/util/is_pair.hpp>
0029
0030 #include <boost/numeric/odeint/util/state_wrapper.hpp>
0031 #include <boost/numeric/odeint/util/resizer.hpp>
0032
0033 #include <boost/numeric/odeint/stepper/stepper_categories.hpp>
0034
0035 #include <boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp>
0036
0037
0038
0039
0040 namespace boost {
0041 namespace numeric {
0042 namespace odeint {
0043
0044
0045 template<
0046 size_t NumOfStages ,
0047 unsigned short Order ,
0048 class Coor ,
0049 class Momentum ,
0050 class Value ,
0051 class CoorDeriv ,
0052 class MomentumDeriv ,
0053 class Time ,
0054 class Algebra ,
0055 class Operations ,
0056 class Resizer
0057 >
0058 class symplectic_nystroem_stepper_base : public algebra_stepper_base< Algebra , Operations >
0059 {
0060
0061 public:
0062
0063 typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type;
0064 typedef typename algebra_stepper_base_type::algebra_type algebra_type;
0065 typedef typename algebra_stepper_base_type::operations_type operations_type;
0066
0067 const static size_t num_of_stages = NumOfStages;
0068 typedef Coor coor_type;
0069 typedef Momentum momentum_type;
0070 typedef std::pair< coor_type , momentum_type > state_type;
0071 typedef CoorDeriv coor_deriv_type;
0072 typedef state_wrapper< coor_deriv_type> wrapped_coor_deriv_type;
0073 typedef MomentumDeriv momentum_deriv_type;
0074 typedef state_wrapper< momentum_deriv_type > wrapped_momentum_deriv_type;
0075 typedef std::pair< coor_deriv_type , momentum_deriv_type > deriv_type;
0076 typedef Value value_type;
0077 typedef Time time_type;
0078 typedef Resizer resizer_type;
0079 typedef stepper_tag stepper_category;
0080
0081 #ifndef DOXYGEN_SKIP
0082 typedef symplectic_nystroem_stepper_base< NumOfStages , Order , Coor , Momentum , Value ,
0083 CoorDeriv , MomentumDeriv , Time , Algebra , Operations , Resizer > internal_stepper_base_type;
0084 #endif
0085 typedef unsigned short order_type;
0086
0087 static const order_type order_value = Order;
0088
0089 typedef boost::array< value_type , num_of_stages > coef_type;
0090
0091 symplectic_nystroem_stepper_base( const coef_type &coef_a , const coef_type &coef_b , const algebra_type &algebra = algebra_type() )
0092 : algebra_stepper_base_type( algebra ) , m_coef_a( coef_a ) , m_coef_b( coef_b ) ,
0093 m_dqdt_resizer() , m_dpdt_resizer() , m_dqdt() , m_dpdt()
0094 { }
0095
0096
0097 order_type order( void ) const
0098 {
0099 return order_value;
0100 }
0101
0102
0103
0104
0105
0106
0107 template< class System , class StateInOut >
0108 void do_step( System system , const StateInOut &state , time_type t , time_type dt )
0109 {
0110 typedef typename odeint::unwrap_reference< System >::type system_type;
0111 do_step_impl( system , state , t , state , dt , typename is_pair< system_type >::type() );
0112 }
0113
0114
0115
0116
0117
0118 template< class System , class StateInOut >
0119 void do_step( System system , StateInOut &state , time_type t , time_type dt )
0120 {
0121 typedef typename odeint::unwrap_reference< System >::type system_type;
0122 do_step_impl( system , state , t , state , dt , typename is_pair< system_type >::type() );
0123 }
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 template< class System , class CoorInOut , class MomentumInOut >
0136 void do_step( System system , CoorInOut &q , MomentumInOut &p , time_type t , time_type dt )
0137 {
0138 do_step( system , std::make_pair( detail::ref( q ) , detail::ref( p ) ) , t , dt );
0139 }
0140
0141
0142
0143
0144
0145 template< class System , class CoorInOut , class MomentumInOut >
0146 void do_step( System system , const CoorInOut &q , const MomentumInOut &p , time_type t , time_type dt )
0147 {
0148 do_step( system , std::make_pair( detail::ref( q ) , detail::ref( p ) ) , t , dt );
0149 }
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 typedef typename odeint::unwrap_reference< System >::type system_type;
0164 do_step_impl( system , in , t , out , dt , typename is_pair< system_type >::type() );
0165 }
0166
0167
0168 template< class StateType >
0169 void adjust_size( const StateType &x )
0170 {
0171 resize_dqdt( x );
0172 resize_dpdt( x );
0173 }
0174
0175
0176 const coef_type& coef_a( void ) const { return m_coef_a; }
0177
0178
0179 const coef_type& coef_b( void ) const { return m_coef_b; }
0180
0181 private:
0182
0183
0184 template< class System , class StateIn , class StateOut >
0185 void do_step_impl( System system , const StateIn &in , time_type , StateOut &out , time_type dt , boost::mpl::true_ )
0186 {
0187 typedef typename odeint::unwrap_reference< System >::type system_type;
0188 typedef typename odeint::unwrap_reference< typename system_type::first_type >::type coor_deriv_func_type;
0189 typedef typename odeint::unwrap_reference< typename system_type::second_type >::type momentum_deriv_func_type;
0190 system_type &sys = system;
0191 coor_deriv_func_type &coor_func = sys.first;
0192 momentum_deriv_func_type &momentum_func = sys.second;
0193
0194 typedef typename odeint::unwrap_reference< StateIn >::type state_in_type;
0195 typedef typename odeint::unwrap_reference< typename state_in_type::first_type >::type coor_in_type;
0196 typedef typename odeint::unwrap_reference< typename state_in_type::second_type >::type momentum_in_type;
0197 const state_in_type &state_in = in;
0198 const coor_in_type &coor_in = state_in.first;
0199 const momentum_in_type &momentum_in = state_in.second;
0200
0201 typedef typename odeint::unwrap_reference< StateOut >::type state_out_type;
0202 typedef typename odeint::unwrap_reference< typename state_out_type::first_type >::type coor_out_type;
0203 typedef typename odeint::unwrap_reference< typename state_out_type::second_type >::type momentum_out_type;
0204 state_out_type &state_out = out;
0205 coor_out_type &coor_out = state_out.first;
0206 momentum_out_type &momentum_out = state_out.second;
0207
0208 m_dqdt_resizer.adjust_size( coor_in , detail::bind( &internal_stepper_base_type::template resize_dqdt< coor_in_type > , detail::ref( *this ) , detail::_1 ) );
0209 m_dpdt_resizer.adjust_size( momentum_in , detail::bind( &internal_stepper_base_type::template resize_dpdt< momentum_in_type > , detail::ref( *this ) , detail::_1 ) );
0210
0211
0212
0213 for( size_t l=0 ; l<num_of_stages ; ++l )
0214 {
0215 if( l == 0 )
0216 {
0217 coor_func( momentum_in , m_dqdt.m_v );
0218 this->m_algebra.for_each3( coor_out , coor_in , m_dqdt.m_v ,
0219 typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_a[l] * dt ) );
0220 momentum_func( coor_out , m_dpdt.m_v );
0221 this->m_algebra.for_each3( momentum_out , momentum_in , m_dpdt.m_v ,
0222 typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_b[l] * dt ) );
0223 }
0224 else
0225 {
0226 coor_func( momentum_out , m_dqdt.m_v );
0227 this->m_algebra.for_each3( coor_out , coor_out , m_dqdt.m_v ,
0228 typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_a[l] * dt ) );
0229 momentum_func( coor_out , m_dpdt.m_v );
0230 this->m_algebra.for_each3( momentum_out , momentum_out , m_dpdt.m_v ,
0231 typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_b[l] * dt ) );
0232 }
0233 }
0234 }
0235
0236
0237
0238 template< class System , class StateIn , class StateOut >
0239 void do_step_impl( System system , const StateIn &in , time_type , StateOut &out , time_type dt , boost::mpl::false_ )
0240 {
0241 typedef typename odeint::unwrap_reference< System >::type momentum_deriv_func_type;
0242 momentum_deriv_func_type &momentum_func = system;
0243
0244 typedef typename odeint::unwrap_reference< StateIn >::type state_in_type;
0245 typedef typename odeint::unwrap_reference< typename state_in_type::first_type >::type coor_in_type;
0246 typedef typename odeint::unwrap_reference< typename state_in_type::second_type >::type momentum_in_type;
0247 const state_in_type &state_in = in;
0248 const coor_in_type &coor_in = state_in.first;
0249 const momentum_in_type &momentum_in = state_in.second;
0250
0251 typedef typename odeint::unwrap_reference< StateOut >::type state_out_type;
0252 typedef typename odeint::unwrap_reference< typename state_out_type::first_type >::type coor_out_type;
0253 typedef typename odeint::unwrap_reference< typename state_out_type::second_type >::type momentum_out_type;
0254 state_out_type &state_out = out;
0255 coor_out_type &coor_out = state_out.first;
0256 momentum_out_type &momentum_out = state_out.second;
0257
0258
0259
0260
0261 m_dpdt_resizer.adjust_size( momentum_in , detail::bind( &internal_stepper_base_type::template resize_dpdt< momentum_in_type > , detail::ref( *this ) , detail::_1 ) );
0262
0263
0264
0265
0266
0267 this->m_algebra.for_each3( coor_out , coor_in , momentum_in ,
0268 typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_a[0] * dt ) );
0269 momentum_func( coor_out , m_dpdt.m_v );
0270 this->m_algebra.for_each3( momentum_out , momentum_in , m_dpdt.m_v ,
0271 typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_b[0] * dt ) );
0272
0273 for( size_t l=1 ; l<num_of_stages ; ++l )
0274 {
0275 this->m_algebra.for_each3( coor_out , coor_out , momentum_out ,
0276 typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_a[l] * dt ) );
0277 momentum_func( coor_out , m_dpdt.m_v );
0278 this->m_algebra.for_each3( momentum_out , momentum_out , m_dpdt.m_v ,
0279 typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_b[l] * dt ) );
0280 }
0281 }
0282
0283 template< class StateIn >
0284 bool resize_dqdt( const StateIn &x )
0285 {
0286 return adjust_size_by_resizeability( m_dqdt , x , typename is_resizeable<coor_deriv_type>::type() );
0287 }
0288
0289 template< class StateIn >
0290 bool resize_dpdt( const StateIn &x )
0291 {
0292 return adjust_size_by_resizeability( m_dpdt , x , typename is_resizeable<momentum_deriv_type>::type() );
0293 }
0294
0295
0296 const coef_type m_coef_a;
0297 const coef_type m_coef_b;
0298
0299 resizer_type m_dqdt_resizer;
0300 resizer_type m_dpdt_resizer;
0301 wrapped_coor_deriv_type m_dqdt;
0302 wrapped_momentum_deriv_type m_dpdt;
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
0421
0422
0423
0424
0425
0426 }
0427 }
0428 }
0429
0430
0431 #endif