1 /* 2 [auto_generated] 3 boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp 4 5 [begin_description] 6 Dense output for Rosenbrock 4. 7 [end_description] 8 9 Copyright 2011-2012 Karsten Ahnert 10 Copyright 2011-2015 Mario Mulansky 11 Copyright 2012 Christoph Koke 12 13 Distributed under the Boost Software License, Version 1.0. 14 (See accompanying file LICENSE_1_0.txt or 15 copy at http://www.boost.org/LICENSE_1_0.txt) 16 */ 17 18 19 #ifndef BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_DENSE_OUTPUT_HPP_INCLUDED 20 #define BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_DENSE_OUTPUT_HPP_INCLUDED 21 22 23 #include <utility> 24 25 #include <boost/numeric/odeint/util/bind.hpp> 26 27 #include <boost/numeric/odeint/stepper/rosenbrock4_controller.hpp> 28 #include <boost/numeric/odeint/util/is_resizeable.hpp> 29 30 #include <boost/numeric/odeint/integrate/max_step_checker.hpp> 31 32 33 namespace boost { 34 namespace numeric { 35 namespace odeint { 36 37 template< class ControlledStepper > 38 class rosenbrock4_dense_output 39 { 40 41 public: 42 43 typedef ControlledStepper controlled_stepper_type; 44 typedef typename controlled_stepper_type::stepper_type stepper_type; 45 typedef typename stepper_type::value_type value_type; 46 typedef typename stepper_type::state_type state_type; 47 typedef typename stepper_type::wrapped_state_type wrapped_state_type; 48 typedef typename stepper_type::time_type time_type; 49 typedef typename stepper_type::deriv_type deriv_type; 50 typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type; 51 typedef typename stepper_type::resizer_type resizer_type; 52 typedef dense_output_stepper_tag stepper_category; 53 54 typedef rosenbrock4_dense_output< ControlledStepper > dense_output_stepper_type; 55 rosenbrock4_dense_output(const controlled_stepper_type & stepper=controlled_stepper_type ())56 rosenbrock4_dense_output( const controlled_stepper_type &stepper = controlled_stepper_type() ) 57 : m_stepper( stepper ) , 58 m_x1() , m_x2() , 59 m_current_state_x1( true ) , 60 m_t() , m_t_old() , m_dt() 61 { 62 } 63 64 65 66 template< class StateType > initialize(const StateType & x0,time_type t0,time_type dt0)67 void initialize( const StateType &x0 , time_type t0 , time_type dt0 ) 68 { 69 m_resizer.adjust_size( x0 , detail::bind( &dense_output_stepper_type::template resize_impl< StateType > , detail::ref( *this ) , detail::_1 ) ); 70 get_current_state() = x0; 71 m_t = t0; 72 m_dt = dt0; 73 } 74 75 template< class System > do_step(System system)76 std::pair< time_type , time_type > do_step( System system ) 77 { 78 failed_step_checker fail_checker; // to throw a runtime_error if step size adjustment fails 79 controlled_step_result res = fail; 80 m_t_old = m_t; 81 do 82 { 83 res = m_stepper.try_step( system , get_current_state() , m_t , get_old_state() , m_dt ); 84 fail_checker(); // check for overflow of failed steps 85 } 86 while( res == fail ); 87 m_stepper.stepper().prepare_dense_output(); 88 this->toggle_current_state(); 89 return std::make_pair( m_t_old , m_t ); 90 } 91 92 93 /* 94 * The two overloads are needed in order to solve the forwarding problem. 95 */ 96 template< class StateOut > calc_state(time_type t,StateOut & x)97 void calc_state( time_type t , StateOut &x ) 98 { 99 m_stepper.stepper().calc_state( t , x , get_old_state() , m_t_old , get_current_state() , m_t ); 100 } 101 102 template< class StateOut > calc_state(time_type t,const StateOut & x)103 void calc_state( time_type t , const StateOut &x ) 104 { 105 m_stepper.stepper().calc_state( t , x , get_old_state() , m_t_old , get_current_state() , m_t ); 106 } 107 108 109 template< class StateType > adjust_size(const StateType & x)110 void adjust_size( const StateType &x ) 111 { 112 m_stepper.adjust_size( x ); 113 resize_impl( x ); 114 } 115 116 117 118 current_state(void) const119 const state_type& current_state( void ) const 120 { 121 return get_current_state(); 122 } 123 current_time(void) const124 time_type current_time( void ) const 125 { 126 return m_t; 127 } 128 previous_state(void) const129 const state_type& previous_state( void ) const 130 { 131 return get_old_state(); 132 } 133 previous_time(void) const134 time_type previous_time( void ) const 135 { 136 return m_t_old; 137 } 138 current_time_step(void) const139 time_type current_time_step( void ) const 140 { 141 return m_dt; 142 } 143 144 145 146 147 private: 148 get_current_state(void)149 state_type& get_current_state( void ) 150 { 151 return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ; 152 } 153 get_current_state(void) const154 const state_type& get_current_state( void ) const 155 { 156 return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ; 157 } 158 get_old_state(void)159 state_type& get_old_state( void ) 160 { 161 return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ; 162 } 163 get_old_state(void) const164 const state_type& get_old_state( void ) const 165 { 166 return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ; 167 } 168 toggle_current_state(void)169 void toggle_current_state( void ) 170 { 171 m_current_state_x1 = ! m_current_state_x1; 172 } 173 174 175 template< class StateIn > resize_impl(const StateIn & x)176 bool resize_impl( const StateIn &x ) 177 { 178 bool resized = false; 179 resized |= adjust_size_by_resizeability( m_x1 , x , typename is_resizeable<state_type>::type() ); 180 resized |= adjust_size_by_resizeability( m_x2 , x , typename is_resizeable<state_type>::type() ); 181 return resized; 182 } 183 184 185 controlled_stepper_type m_stepper; 186 resizer_type m_resizer; 187 wrapped_state_type m_x1 , m_x2; 188 bool m_current_state_x1; 189 time_type m_t , m_t_old , m_dt; 190 }; 191 192 193 194 } // namespace odeint 195 } // namespace numeric 196 } // namespace boost 197 198 199 #endif // BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_DENSE_OUTPUT_HPP_INCLUDED 200