rosenbrock4_dense_output.hpp 5.5 KB

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