]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/numeric/odeint/include/boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / numeric / odeint / include / boost / numeric / odeint / integrate / detail / integrate_adaptive.hpp
CommitLineData
7c673cae
FG
1/*
2 [auto_generated]
3 boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp
4
5 [begin_description]
6 Default Integrate adaptive implementation.
7 [end_description]
8
9 Copyright 2011-2013 Karsten Ahnert
10 Copyright 2011-2015 Mario Mulansky
11 Copyright 2012 Christoph Koke
12
13 Distributed under the Boost Software License, Version 1.0.
14 (See accompanying file LICENSE_1_0.txt or
15 copy at http://www.boost.org/LICENSE_1_0.txt)
16 */
17
18
19#ifndef BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_ADAPTIVE_HPP_INCLUDED
20#define BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_ADAPTIVE_HPP_INCLUDED
21
22#include <stdexcept>
23
24#include <boost/throw_exception.hpp>
25
26#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
27#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
28#include <boost/numeric/odeint/integrate/max_step_checker.hpp>
29#include <boost/numeric/odeint/integrate/detail/integrate_const.hpp>
30#include <boost/numeric/odeint/util/bind.hpp>
31#include <boost/numeric/odeint/util/unwrap_reference.hpp>
32#include <boost/numeric/odeint/util/copy.hpp>
33
34#include <boost/numeric/odeint/util/detail/less_with_sign.hpp>
35
36
37#include <iostream>
38
39namespace boost {
40namespace numeric {
41namespace odeint {
42namespace detail {
43
44// forward declaration
45template< class Stepper , class System , class State , class Time , class Observer >
46size_t integrate_const(
47 Stepper stepper , System system , State &start_state ,
48 Time start_time , Time end_time , Time dt ,
49 Observer observer , stepper_tag );
50
51/*
52 * integrate_adaptive for simple stepper is basically an integrate_const + some last step
53 */
54template< class Stepper , class System , class State , class Time , class Observer >
55size_t integrate_adaptive(
56 Stepper stepper , System system , State &start_state ,
57 Time start_time , Time end_time , Time dt ,
58 Observer observer , stepper_tag
59)
60{
61 size_t steps = detail::integrate_const( stepper , system , start_state , start_time ,
62 end_time , dt , observer , stepper_tag() );
63 typename odeint::unwrap_reference< Observer >::type &obs = observer;
64 typename odeint::unwrap_reference< Stepper >::type &st = stepper;
65
66 Time end = start_time + dt*steps;
67 if( less_with_sign( end , end_time , dt ) )
68 { //make a last step to end exactly at end_time
69 st.do_step( system , start_state , end , end_time - end );
70 steps++;
71 obs( start_state , end_time );
72 }
73 return steps;
74}
75
76
77/*
78 * integrate adaptive for controlled stepper
79 */
80template< class Stepper , class System , class State , class Time , class Observer >
81size_t integrate_adaptive(
82 Stepper stepper , System system , State &start_state ,
83 Time &start_time , Time end_time , Time &dt ,
84 Observer observer , controlled_stepper_tag
85)
86{
87 typename odeint::unwrap_reference< Observer >::type &obs = observer;
88 typename odeint::unwrap_reference< Stepper >::type &st = stepper;
89
90 failed_step_checker fail_checker; // to throw a runtime_error if step size adjustment fails
91 size_t count = 0;
92 while( less_with_sign( start_time , end_time , dt ) )
93 {
94 obs( start_state , start_time );
95 if( less_with_sign( end_time , static_cast<Time>(start_time + dt) , dt ) )
96 {
97 dt = end_time - start_time;
98 }
99
100 controlled_step_result res;
101 do
102 {
103 res = st.try_step( system , start_state , start_time , dt );
104 fail_checker(); // check number of failed steps
105 }
106 while( res == fail );
107 fail_checker.reset(); // if we reach here, the step was successful -> reset fail checker
108
109 ++count;
110 }
111 obs( start_state , start_time );
112 return count;
113}
114
115
116/*
117 * integrate adaptive for dense output steppers
118 *
119 * step size control is used if the stepper supports it
120 */
121template< class Stepper , class System , class State , class Time , class Observer >
122size_t integrate_adaptive(
123 Stepper stepper , System system , State &start_state ,
124 Time start_time , Time end_time , Time dt ,
125 Observer observer , dense_output_stepper_tag )
126{
127 typename odeint::unwrap_reference< Observer >::type &obs = observer;
128 typename odeint::unwrap_reference< Stepper >::type &st = stepper;
129
130 size_t count = 0;
131 st.initialize( start_state , start_time , dt );
132
133 while( less_with_sign( st.current_time() , end_time , st.current_time_step() ) )
134 {
135 while( less_eq_with_sign( static_cast<Time>(st.current_time() + st.current_time_step()) ,
136 end_time ,
137 st.current_time_step() ) )
138 { //make sure we don't go beyond the end_time
139 obs( st.current_state() , st.current_time() );
140 st.do_step( system );
141 ++count;
142 }
143 // calculate time step to arrive exactly at end time
144 st.initialize( st.current_state() , st.current_time() , static_cast<Time>(end_time - st.current_time()) );
145 }
146 obs( st.current_state() , st.current_time() );
147 // overwrite start_state with the final point
148 boost::numeric::odeint::copy( st.current_state() , start_state );
149 return count;
150}
151
152
153
154
155} // namespace detail
156} // namespace odeint
157} // namespace numeric
158} // namespace boost
159
160
161#endif // BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_ADAPTIVE_HPP_INCLUDED