HasConverged.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <boost/none.hpp>
7 #include <boost/optional.hpp>
8 #include <cstddef>
9 #include <iosfwd>
10 
11 #include "NumericalAlgorithms/Convergence/Criteria.hpp"
12 #include "NumericalAlgorithms/Convergence/Reason.hpp"
13 
14 /// \cond
15 namespace PUP {
16 class er;
17 } // namespace PUP
18 /// \endcond
19 
20 namespace Convergence {
21 
22 /*!
23  * \brief Determine whether the \p criteria are met.
24  *
25  * \note This function assumes the \p iteration_id is that of the next, but
26  * not yet performed step. For instance, a `MaxIteration` criterion of 1 will
27  * match if the \p iteration_id is 1 or higher, since the first iteration
28  * (with id 0) has been completed. At this point, also the \p residual_magnitude
29  * reflects the state of the algorithm after completion of the first iteration.
30  * The `initial_residual_magnitude` always refers to the state before the first
31  * iteration has begun.
32  *
33  * \returns a `Convergence::Reason` if the criteria are met, or
34  * `boost::none` otherwise.
35  */
36 boost::optional<Reason> criteria_match(
37  const Criteria& criteria, size_t iteration_id, double residual_magnitude,
38  double initial_residual_magnitude) noexcept;
39 
40 /*!
41  * \brief Signals convergence of the algorithm.
42  *
43  * \details Evaluates to `true` if the algorithm has converged and no
44  * further iterations should be performed. In this case, the `reason()` member
45  * function provides more information. If `false`, calling `reason()` is an
46  * error.
47  *
48  * The stream operator provides a human-readable description of the convergence
49  * status.
50  *
51  * This type default-constructs to a state that signals the algorithm has
52  * not yet converged.
53  */
54 struct HasConverged {
55  public:
56  HasConverged() = default;
57  /*!
58  * \brief Determine whether the \p criteria are met by means of
59  * `Convergence::criteria_match`.
60  */
61  HasConverged(const Criteria& criteria, size_t iteration_id,
62  double residual_magnitude,
63  double initial_residual_magnitude) noexcept;
64 
65  explicit operator bool() const noexcept { return static_cast<bool>(reason_); }
66 
67  /*!
68  * \brief The reason the algorithm has converged.
69  *
70  * \warning Calling this function is an error if the algorithm has not yet
71  * converged.
72  */
73  Reason reason() const noexcept;
74 
75  void pup(PUP::er& p) noexcept; // NOLINT
76 
77  friend bool operator==(const HasConverged& lhs,
78  const HasConverged& rhs) noexcept;
79  friend bool operator!=(const HasConverged& lhs,
80  const HasConverged& rhs) noexcept;
81 
82  friend std::ostream& operator<<(std::ostream& os,
83  const HasConverged& has_converged) noexcept;
84 
85  private:
86  boost::optional<Reason> reason_{boost::none};
87  Criteria criteria_{};
88  size_t iteration_id_{};
89  double residual_magnitude_{};
90  double initial_residual_magnitude_{};
91 };
92 
93 } // namespace Convergence
Definition: Strahlkorper.hpp:14
Signals convergence of the algorithm.
Definition: HasConverged.hpp:54
Criteria that determine an iterative algorithm has converged.
Definition: Criteria.hpp:35
Definition: Criteria.cpp:8