velocity_verlet.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /*
  2. [auto_generated]
  3. boost/numeric/odeint/stepper/velocity_verlet.hpp
  4. [begin_description]
  5. tba.
  6. [end_description]
  7. Copyright 2009-2012 Karsten Ahnert
  8. Copyright 2009-2012 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_VELOCITY_VERLET_HPP_DEFINED
  14. #define BOOST_NUMERIC_ODEINT_STEPPER_VELOCITY_VERLET_HPP_DEFINED
  15. #include <boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp>
  16. #include <boost/numeric/odeint/stepper/stepper_categories.hpp>
  17. #include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
  18. #include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
  19. #include <boost/numeric/odeint/util/resizer.hpp>
  20. #include <boost/numeric/odeint/util/state_wrapper.hpp>
  21. #include <boost/numeric/odeint/util/unwrap_reference.hpp>
  22. #include <boost/numeric/odeint/util/bind.hpp>
  23. #include <boost/numeric/odeint/util/copy.hpp>
  24. #include <boost/numeric/odeint/util/resizer.hpp>
  25. // #include <boost/numeric/odeint/util/is_pair.hpp>
  26. // #include <array>
  27. namespace boost {
  28. namespace numeric {
  29. namespace odeint {
  30. template <
  31. class Coor ,
  32. class Velocity = Coor ,
  33. class Value = double ,
  34. class Acceleration = Coor ,
  35. class Time = Value ,
  36. class TimeSq = Time ,
  37. class Algebra = typename algebra_dispatcher< Coor >::algebra_type ,
  38. class Operations = typename operations_dispatcher< Coor >::operations_type ,
  39. class Resizer = initially_resizer
  40. >
  41. class velocity_verlet : public algebra_stepper_base< Algebra , Operations >
  42. {
  43. public:
  44. typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type;
  45. typedef typename algebra_stepper_base_type::algebra_type algebra_type;
  46. typedef typename algebra_stepper_base_type::operations_type operations_type;
  47. typedef Coor coor_type;
  48. typedef Velocity velocity_type;
  49. typedef Acceleration acceleration_type;
  50. typedef std::pair< coor_type , velocity_type > state_type;
  51. typedef std::pair< velocity_type , acceleration_type > deriv_type;
  52. typedef state_wrapper< acceleration_type > wrapped_acceleration_type;
  53. typedef Value value_type;
  54. typedef Time time_type;
  55. typedef TimeSq time_square_type;
  56. typedef Resizer resizer_type;
  57. typedef stepper_tag stepper_category;
  58. typedef unsigned short order_type;
  59. static const order_type order_value = 1;
  60. /**
  61. * \return Returns the order of the stepper.
  62. */
  63. order_type order( void ) const
  64. {
  65. return order_value;
  66. }
  67. velocity_verlet( const algebra_type & algebra = algebra_type() )
  68. : algebra_stepper_base_type( algebra ) , m_first_call( true )
  69. , m_a1() , m_a2() , m_current_a1( true ) { }
  70. template< class System , class StateInOut >
  71. void do_step( System system , StateInOut & x , time_type t , time_type dt )
  72. {
  73. do_step_v1( system , x , t , dt );
  74. }
  75. template< class System , class StateInOut >
  76. void do_step( System system , const StateInOut & x , time_type t , time_type dt )
  77. {
  78. do_step_v1( system , x , t , dt );
  79. }
  80. template< class System , class CoorIn , class VelocityIn , class AccelerationIn ,
  81. class CoorOut , class VelocityOut , class AccelerationOut >
  82. void do_step( System system , CoorIn const & qin , VelocityIn const & pin , AccelerationIn const & ain ,
  83. CoorOut & qout , VelocityOut & pout , AccelerationOut & aout , time_type t , time_type dt )
  84. {
  85. const value_type one = static_cast< value_type >( 1.0 );
  86. const value_type one_half = static_cast< value_type >( 0.5 );
  87. algebra_stepper_base_type::m_algebra.for_each4(
  88. qout , qin , pin , ain ,
  89. typename operations_type::template scale_sum3< value_type , time_type , time_square_type >( one , one * dt , one_half * dt * dt ) );
  90. typename odeint::unwrap_reference< System >::type & sys = system;
  91. sys( qout , pin , aout , t + dt );
  92. algebra_stepper_base_type::m_algebra.for_each4(
  93. pout , pin , ain , aout ,
  94. typename operations_type::template scale_sum3< value_type , time_type , time_type >( one , one_half * dt , one_half * dt ) );
  95. }
  96. template< class StateIn >
  97. void adjust_size( const StateIn & x )
  98. {
  99. if( resize_impl( x ) )
  100. m_first_call = true;
  101. }
  102. void reset( void )
  103. {
  104. m_first_call = true;
  105. }
  106. /**
  107. * \fn velocity_verlet::initialize( const AccelerationIn &qin )
  108. * \brief Initializes the internal state of the stepper.
  109. * \param deriv The acceleration of x. The next call of `do_step` expects that the acceleration of `x` passed to `do_step`
  110. * has the value of `qin`.
  111. */
  112. template< class AccelerationIn >
  113. void initialize( const AccelerationIn & ain )
  114. {
  115. // alloc a
  116. m_resizer.adjust_size(ain, [this](auto&& arg) { return this->resize_impl<AccelerationIn>(std::forward<decltype(arg)>(arg)); });
  117. boost::numeric::odeint::copy( ain , get_current_acc() );
  118. m_first_call = false;
  119. }
  120. template< class System , class CoorIn , class VelocityIn >
  121. void initialize( System system , const CoorIn & qin , const VelocityIn & pin , time_type t )
  122. {
  123. m_resizer.adjust_size(qin, [this](auto&& arg) { return this->resize_impl<CoorIn>(std::forward<decltype(arg)>(arg)); });
  124. initialize_acc( system , qin , pin , t );
  125. }
  126. bool is_initialized( void ) const
  127. {
  128. return ! m_first_call;
  129. }
  130. private:
  131. template< class System , class CoorIn , class VelocityIn >
  132. void initialize_acc( System system , const CoorIn & qin , const VelocityIn & pin , time_type t )
  133. {
  134. typename odeint::unwrap_reference< System >::type & sys = system;
  135. sys( qin , pin , get_current_acc() , t );
  136. m_first_call = false;
  137. }
  138. template< class System , class StateInOut >
  139. void do_step_v1( System system , StateInOut & x , time_type t , time_type dt )
  140. {
  141. typedef typename odeint::unwrap_reference< StateInOut >::type state_in_type;
  142. typedef typename odeint::unwrap_reference< typename state_in_type::first_type >::type coor_in_type;
  143. typedef typename odeint::unwrap_reference< typename state_in_type::second_type >::type momentum_in_type;
  144. typedef typename boost::remove_reference< coor_in_type >::type xyz_type;
  145. state_in_type & statein = x;
  146. coor_in_type & qinout = statein.first;
  147. momentum_in_type & pinout = statein.second;
  148. // alloc a
  149. if( m_resizer.adjust_size(qinout, [this](auto&& arg) { return this->resize_impl<xyz_type>(std::forward<decltype(arg)>(arg)); })
  150. || m_first_call )
  151. {
  152. initialize_acc( system , qinout , pinout , t );
  153. }
  154. // check first
  155. do_step( system , qinout , pinout , get_current_acc() , qinout , pinout , get_old_acc() , t , dt );
  156. toggle_current_acc();
  157. }
  158. template< class StateIn >
  159. bool resize_impl( const StateIn & x )
  160. {
  161. bool resized = false;
  162. resized |= adjust_size_by_resizeability( m_a1 , x , typename is_resizeable< acceleration_type >::type() );
  163. resized |= adjust_size_by_resizeability( m_a2 , x , typename is_resizeable< acceleration_type >::type() );
  164. return resized;
  165. }
  166. acceleration_type & get_current_acc( void )
  167. {
  168. return m_current_a1 ? m_a1.m_v : m_a2.m_v ;
  169. }
  170. const acceleration_type & get_current_acc( void ) const
  171. {
  172. return m_current_a1 ? m_a1.m_v : m_a2.m_v ;
  173. }
  174. acceleration_type & get_old_acc( void )
  175. {
  176. return m_current_a1 ? m_a2.m_v : m_a1.m_v ;
  177. }
  178. const acceleration_type & get_old_acc( void ) const
  179. {
  180. return m_current_a1 ? m_a2.m_v : m_a1.m_v ;
  181. }
  182. void toggle_current_acc( void )
  183. {
  184. m_current_a1 = ! m_current_a1;
  185. }
  186. resizer_type m_resizer;
  187. bool m_first_call;
  188. wrapped_acceleration_type m_a1 , m_a2;
  189. bool m_current_a1;
  190. };
  191. /**
  192. * \class velocity_verlet
  193. * \brief The Velocity-Verlet algorithm.
  194. *
  195. * <a href="http://en.wikipedia.org/wiki/Verlet_integration" >The Velocity-Verlet algorithm</a> is a method for simulation of molecular dynamics systems. It solves the ODE
  196. * a=f(r,v',t) where r are the coordinates, v are the velocities and a are the accelerations, hence v = dr/dt, a=dv/dt.
  197. *
  198. * \tparam Coor The type representing the coordinates.
  199. * \tparam Velocity The type representing the velocities.
  200. * \tparam Value The type value type.
  201. * \tparam Acceleration The type representing the acceleration.
  202. * \tparam Time The time representing the independent variable - the time.
  203. * \tparam TimeSq The time representing the square of the time.
  204. * \tparam Algebra The algebra.
  205. * \tparam Operations The operations type.
  206. * \tparam Resizer The resizer policy type.
  207. */
  208. /**
  209. * \fn velocity_verlet::velocity_verlet( const algebra_type &algebra )
  210. * \brief Constructs the velocity_verlet class. This constructor can be used as a default
  211. * constructor if the algebra has a default constructor.
  212. * \param algebra A copy of algebra is made and stored.
  213. */
  214. /**
  215. * \fn velocity_verlet::do_step( System system , StateInOut &x , time_type t , time_type dt )
  216. * \brief This method performs one step. It transforms the result in-place.
  217. *
  218. * It can be used like
  219. * \code
  220. * pair< coordinates , velocities > state;
  221. * stepper.do_step( sys , x , t , dt );
  222. * \endcode
  223. *
  224. * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
  225. * Second Order System concept.
  226. * \param x The state of the ODE which should be solved. The state is pair of Coor and Velocity.
  227. * \param t The value of the time, at which the step should be performed.
  228. * \param dt The step size.
  229. */
  230. /**
  231. * \fn velocity_verlet::do_step( System system , const StateInOut &x , time_type t , time_type dt )
  232. * \brief This method performs one step. It transforms the result in-place.
  233. *
  234. * It can be used like
  235. * \code
  236. * pair< coordinates , velocities > state;
  237. * stepper.do_step( sys , x , t , dt );
  238. * \endcode
  239. *
  240. * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
  241. * Second Order System concept.
  242. * \param x The state of the ODE which should be solved. The state is pair of Coor and Velocity.
  243. * \param t The value of the time, at which the step should be performed.
  244. * \param dt The step size.
  245. */
  246. /**
  247. * \fn velocity_verlet::do_step( System system , CoorIn const & qin , VelocityIn const & pin , AccelerationIn const & ain , CoorOut & qout , VelocityOut & pout , AccelerationOut & aout , time_type t , time_type dt )
  248. * \brief This method performs one step. It transforms the result in-place. Additionally to the other methods
  249. * the coordinates, velocities and accelerations are passed directly to do_step and they are transformed out-of-place.
  250. *
  251. * It can be used like
  252. * \code
  253. * coordinates qin , qout;
  254. * velocities pin , pout;
  255. * accelerations ain, aout;
  256. * stepper.do_step( sys , qin , pin , ain , qout , pout , aout , t , dt );
  257. * \endcode
  258. *
  259. * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
  260. * Second Order System concept.
  261. * \param x The state of the ODE which should be solved. The state is pair of Coor and Velocity.
  262. * \param t The value of the time, at which the step should be performed.
  263. * \param dt The step size.
  264. */
  265. /**
  266. * \fn void velocity_verlet::adjust_size( const StateIn &x )
  267. * \brief Adjust the size of all temporaries in the stepper manually.
  268. * \param x A state from which the size of the temporaries to be resized is deduced.
  269. */
  270. /**
  271. * \fn velocity_verlet::reset( void )
  272. * \brief Resets the internal state of this stepper. After calling this method it is safe to use all
  273. * `do_step` method without explicitly initializing the stepper.
  274. */
  275. /**
  276. * \fn velocity_verlet::initialize( System system , const CoorIn &qin , const VelocityIn &pin , time_type t )
  277. * \brief Initializes the internal state of the stepper.
  278. *
  279. * This method is equivalent to
  280. * \code
  281. * Acceleration a;
  282. * system( qin , pin , a , t );
  283. * stepper.initialize( a );
  284. * \endcode
  285. *
  286. * \param system The system function for the next calls of `do_step`.
  287. * \param qin The current coordinates of the ODE.
  288. * \param pin The current velocities of the ODE.
  289. * \param t The current time of the ODE.
  290. */
  291. /**
  292. * \fn velocity_verlet::is_initialized()
  293. * \returns Returns if the stepper is initialized.
  294. */
  295. } // namespace odeint
  296. } // namespace numeric
  297. } // namespace boost
  298. #endif // BOOST_NUMERIC_ODEINT_STEPPER_VELOCITY_VERLET_HPP_DEFINED