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_ROSENBROCK4_DENSE_OUTPUT_HPP_INCLUDED
0020 #define BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_DENSE_OUTPUT_HPP_INCLUDED
0021
0022
0023 #include <utility>
0024
0025 #include <boost/numeric/odeint/util/bind.hpp>
0026
0027 #include <boost/numeric/odeint/stepper/rosenbrock4_controller.hpp>
0028 #include <boost/numeric/odeint/util/is_resizeable.hpp>
0029
0030 #include <boost/numeric/odeint/integrate/max_step_checker.hpp>
0031
0032
0033 namespace boost {
0034 namespace numeric {
0035 namespace odeint {
0036
0037 template< class ControlledStepper >
0038 class rosenbrock4_dense_output
0039 {
0040
0041 public:
0042
0043 typedef ControlledStepper controlled_stepper_type;
0044 typedef typename unwrap_reference< controlled_stepper_type >::type unwrapped_controlled_stepper_type;
0045 typedef typename unwrapped_controlled_stepper_type::stepper_type stepper_type;
0046 typedef typename stepper_type::value_type value_type;
0047 typedef typename stepper_type::state_type state_type;
0048 typedef typename stepper_type::wrapped_state_type wrapped_state_type;
0049 typedef typename stepper_type::time_type time_type;
0050 typedef typename stepper_type::deriv_type deriv_type;
0051 typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type;
0052 typedef typename stepper_type::resizer_type resizer_type;
0053 typedef dense_output_stepper_tag stepper_category;
0054
0055 typedef rosenbrock4_dense_output< ControlledStepper > dense_output_stepper_type;
0056
0057 rosenbrock4_dense_output( const controlled_stepper_type &stepper = controlled_stepper_type() )
0058 : m_stepper( stepper ) ,
0059 m_x1() , m_x2() ,
0060 m_current_state_x1( true ) ,
0061 m_t() , m_t_old() , m_dt()
0062 {
0063 }
0064
0065
0066
0067 template< class StateType >
0068 void initialize( const StateType &x0 , time_type t0 , time_type dt0 )
0069 {
0070 m_resizer.adjust_size( x0 , detail::bind( &dense_output_stepper_type::template resize_impl< StateType > , detail::ref( *this ) , detail::_1 ) );
0071 get_current_state() = x0;
0072 m_t = t0;
0073 m_dt = dt0;
0074 }
0075
0076 template< class System >
0077 std::pair< time_type , time_type > do_step( System system )
0078 {
0079 unwrapped_controlled_stepper_type &stepper = m_stepper;
0080 failed_step_checker fail_checker;
0081 controlled_step_result res = fail;
0082 m_t_old = m_t;
0083 do
0084 {
0085 res = stepper.try_step( system , get_current_state() , m_t , get_old_state() , m_dt );
0086 fail_checker();
0087 }
0088 while( res == fail );
0089 stepper.stepper().prepare_dense_output();
0090 this->toggle_current_state();
0091 return std::make_pair( m_t_old , m_t );
0092 }
0093
0094
0095
0096
0097
0098 template< class StateOut >
0099 void calc_state( time_type t , StateOut &x )
0100 {
0101 unwrapped_controlled_stepper_type &stepper = m_stepper;
0102 stepper.stepper().calc_state( t , x , get_old_state() , m_t_old , get_current_state() , m_t );
0103 }
0104
0105 template< class StateOut >
0106 void calc_state( time_type t , const StateOut &x )
0107 {
0108 unwrapped_controlled_stepper_type &stepper = m_stepper;
0109 stepper.stepper().calc_state( t , x , get_old_state() , m_t_old , get_current_state() , m_t );
0110 }
0111
0112
0113 template< class StateType >
0114 void adjust_size( const StateType &x )
0115 {
0116 unwrapped_controlled_stepper_type &stepper = m_stepper;
0117 stepper.adjust_size( x );
0118 resize_impl( x );
0119 }
0120
0121
0122
0123
0124 const state_type& current_state( void ) const
0125 {
0126 return get_current_state();
0127 }
0128
0129 time_type current_time( void ) const
0130 {
0131 return m_t;
0132 }
0133
0134 const state_type& previous_state( void ) const
0135 {
0136 return get_old_state();
0137 }
0138
0139 time_type previous_time( void ) const
0140 {
0141 return m_t_old;
0142 }
0143
0144 time_type current_time_step( void ) const
0145 {
0146 return m_dt;
0147 }
0148
0149
0150
0151
0152 private:
0153
0154 state_type& get_current_state( void )
0155 {
0156 return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ;
0157 }
0158
0159 const state_type& get_current_state( void ) const
0160 {
0161 return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ;
0162 }
0163
0164 state_type& get_old_state( void )
0165 {
0166 return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ;
0167 }
0168
0169 const state_type& get_old_state( void ) const
0170 {
0171 return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ;
0172 }
0173
0174 void toggle_current_state( void )
0175 {
0176 m_current_state_x1 = ! m_current_state_x1;
0177 }
0178
0179
0180 template< class StateIn >
0181 bool resize_impl( const StateIn &x )
0182 {
0183 bool resized = false;
0184 resized |= adjust_size_by_resizeability( m_x1 , x , typename is_resizeable<state_type>::type() );
0185 resized |= adjust_size_by_resizeability( m_x2 , x , typename is_resizeable<state_type>::type() );
0186 return resized;
0187 }
0188
0189
0190 controlled_stepper_type m_stepper;
0191 resizer_type m_resizer;
0192 wrapped_state_type m_x1 , m_x2;
0193 bool m_current_state_x1;
0194 time_type m_t , m_t_old , m_dt;
0195 };
0196
0197
0198
0199 }
0200 }
0201 }
0202
0203
0204 #endif