Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <limits>
7 : #include <optional>
8 :
9 : /// \cond
10 : struct TimeStepRequest;
11 : namespace PUP {
12 : class er;
13 : } // namespace PUP
14 : /// \endcond
15 :
16 : /// Combine TimeStepRequest objects to find a consensus step. See
17 : /// that class for details.
18 1 : class TimeStepRequestProcessor {
19 : public:
20 0 : TimeStepRequestProcessor() = default;
21 0 : explicit TimeStepRequestProcessor(bool time_runs_forward);
22 :
23 : /// The new goal, if one was given.
24 1 : std::optional<double> new_step_size_goal() const;
25 :
26 : /// The new step. Two versions are provided, as neither computing
27 : /// the step size from the end or the end from the size is
28 : /// guaranteed to be an exact operation on floating-point values,
29 : /// and which quantity is fundamental varies between consumers. The
30 : /// \p step_size_goal is ignored if any requests have set a new
31 : /// goal.
32 : /// @{
33 1 : double step_size(double step_start, double step_size_goal) const;
34 1 : double step_end(double step_start, double step_size_goal) const;
35 : /// @}
36 :
37 0 : void process(const TimeStepRequest& request);
38 :
39 : /// Merge the results from another object.
40 1 : TimeStepRequestProcessor& operator+=(const TimeStepRequestProcessor& other);
41 :
42 : /// ERROR if \p size and \p end do not satisfy the hard limits.
43 1 : void error_on_hard_limit(double size, double end) const;
44 :
45 0 : void pup(PUP::er& p);
46 :
47 : private:
48 0 : friend bool operator==(const TimeStepRequestProcessor& a,
49 : const TimeStepRequestProcessor& b);
50 :
51 0 : bool time_runs_forward_ = false;
52 :
53 0 : std::optional<double> step_size_goal_{};
54 :
55 0 : double step_size_request_ = std::numeric_limits<double>::signaling_NaN();
56 0 : double step_end_request_ = std::numeric_limits<double>::signaling_NaN();
57 :
58 0 : bool can_use_larger_limit_ = false;
59 0 : double next_step_size_request_ = std::numeric_limits<double>::signaling_NaN();
60 0 : double next_step_end_request_ = std::numeric_limits<double>::signaling_NaN();
61 :
62 0 : double step_size_hard_limit_ = std::numeric_limits<double>::signaling_NaN();
63 0 : double step_end_hard_limit_ = std::numeric_limits<double>::signaling_NaN();
64 : };
65 :
66 0 : bool operator!=(const TimeStepRequestProcessor& a,
67 : const TimeStepRequestProcessor& b);
68 :
69 : /// Combine the limits from two TimeStepRequestProcessor objects.
70 1 : TimeStepRequestProcessor operator+(const TimeStepRequestProcessor& a,
71 : const TimeStepRequestProcessor& b);
|