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