adams_bashforth.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. [auto_generated]
  3. libs/numeric/odeint/test/adams_bashforth.cpp
  4. [begin_description]
  5. This file tests the use of the adams bashforth stepper.
  6. [end_description]
  7. Copyright 2011-2012 Karsten Ahnert
  8. Copyright 2011-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. // disable checked iterator warning for msvc
  14. #include <boost/config.hpp>
  15. #ifdef BOOST_MSVC
  16. #pragma warning(disable:4996)
  17. #endif
  18. #define BOOST_TEST_MODULE odeint_adams_bashforth
  19. #include <utility>
  20. #include <boost/array.hpp>
  21. #include <boost/test/unit_test.hpp>
  22. #include <boost/mpl/list.hpp>
  23. #include <boost/mpl/size_t.hpp>
  24. #include <boost/mpl/range_c.hpp>
  25. #include <boost/numeric/odeint/stepper/adams_bashforth.hpp>
  26. #include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
  27. using namespace boost::unit_test;
  28. using namespace boost::numeric::odeint;
  29. typedef double value_type;
  30. struct lorenz
  31. {
  32. template< class State , class Deriv , class Value >
  33. void operator()( const State &_x , Deriv &_dxdt , const Value &dt ) const
  34. {
  35. const value_type sigma = 10.0;
  36. const value_type R = 28.0;
  37. const value_type b = 8.0 / 3.0;
  38. typename boost::range_iterator< const State >::type x = boost::begin( _x );
  39. typename boost::range_iterator< Deriv >::type dxdt = boost::begin( _dxdt );
  40. dxdt[0] = sigma * ( x[1] - x[0] );
  41. dxdt[1] = R * x[0] - x[1] - x[0] * x[2];
  42. dxdt[2] = x[0]*x[1] - b * x[2];
  43. }
  44. };
  45. template< class State >
  46. class rk4_decorator
  47. {
  48. public:
  49. size_t do_count;
  50. template< class System , class StateIn , class DerivIn , class StateOut >
  51. void do_step_dxdt_impl( System system , const StateIn &in , const DerivIn &dxdt , value_type t , StateOut &out , value_type dt )
  52. {
  53. m_stepper.do_step( system , in , dxdt , t , out , dt );
  54. ++do_count;
  55. }
  56. template< class System , class StateInOut , class DerivIn >
  57. void do_step_dxdt_impl( System system , StateInOut &x , const DerivIn &dxdt , value_type t , value_type dt )
  58. {
  59. m_stepper.do_step( system , x , dxdt , t , dt );
  60. ++do_count;
  61. }
  62. runge_kutta4< State > m_stepper;
  63. private:
  64. };
  65. BOOST_AUTO_TEST_SUITE( adams_bashforth_test )
  66. BOOST_AUTO_TEST_CASE( test_adams_bashforth_coefficients )
  67. {
  68. detail::adams_bashforth_coefficients< value_type , 1 > c1;
  69. detail::adams_bashforth_coefficients< value_type , 2 > c2;
  70. detail::adams_bashforth_coefficients< value_type , 3 > c3;
  71. detail::adams_bashforth_coefficients< value_type , 4 > c4;
  72. detail::adams_bashforth_coefficients< value_type , 5 > c5;
  73. detail::adams_bashforth_coefficients< value_type , 6 > c6;
  74. detail::adams_bashforth_coefficients< value_type , 7 > c7;
  75. detail::adams_bashforth_coefficients< value_type , 8 > c8;
  76. }
  77. BOOST_AUTO_TEST_CASE( test_rotating_buffer )
  78. {
  79. const size_t N = 5;
  80. detail::rotating_buffer< size_t , N > buffer;
  81. for( size_t i=0 ; i<N ; ++i ) buffer[i] = i;
  82. for( size_t i=0 ; i<N ; ++i )
  83. BOOST_CHECK_EQUAL( buffer[i] , i );
  84. buffer.rotate();
  85. for( size_t i=1 ; i<N ; ++i )
  86. BOOST_CHECK_EQUAL( buffer[i] , i - 1 );
  87. BOOST_CHECK_EQUAL( buffer[0] , size_t( N-1 ) );
  88. }
  89. BOOST_AUTO_TEST_CASE( test_copying )
  90. {
  91. typedef boost::array< double , 1 > state_type;
  92. typedef adams_bashforth< 2 , state_type > stepper_type;
  93. stepper_type s1;
  94. s1.step_storage()[0].m_v[0] = 1.5;
  95. s1.step_storage()[1].m_v[0] = 2.25;
  96. stepper_type s2( s1 );
  97. BOOST_CHECK_CLOSE( s1.step_storage()[0].m_v[0] , s2.step_storage()[0].m_v[0] , 1.0e-14 );
  98. BOOST_CHECK_CLOSE( s1.step_storage()[1].m_v[0] , s2.step_storage()[1].m_v[0] , 1.0e-14 );
  99. BOOST_CHECK( ( &(s1.step_storage()[0]) ) != ( &(s2.step_storage()[0]) ) );
  100. stepper_type s3;
  101. state_type *p1 = &( s3.step_storage()[0].m_v ) , *p2 = &( s3.step_storage()[1].m_v );
  102. s3 = s1;
  103. BOOST_CHECK( p1 == ( &( s3.step_storage()[0].m_v ) ) );
  104. BOOST_CHECK( p2 == ( &( s3.step_storage()[1].m_v ) ) );
  105. BOOST_CHECK_CLOSE( s1.step_storage()[0].m_v[0] , s3.step_storage()[0].m_v[0] , 1.0e-14 );
  106. BOOST_CHECK_CLOSE( s1.step_storage()[1].m_v[0] , s3.step_storage()[1].m_v[0] , 1.0e-14 );
  107. }
  108. typedef boost::mpl::range_c< size_t , 1 , 6 > vector_of_steps;
  109. BOOST_AUTO_TEST_CASE_TEMPLATE( test_init_and_steps , step_type , vector_of_steps )
  110. {
  111. const static size_t steps = step_type::value;
  112. typedef boost::array< value_type , 3 > state_type;
  113. adams_bashforth< steps , state_type > stepper;
  114. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  115. const value_type dt = 0.01;
  116. value_type t = 0.0;
  117. stepper.initialize( lorenz() , x , t , dt );
  118. BOOST_CHECK_CLOSE( t , value_type( steps - 1 ) * dt , 1.0e-14 );
  119. stepper.do_step( lorenz() , x , t , dt );
  120. }
  121. BOOST_AUTO_TEST_CASE( test_instantiation )
  122. {
  123. typedef boost::array< double , 3 > state_type;
  124. adams_bashforth< 1 , state_type > s1;
  125. adams_bashforth< 2 , state_type > s2;
  126. adams_bashforth< 3 , state_type > s3;
  127. adams_bashforth< 4 , state_type > s4;
  128. adams_bashforth< 5 , state_type > s5;
  129. adams_bashforth< 6 , state_type > s6;
  130. adams_bashforth< 7 , state_type > s7;
  131. adams_bashforth< 8 , state_type > s8;
  132. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  133. value_type t = 0.0 , dt = 0.01;
  134. s1.do_step( lorenz() , x , t , dt );
  135. s2.do_step( lorenz() , x , t , dt );
  136. s3.do_step( lorenz() , x , t , dt );
  137. s4.do_step( lorenz() , x , t , dt );
  138. s5.do_step( lorenz() , x , t , dt );
  139. s6.do_step( lorenz() , x , t , dt );
  140. // s7.do_step( lorenz() , x , t , dt );
  141. // s8.do_step( lorenz() , x , t , dt );
  142. }
  143. BOOST_AUTO_TEST_CASE( test_auto_initialization )
  144. {
  145. typedef boost::array< double , 3 > state_type;
  146. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  147. adams_bashforth< 3 , state_type , value_type , state_type , value_type , range_algebra , default_operations ,
  148. initially_resizer , rk4_decorator< state_type > > adams;
  149. adams.initializing_stepper().do_count = 0;
  150. adams.do_step( lorenz() , x , 0.0 , x , 0.1 );
  151. BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 1 ) );
  152. adams.do_step( lorenz() , x , 0.0 , x , 0.1 );
  153. BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) );
  154. adams.do_step( lorenz() , x , 0.0 , x , 0.1 );
  155. BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) );
  156. adams.do_step( lorenz() , x , 0.0 , x , 0.1 );
  157. BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) );
  158. adams.reset();
  159. adams.do_step( lorenz() , x , 0.0 , x , 0.1 );
  160. BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 3 ) );
  161. adams.do_step( lorenz() , x , 0.0 , x , 0.1 );
  162. BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 4 ) );
  163. }
  164. BOOST_AUTO_TEST_CASE( test_manual_initialization )
  165. {
  166. typedef boost::array< double , 3 > state_type;
  167. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  168. adams_bashforth< 3 , state_type , value_type , state_type , value_type , range_algebra , default_operations ,
  169. initially_resizer , rk4_decorator< state_type > > adams;
  170. adams.initializing_stepper().do_count = 0;
  171. double t = 0.0 , dt = 0.1;
  172. adams.initialize( lorenz() , x , t , dt );
  173. BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) );
  174. adams.do_step( lorenz() , x , 0.0 , x , 0.1 );
  175. BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) );
  176. }
  177. BOOST_AUTO_TEST_SUITE_END()