Line data Source code
1 1 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : /// \file 5 : /// Defines class TimeStepId. 6 : 7 : #pragma once 8 : 9 : #include <cstddef> 10 : #include <cstdint> 11 : #include <functional> 12 : #include <iosfwd> 13 : #include <limits> 14 : 15 : #include "Time/Time.hpp" 16 : #include "Utilities/Rational.hpp" 17 : 18 : namespace PUP { 19 : class er; 20 : } // namespace PUP 21 : 22 : /// \ingroup TimeGroup 23 : /// 24 : /// A unique identifier for the temporal state of an integrated 25 : /// system. 26 1 : class TimeStepId { 27 : public: 28 0 : TimeStepId() = default; 29 : /// Create a TimeStepId at the start of a step. If that step is at the 30 : /// (evolution-defined) end of the slab the TimeStepId will be advanced 31 : /// to the next slab. 32 1 : TimeStepId(bool time_runs_forward, int64_t slab_number, const Time& time); 33 : /// Create a TimeStepId at a substep at time `substep_time` in a step 34 : /// starting at time `step_time`. 35 1 : TimeStepId(bool time_runs_forward, int64_t slab_number, const Time& step_time, 36 : uint64_t substep, const TimeDelta& step_size, double substep_time); 37 : 38 0 : bool time_runs_forward() const; 39 0 : int64_t slab_number() const { return slab_number_; } 40 : /// Time at the start of the current step 41 1 : const Time& step_time() const { return step_time_; } 42 0 : uint64_t substep() const { return substep_; } 43 : /// Current step size. Only available when the substep is nonzero, 44 : /// because on the full step the state is valid for any step size. 45 1 : TimeDelta step_size() const; 46 : /// Time of the current substep 47 1 : double substep_time() const { return substep_time_; } 48 : 49 0 : bool is_at_slab_boundary() const; 50 : 51 : /// Returns a new TimeStepId representing the start of the next step. 52 1 : TimeStepId next_step(const TimeDelta& step_size) const; 53 : 54 : /// Returns a new TimeStepId representing the next substep, given 55 : /// the position of the substep within the step. 56 1 : TimeStepId next_substep(const TimeDelta& step_size, 57 : double step_fraction) const; 58 : 59 : // NOLINTNEXTLINE(google-runtime-references) 60 0 : void pup(PUP::er& p); 61 : 62 : private: 63 0 : void canonicalize(); 64 : 65 0 : int64_t slab_number_{std::numeric_limits<int64_t>::lowest()}; 66 0 : Time step_time_{}; 67 0 : uint8_t substep_{0}; 68 0 : Rational step_size_{}; 69 0 : double substep_time_{}; 70 : }; 71 : 72 : /// These comparisons define a total order on all TimeStepIds with the 73 : /// same direction of time flow. For any two objects representing 74 : /// states of the same element, the ordering will match the 75 : /// computational ordering of those states. For others, (e.g., 76 : /// overlapping steps) it is arbitrary. 77 : /// @{ 78 1 : bool operator==(const TimeStepId& a, const TimeStepId& b); 79 1 : bool operator!=(const TimeStepId& a, const TimeStepId& b); 80 1 : bool operator<(const TimeStepId& a, const TimeStepId& b); 81 1 : bool operator<=(const TimeStepId& a, const TimeStepId& b); 82 1 : bool operator>(const TimeStepId& a, const TimeStepId& b); 83 1 : bool operator>=(const TimeStepId& a, const TimeStepId& b); 84 : /// @} 85 : 86 0 : std::ostream& operator<<(std::ostream& s, const TimeStepId& id); 87 : 88 0 : size_t hash_value(const TimeStepId& id); 89 : 90 : namespace std { 91 : template <> 92 : struct hash<TimeStepId> { 93 : size_t operator()(const TimeStepId& id) const; 94 : }; 95 : } // namespace std