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-2012 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 31 namespace boost { 32 namespace numeric { 33 namespace odeint { 34 35 template< class ControlledStepper > 36 class rosenbrock4_dense_output 37 { 38 39 public: 40 41 typedef ControlledStepper controlled_stepper_type; 42 typedef typename controlled_stepper_type::stepper_type stepper_type; 43 typedef typename stepper_type::value_type value_type; 44 typedef typename stepper_type::state_type state_type; 45 typedef typename stepper_type::wrapped_state_type wrapped_state_type; 46 typedef typename stepper_type::time_type time_type; 47 typedef typename stepper_type::deriv_type deriv_type; 48 typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type; 49 typedef typename stepper_type::resizer_type resizer_type; 50 typedef dense_output_stepper_tag stepper_category; 51 52 typedef rosenbrock4_dense_output< ControlledStepper > dense_output_stepper_type; 53 rosenbrock4_dense_output(const controlled_stepper_type & stepper=controlled_stepper_type ())54 rosenbrock4_dense_output( const controlled_stepper_type &stepper = controlled_stepper_type() ) 55 : m_stepper( stepper ) , 56 m_x1() , m_x2() , 57 m_current_state_x1( true ) , 58 m_t() , m_t_old() , m_dt() 59 { 60 } 61 62 63 64 template< class StateType > initialize(const StateType & x0,time_type t0,time_type dt0)65 void initialize( const StateType &x0 , time_type t0 , time_type dt0 ) 66 { 67 m_resizer.adjust_size( x0 , detail::bind( &dense_output_stepper_type::template resize_impl< StateType > , detail::ref( *this ) , detail::_1 ) ); 68 get_current_state() = x0; 69 m_t = t0; 70 m_dt = dt0; 71 } 72 73 template< class System > do_step(System system)74 std::pair< time_type , time_type > do_step( System system ) 75 { 76 const size_t max_count = 1000; 77 78 controlled_step_result res = fail; 79 m_t_old = m_t; 80 size_t count = 0; 81 do 82 { 83 res = m_stepper.try_step( system , get_current_state() , m_t , get_old_state() , m_dt ); 84 if( count++ == max_count ) 85 throw std::overflow_error( "rosenbrock4 : too much iterations!"); 86 } 87 while( res == fail ); 88 m_stepper.stepper().prepare_dense_output(); 89 this->toggle_current_state(); 90 return std::make_pair( m_t_old , m_t ); 91 } 92 93 94 /* 95 * The two overloads are needed in order to solve the forwarding problem. 96 */ 97 template< class StateOut > calc_state(time_type t,StateOut & x)98 void calc_state( time_type t , StateOut &x ) 99 { 100 m_stepper.stepper().calc_state( t , x , get_old_state() , m_t_old , get_current_state() , m_t ); 101 } 102 103 template< class StateOut > calc_state(time_type t,const StateOut & x)104 void calc_state( time_type t , const StateOut &x ) 105 { 106 m_stepper.stepper().calc_state( t , x , get_old_state() , m_t_old , get_current_state() , m_t ); 107 } 108 109 110 template< class StateType > adjust_size(const StateType & x)111 void adjust_size( const StateType &x ) 112 { 113 m_stepper.adjust_size( x ); 114 resize_impl( x ); 115 } 116 117 118 119 current_state(void) const120 const state_type& current_state( void ) const 121 { 122 return get_current_state(); 123 } 124 current_time(void) const125 time_type current_time( void ) const 126 { 127 return m_t; 128 } 129 previous_state(void) const130 const state_type& previous_state( void ) const 131 { 132 return get_old_state(); 133 } 134 previous_time(void) const135 time_type previous_time( void ) const 136 { 137 return m_t_old; 138 } 139 current_time_step(void) const140 time_type current_time_step( void ) const 141 { 142 return m_dt; 143 } 144 145 146 147 148 private: 149 get_current_state(void)150 state_type& get_current_state( void ) 151 { 152 return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ; 153 } 154 get_current_state(void) const155 const state_type& get_current_state( void ) const 156 { 157 return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ; 158 } 159 get_old_state(void)160 state_type& get_old_state( void ) 161 { 162 return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ; 163 } 164 get_old_state(void) const165 const state_type& get_old_state( void ) const 166 { 167 return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ; 168 } 169 toggle_current_state(void)170 void toggle_current_state( void ) 171 { 172 m_current_state_x1 = ! m_current_state_x1; 173 } 174 175 176 template< class StateIn > resize_impl(const StateIn & x)177 bool resize_impl( const StateIn &x ) 178 { 179 bool resized = false; 180 resized |= adjust_size_by_resizeability( m_x1 , x , typename is_resizeable<state_type>::type() ); 181 resized |= adjust_size_by_resizeability( m_x2 , x , typename is_resizeable<state_type>::type() ); 182 return resized; 183 } 184 185 186 controlled_stepper_type m_stepper; 187 resizer_type m_resizer; 188 wrapped_state_type m_x1 , m_x2; 189 bool m_current_state_x1; 190 time_type m_t , m_t_old , m_dt; 191 }; 192 193 194 195 } // namespace odeint 196 } // namespace numeric 197 } // namespace boost 198 199 200 #endif // BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_DENSE_OUTPUT_HPP_INCLUDED 201