rosenbrock4_dense_output.hpp 5.0 KB

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