velocity_verlet.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /*
  2. [auto_generated]
  3. libs/numeric/odeint/test/velocity_verlet.cpp
  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. #include <boost/config.hpp>
  14. #ifdef BOOST_MSVC
  15. #pragma warning(disable:4996)
  16. #endif
  17. #define BOOST_TEST_MODULE odeint_velocity_verlet
  18. #define BOOST_FUSION_INVOKE_MAX_ARITY 15
  19. #define BOOST_RESULT_OF_NUM_ARGS 15
  20. #include <boost/numeric/odeint/config.hpp>
  21. #include "resizing_test_state_type.hpp"
  22. #include <boost/numeric/odeint/stepper/velocity_verlet.hpp>
  23. #include <boost/numeric/odeint/algebra/fusion_algebra.hpp>
  24. #include <boost/array.hpp>
  25. #include <boost/test/unit_test.hpp>
  26. #include <boost/units/systems/si/length.hpp>
  27. #include <boost/units/systems/si/time.hpp>
  28. #include <boost/units/systems/si/velocity.hpp>
  29. #include <boost/units/systems/si/acceleration.hpp>
  30. #include <boost/units/systems/si/io.hpp>
  31. #include <boost/fusion/include/vector.hpp>
  32. #include <boost/fusion/include/vector20.hpp>
  33. #include <boost/fusion/container.hpp>
  34. namespace fusion = boost::fusion;
  35. namespace units = boost::units;
  36. namespace si = boost::units::si;
  37. typedef double value_type;
  38. typedef units::quantity< si::time , value_type > time_type;
  39. typedef units::unit< units::derived_dimension< units::time_base_dimension , 2 >::type , si::system > time_2;
  40. typedef units::quantity< time_2 , value_type > time_2_type;
  41. typedef units::quantity< si::length , value_type > length_type;
  42. typedef units::quantity< si::velocity , value_type > velocity_type;
  43. typedef units::quantity< si::acceleration , value_type > acceleration_type;
  44. typedef fusion::vector< length_type , length_type > coor_vector;
  45. typedef fusion::vector< velocity_type , velocity_type > velocity_vector;
  46. typedef fusion::vector< acceleration_type , acceleration_type > accelartion_vector;
  47. using namespace boost::unit_test;
  48. using namespace boost::numeric::odeint;
  49. size_t ode_call_count;
  50. struct velocity_verlet_fixture
  51. {
  52. velocity_verlet_fixture( void ) { ode_call_count = 0; adjust_size_count = 0; }
  53. };
  54. struct ode
  55. {
  56. template< class CoorIn , class MomentumIn , class AccelerationOut , class Time >
  57. void operator()( const CoorIn &q , const MomentumIn &p , AccelerationOut &a , Time t ) const
  58. {
  59. a[0] = -q[0] - p[0];
  60. a[1] = -q[1] - p[1];
  61. ++ode_call_count;
  62. }
  63. };
  64. struct ode_units
  65. {
  66. void operator()( coor_vector const &q , velocity_vector const &p , accelartion_vector &a , time_type t ) const
  67. {
  68. const units::quantity< si::frequency , value_type > omega = 1.0 * si::hertz;
  69. const units::quantity< si::frequency , value_type > friction = 0.001 * si::hertz;
  70. fusion::at_c< 0 >( a ) = omega * omega * fusion::at_c< 0 >( q ) - friction * fusion::at_c< 0 >( p );
  71. fusion::at_c< 1 >( a ) = omega * omega * fusion::at_c< 1 >( q ) - friction * fusion::at_c< 0 >( p );
  72. ++ode_call_count;
  73. }
  74. };
  75. template< class Q , class P >
  76. void init_state( Q &q , P &p )
  77. {
  78. q[0] = 1.0 ; q[1] = 0.5;
  79. p[0] = 2.0 ; p[1] = -1.0;
  80. }
  81. typedef boost::array< double , 2 > array_type;
  82. typedef std::vector< double > vector_type;
  83. typedef velocity_verlet< array_type > array_stepper;
  84. typedef velocity_verlet< vector_type > vector_stepper;
  85. template< typename Resizer >
  86. struct get_resizer_test_stepper
  87. {
  88. typedef velocity_verlet< test_array_type , test_array_type , double , test_array_type ,
  89. double , double , range_algebra , default_operations , Resizer > type;
  90. };
  91. BOOST_AUTO_TEST_SUITE( velocity_verlet_test )
  92. BOOST_FIXTURE_TEST_CASE( test_with_array_ref , velocity_verlet_fixture )
  93. {
  94. array_stepper stepper;
  95. array_type q , p ;
  96. init_state( q , p );
  97. stepper.do_step( ode() , std::make_pair( boost::ref( q ) , boost::ref( p ) ) , 0.0 , 0.01 );
  98. BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) );
  99. }
  100. BOOST_FIXTURE_TEST_CASE( test_with_array_pair , velocity_verlet_fixture )
  101. {
  102. array_stepper stepper;
  103. std::pair< array_type , array_type > xxx;
  104. init_state( xxx.first , xxx.second );
  105. stepper.do_step( ode() , xxx , 0.0 , 0.01 );
  106. BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) );
  107. }
  108. BOOST_FIXTURE_TEST_CASE( test_with_vector_ref , velocity_verlet_fixture )
  109. {
  110. vector_stepper stepper;
  111. vector_type q( 2 ) , p( 2 );
  112. init_state( q , p );
  113. stepper.do_step( ode() , std::make_pair( boost::ref( q ) , boost::ref( p ) ) , 0.0 , 0.01 );
  114. BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) );
  115. }
  116. BOOST_FIXTURE_TEST_CASE( test_with_vector_pair , velocity_verlet_fixture )
  117. {
  118. vector_stepper stepper;
  119. std::pair< vector_type , vector_type > x;
  120. x.first.resize( 2 ) ; x.second.resize( 2 );
  121. init_state( x.first , x.second );
  122. stepper.do_step( ode() , x , 0.0 , 0.01 );
  123. BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) );
  124. }
  125. BOOST_FIXTURE_TEST_CASE( test_initial_resizer , velocity_verlet_fixture )
  126. {
  127. typedef get_resizer_test_stepper< initially_resizer >::type stepper_type;
  128. std::pair< test_array_type , test_array_type > x;
  129. init_state( x.first , x.second );
  130. stepper_type stepper;
  131. stepper.do_step( ode() , x , 0.0 , 0.01 );
  132. stepper.do_step( ode() , x , 0.0 , 0.01 );
  133. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) );
  134. BOOST_CHECK_EQUAL( ode_call_count , size_t( 3 ) );
  135. }
  136. BOOST_FIXTURE_TEST_CASE( test_always_resizer , velocity_verlet_fixture )
  137. {
  138. typedef get_resizer_test_stepper< always_resizer >::type stepper_type;
  139. std::pair< test_array_type , test_array_type > x;
  140. init_state( x.first , x.second );
  141. stepper_type stepper;
  142. stepper.do_step( ode() , x , 0.0 , 0.01 );
  143. stepper.do_step( ode() , x , 0.0 , 0.01 );
  144. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 4 ) );
  145. BOOST_CHECK_EQUAL( ode_call_count , size_t( 4 ) ); // attention: one more system call, since the size of the state has been changed
  146. }
  147. BOOST_FIXTURE_TEST_CASE( test_with_never_resizer , velocity_verlet_fixture )
  148. {
  149. typedef get_resizer_test_stepper< never_resizer >::type stepper_type;
  150. std::pair< test_array_type , test_array_type > x;
  151. init_state( x.first , x.second );
  152. stepper_type stepper;
  153. stepper.do_step( ode() , x , 0.0 , 0.01 );
  154. stepper.do_step( ode() , x , 0.0 , 0.01 );
  155. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 0 ) );
  156. BOOST_CHECK_EQUAL( ode_call_count , size_t( 3 ) );
  157. }
  158. BOOST_FIXTURE_TEST_CASE( test_reset , velocity_verlet_fixture )
  159. {
  160. typedef get_resizer_test_stepper< initially_resizer >::type stepper_type;
  161. std::pair< test_array_type , test_array_type > x;
  162. init_state( x.first , x.second );
  163. stepper_type stepper;
  164. stepper.do_step( ode() , x , 0.0 , 0.01 );
  165. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) );
  166. BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) );
  167. stepper.do_step( ode() , x , 0.0 , 0.01 );
  168. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) );
  169. BOOST_CHECK_EQUAL( ode_call_count , size_t( 3 ) );
  170. stepper.reset();
  171. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) );
  172. BOOST_CHECK_EQUAL( ode_call_count , size_t( 3 ) );
  173. stepper.do_step( ode() , x , 0.0 , 0.01 );
  174. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) );
  175. BOOST_CHECK_EQUAL( ode_call_count , size_t( 5 ) );
  176. }
  177. BOOST_FIXTURE_TEST_CASE( test_initialize1 , velocity_verlet_fixture )
  178. {
  179. typedef get_resizer_test_stepper< initially_resizer >::type stepper_type;
  180. std::pair< test_array_type , test_array_type > x;
  181. init_state( x.first , x.second );
  182. stepper_type stepper;
  183. test_array_type ain;
  184. ode()( x.first , x.second , ain , 0.0 );
  185. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 0 ) );
  186. stepper.initialize( ain );
  187. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) );
  188. BOOST_CHECK_EQUAL( ode_call_count , size_t( 1 ) );
  189. stepper.do_step( ode() , x , 0.0 , 0.01 );
  190. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) );
  191. BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) );
  192. }
  193. BOOST_FIXTURE_TEST_CASE( test_initialize2 , velocity_verlet_fixture )
  194. {
  195. typedef get_resizer_test_stepper< initially_resizer >::type stepper_type;
  196. std::pair< test_array_type , test_array_type > x;
  197. init_state( x.first , x.second );
  198. stepper_type stepper;
  199. stepper.initialize( ode() , x.first , x.second , 0.0 );
  200. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) );
  201. BOOST_CHECK_EQUAL( ode_call_count , size_t( 1 ) );
  202. stepper.do_step( ode() , x , 0.0 , 0.01 );
  203. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) );
  204. BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) );
  205. }
  206. BOOST_FIXTURE_TEST_CASE( test_adjust_size , velocity_verlet_fixture )
  207. {
  208. typedef get_resizer_test_stepper< initially_resizer >::type stepper_type;
  209. std::pair< test_array_type , test_array_type > x;
  210. init_state( x.first , x.second );
  211. stepper_type stepper;
  212. stepper.do_step( ode() , x , 0.0 , 0.01 );
  213. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) );
  214. BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) );
  215. stepper.adjust_size( x.first );
  216. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 4 ) );
  217. BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) );
  218. stepper.do_step( ode() , x , 0.0 , 0.01 );
  219. BOOST_CHECK_EQUAL( adjust_size_count , size_t( 4 ) );
  220. BOOST_CHECK_EQUAL( ode_call_count , size_t( 4 ) );
  221. }
  222. BOOST_FIXTURE_TEST_CASE( test_with_unit_pair , velocity_verlet_fixture )
  223. {
  224. typedef velocity_verlet< coor_vector , velocity_vector , value_type , accelartion_vector ,
  225. time_type , time_2_type , fusion_algebra , default_operations > stepper_type;
  226. std::pair< coor_vector , velocity_vector > x;
  227. fusion::at_c< 0 >( x.first ) = 1.0 * si::meter;
  228. fusion::at_c< 1 >( x.first ) = 0.5 * si::meter;
  229. fusion::at_c< 0 >( x.second ) = 2.0 * si::meter_per_second;
  230. fusion::at_c< 1 >( x.second ) = -1.0 * si::meter_per_second;
  231. stepper_type stepper;
  232. stepper.do_step( ode_units() , x , 0.0 * si::second , 0.01 * si::second );
  233. BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) );
  234. }
  235. BOOST_FIXTURE_TEST_CASE( test_with_unit_ref , velocity_verlet_fixture )
  236. {
  237. typedef velocity_verlet< coor_vector , velocity_vector , value_type , accelartion_vector ,
  238. time_type , time_2_type , fusion_algebra , default_operations > stepper_type;
  239. coor_vector q;
  240. velocity_vector p;
  241. fusion::at_c< 0 >( q ) = 1.0 * si::meter;
  242. fusion::at_c< 1 >( q ) = 0.5 * si::meter;
  243. fusion::at_c< 0 >( p ) = 2.0 * si::meter_per_second;
  244. fusion::at_c< 1 >( p ) = -1.0 * si::meter_per_second;
  245. stepper_type stepper;
  246. stepper.do_step( ode_units() , std::make_pair( boost::ref( q ) , boost::ref( p ) ) , 0.0 * si::second , 0.01 * si::second );
  247. BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) );
  248. }
  249. BOOST_AUTO_TEST_SUITE_END()