File indexing completed on 2025-01-18 09:42:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA4_CLASSIC_HPP_INCLUDED
0020 #define BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA4_CLASSIC_HPP_INCLUDED
0021
0022
0023
0024 #include <boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp>
0025 #include <boost/numeric/odeint/algebra/range_algebra.hpp>
0026 #include <boost/numeric/odeint/algebra/default_operations.hpp>
0027 #include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
0028 #include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
0029
0030 #include <boost/numeric/odeint/util/state_wrapper.hpp>
0031 #include <boost/numeric/odeint/util/is_resizeable.hpp>
0032 #include <boost/numeric/odeint/util/resizer.hpp>
0033
0034 namespace boost {
0035 namespace numeric {
0036 namespace odeint {
0037
0038 template<
0039 class State ,
0040 class Value = double ,
0041 class Deriv = State ,
0042 class Time = Value ,
0043 class Algebra = typename algebra_dispatcher< State >::algebra_type ,
0044 class Operations = typename operations_dispatcher< State >::operations_type ,
0045 class Resizer = initially_resizer
0046 >
0047 #ifndef DOXYGEN_SKIP
0048 class runge_kutta4_classic
0049 : public explicit_stepper_base<
0050 runge_kutta4_classic< State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
0051 4 , State , Value , Deriv , Time , Algebra , Operations , Resizer >
0052 #else
0053 class runge_kutta4_classic : public explicit_stepper_base
0054 #endif
0055 {
0056
0057 public :
0058
0059 #ifndef DOXYGEN_SKIP
0060 typedef explicit_stepper_base<
0061 runge_kutta4_classic< State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
0062 4 , State , Value , Deriv , Time , Algebra , Operations , Resizer > stepper_base_type;
0063 #else
0064 typedef explicit_stepper_base< runge_kutta4_classic< ... > , ... > stepper_base_type;
0065 #endif
0066
0067 typedef typename stepper_base_type::state_type state_type;
0068 typedef typename stepper_base_type::value_type value_type;
0069 typedef typename stepper_base_type::deriv_type deriv_type;
0070 typedef typename stepper_base_type::time_type time_type;
0071 typedef typename stepper_base_type::algebra_type algebra_type;
0072 typedef typename stepper_base_type::operations_type operations_type;
0073 typedef typename stepper_base_type::resizer_type resizer_type;
0074
0075 #ifndef DOXYGEN_SKIP
0076 typedef typename stepper_base_type::stepper_type stepper_type;
0077 typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
0078 typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
0079 #endif
0080
0081
0082
0083 runge_kutta4_classic( const algebra_type &algebra = algebra_type() ) : stepper_base_type( algebra )
0084 { }
0085
0086
0087 template< class System , class StateIn , class DerivIn , class StateOut >
0088 void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
0089 {
0090
0091
0092 static const value_type val1 = static_cast< value_type >( 1 );
0093
0094 m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl< StateIn > , detail::ref( *this ) , detail::_1 ) );
0095
0096 typename odeint::unwrap_reference< System >::type &sys = system;
0097
0098 const time_type dh = dt / static_cast< value_type >( 2 );
0099 const time_type th = t + dh;
0100
0101
0102
0103 stepper_base_type::m_algebra.for_each3( m_x_tmp.m_v , in , dxdt ,
0104 typename operations_type::template scale_sum2< value_type , time_type >( val1 , dh ) );
0105
0106
0107
0108 sys( m_x_tmp.m_v , m_dxt.m_v , th );
0109
0110
0111 stepper_base_type::m_algebra.for_each3( m_x_tmp.m_v , in , m_dxt.m_v ,
0112 typename operations_type::template scale_sum2< value_type , time_type >( val1 , dh ) );
0113
0114
0115
0116 sys( m_x_tmp.m_v , m_dxm.m_v , th );
0117
0118 stepper_base_type::m_algebra.for_each3( m_x_tmp.m_v , in , m_dxm.m_v ,
0119 typename operations_type::template scale_sum2< value_type , time_type >( val1 , dt ) );
0120
0121
0122
0123 sys( m_x_tmp.m_v , m_dxh.m_v , t + dt );
0124
0125
0126 time_type dt6 = dt / static_cast< value_type >( 6 );
0127 time_type dt3 = dt / static_cast< value_type >( 3 );
0128 stepper_base_type::m_algebra.for_each6( out , in , dxdt , m_dxt.m_v , m_dxm.m_v , m_dxh.m_v ,
0129 typename operations_type::template scale_sum5< value_type , time_type , time_type , time_type , time_type >( 1.0 , dt6 , dt3 , dt3 , dt6 ) );
0130
0131
0132
0133
0134
0135
0136
0137
0138 }
0139
0140 template< class StateType >
0141 void adjust_size( const StateType &x )
0142 {
0143 resize_impl( x );
0144 stepper_base_type::adjust_size( x );
0145 }
0146
0147 private:
0148
0149 template< class StateIn >
0150 bool resize_impl( const StateIn &x )
0151 {
0152 bool resized = false;
0153 resized |= adjust_size_by_resizeability( m_x_tmp , x , typename is_resizeable<state_type>::type() );
0154 resized |= adjust_size_by_resizeability( m_dxm , x , typename is_resizeable<deriv_type>::type() );
0155 resized |= adjust_size_by_resizeability( m_dxt , x , typename is_resizeable<deriv_type>::type() );
0156 resized |= adjust_size_by_resizeability( m_dxh , x , typename is_resizeable<deriv_type>::type() );
0157 return resized;
0158 }
0159
0160
0161 resizer_type m_resizer;
0162
0163 wrapped_deriv_type m_dxt;
0164 wrapped_deriv_type m_dxm;
0165 wrapped_deriv_type m_dxh;
0166 wrapped_state_type m_x_tmp;
0167
0168 };
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
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 #endif