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