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