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);