1 /*
2  [auto_generated]
3  boost/numeric/odeint/integrate/max_step_checker.hpp
4 
5  [begin_description]
6  Throws exception if too many steps are performed.
7  [end_description]
8 
9  Copyright 2015 Mario Mulansky
10 
11  Distributed under the Boost Software License, Version 1.0.
12  (See accompanying file LICENSE_1_0.txt or
13  copy at http://www.boost.org/LICENSE_1_0.txt)
14  */
15 
16 
17 #ifndef BOOST_NUMERIC_ODEINT_INTEGRATE_MAX_STEP_CHECKER_HPP_INCLUDED
18 #define BOOST_NUMERIC_ODEINT_INTEGRATE_MAX_STEP_CHECKER_HPP_INCLUDED
19 
20 #include <stdexcept>
21 #include <cstdio>
22 
23 #include <boost/throw_exception.hpp>
24 #include <boost/numeric/odeint/util/odeint_error.hpp>
25 
26 
27 namespace boost {
28 namespace numeric {
29 namespace odeint {
30 
31 /**
32  * \brief A class for performing overflow checks on the step count in integrate functions.
33  *
34  * Provide an instance of this class to integrate functions if you want to throw a runtime error if
35  * too many steps are performed without progress during the integrate routine.
36  */
37 class max_step_checker
38 {
39 public:
40 
41 protected:
42     const int m_max_steps;
43     int m_steps;
44 
45 public:
46     /**
47      * \brief Construct the max_step_checker.
48      * max_steps is the maximal number of iterations allowed before runtime_error is thrown.
49      */
max_step_checker(const int max_steps=500)50     max_step_checker(const int max_steps = 500)
51         : m_max_steps(max_steps)
52     {
53         reset();
54     }
55 
56     /**
57      * \brief Resets the max_step_checker by setting the internal counter to 0.
58      */
reset()59     void reset()
60     {
61         m_steps = 0;
62     }
63 
64     /**
65      * \brief Increases the counter and performs the iteration check
66      */
operator ()(void)67     void operator()(void)
68     {
69         if( m_steps++ >= m_max_steps )
70         {
71             char error_msg[200];
72             std::sprintf(error_msg, "Max number of iterations exceeded (%d).", m_max_steps);
73             BOOST_THROW_EXCEPTION( no_progress_error(error_msg) );
74         }
75     }
76 };
77 
78 
79 /**
80  * \brief A class for performing overflow checks on the failed step count in step size adjustments.
81  *
82  * Used internally within the dense output stepper and integrate routines.
83  */
84 class failed_step_checker : public max_step_checker
85 {
86 
87 public:
88     /**
89      * \brief Construct the failed_step_checker.
90      * max_steps is the maximal number of iterations allowed before runtime_error is thrown.
91      */
failed_step_checker(const int max_steps=500)92     failed_step_checker(const int max_steps = 500)
93             : max_step_checker(max_steps)
94     {}
95 
96     /**
97      * \brief Increases the counter and performs the iteration check
98      */
operator ()(void)99     void operator()(void)
100     {
101         if( m_steps++ >= m_max_steps )
102         {
103             char error_msg[200];
104             std::sprintf(error_msg, "Max number of iterations exceeded (%d). A new step size was not found.", m_max_steps);
105             BOOST_THROW_EXCEPTION( step_adjustment_error(error_msg) );
106         }
107     }
108 };
109 
110 } // namespace odeint
111 } // namespace numeric
112 } // namespace boost
113 
114 #endif
115