File indexing completed on 2025-01-18 09:42:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_NUMERIC_ODEINT_STEPPER_EXPLICIT_GENERIC_RK_HPP_INCLUDED
0020 #define BOOST_NUMERIC_ODEINT_STEPPER_EXPLICIT_GENERIC_RK_HPP_INCLUDED
0021
0022
0023 #include <boost/array.hpp>
0024
0025
0026 #include <boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp>
0027 #include <boost/numeric/odeint/algebra/range_algebra.hpp>
0028 #include <boost/numeric/odeint/algebra/default_operations.hpp>
0029 #include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
0030 #include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
0031 #include <boost/numeric/odeint/stepper/detail/generic_rk_algorithm.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 namespace boost {
0038 namespace numeric {
0039 namespace odeint {
0040
0041
0042
0043 #ifndef DOXYGEN_SKIP
0044 template<
0045 size_t StageCount,
0046 size_t Order,
0047 class State ,
0048 class Value = double ,
0049 class Deriv = State ,
0050 class Time = Value ,
0051 class Algebra = typename algebra_dispatcher< State >::algebra_type ,
0052 class Operations = typename operations_dispatcher< State >::operations_type ,
0053 class Resizer = initially_resizer
0054 >
0055 class explicit_generic_rk;
0056
0057
0058 struct stage_vector;
0059
0060 template< class T , class Constant >
0061 struct array_wrapper
0062 {
0063 typedef const typename boost::array< T , Constant::value > type;
0064 };
0065
0066 template< class T , size_t i >
0067 struct stage
0068 {
0069 T c;
0070 boost::array< T , i > a;
0071 };
0072
0073
0074 template< class T , class Constant >
0075 struct stage_wrapper
0076 {
0077 typedef stage< T , Constant::value > type;
0078 };
0079 #endif
0080
0081
0082 template<
0083 size_t StageCount,
0084 size_t Order,
0085 class State ,
0086 class Value ,
0087 class Deriv ,
0088 class Time ,
0089 class Algebra ,
0090 class Operations ,
0091 class Resizer
0092 >
0093 #ifndef DOXYGEN_SKIP
0094 class explicit_generic_rk : public explicit_stepper_base<
0095 explicit_generic_rk< StageCount , Order , State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
0096 Order , State , Value , Deriv , Time , Algebra , Operations , Resizer >
0097 #else
0098 class explicit_generic_rk : public explicit_stepper_base
0099 #endif
0100 {
0101
0102 public:
0103
0104 #ifndef DOXYGEN_SKIP
0105 typedef explicit_stepper_base<
0106 explicit_generic_rk< StageCount , Order , State , Value , Deriv ,Time , Algebra , Operations , Resizer > ,
0107 Order , State , Value , Deriv , Time , Algebra ,
0108 Operations , Resizer > stepper_base_type;
0109 #else
0110 typedef explicit_stepper_base< ... > stepper_base_type;
0111 #endif
0112
0113 typedef typename stepper_base_type::state_type state_type;
0114 typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
0115 typedef typename stepper_base_type::value_type value_type;
0116 typedef typename stepper_base_type::deriv_type deriv_type;
0117 typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
0118 typedef typename stepper_base_type::time_type time_type;
0119 typedef typename stepper_base_type::algebra_type algebra_type;
0120 typedef typename stepper_base_type::operations_type operations_type;
0121 typedef typename stepper_base_type::resizer_type resizer_type;
0122
0123 #ifndef DOXYGEN_SKIP
0124 typedef explicit_generic_rk< StageCount , Order , State , Value , Deriv ,Time , Algebra , Operations , Resizer > stepper_type;
0125 #endif
0126
0127 typedef detail::generic_rk_algorithm< StageCount , Value , Algebra , Operations > rk_algorithm_type;
0128
0129 typedef typename rk_algorithm_type::coef_a_type coef_a_type;
0130 typedef typename rk_algorithm_type::coef_b_type coef_b_type;
0131 typedef typename rk_algorithm_type::coef_c_type coef_c_type;
0132
0133 #ifndef DOXYGEN_SKIP
0134 static const size_t stage_count = StageCount;
0135 #endif
0136
0137 public:
0138
0139 explicit_generic_rk( const coef_a_type &a , const coef_b_type &b , const coef_c_type &c ,
0140 const algebra_type &algebra = algebra_type() )
0141 : stepper_base_type( algebra ) , m_rk_algorithm( a , b , c )
0142 { }
0143
0144
0145 template< class System , class StateIn , class DerivIn , class StateOut >
0146 void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt ,
0147 time_type t , StateOut &out , time_type dt )
0148 {
0149 m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl< StateIn > , detail::ref( *this ) , detail::_1 ) );
0150
0151
0152 m_rk_algorithm.do_step( stepper_base_type::m_algebra , system , in , dxdt , t , out , dt , m_x_tmp.m_v , m_F );
0153 }
0154
0155 template< class StateIn >
0156 void adjust_size( const StateIn &x )
0157 {
0158 resize_impl( x );
0159 stepper_base_type::adjust_size( x );
0160 }
0161
0162 private:
0163
0164 template< class StateIn >
0165 bool resize_impl( const StateIn &x )
0166 {
0167 bool resized( false );
0168 resized |= adjust_size_by_resizeability( m_x_tmp , x , typename is_resizeable<state_type>::type() );
0169 for( size_t i = 0 ; i < StageCount-1 ; ++i )
0170 {
0171 resized |= adjust_size_by_resizeability( m_F[i] , x , typename is_resizeable<deriv_type>::type() );
0172 }
0173 return resized;
0174 }
0175
0176
0177 rk_algorithm_type m_rk_algorithm;
0178
0179 resizer_type m_resizer;
0180
0181 wrapped_state_type m_x_tmp;
0182 wrapped_deriv_type m_F[StageCount-1];
0183
0184 };
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243 }
0244 }
0245 }
0246 #endif