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 : /// Returns the time of the next step if called on a substep, or the
60 : /// current time if called on a full step.
61 1 : Time skip_to_step() const;
62 :
63 : // NOLINTNEXTLINE(google-runtime-references)
64 0 : void pup(PUP::er& p);
65 :
66 : private:
67 0 : void canonicalize();
68 :
69 0 : int64_t slab_number_{std::numeric_limits<int64_t>::lowest()};
70 0 : Time step_time_{};
71 0 : uint8_t substep_{0};
72 0 : Rational step_size_{};
73 0 : double substep_time_{};
74 : };
75 :
76 : /// These comparisons define a total order on all TimeStepIds with the
77 : /// same direction of time flow. For any two objects representing
78 : /// states of the same element, the ordering will match the
79 : /// computational ordering of those states. For others, (e.g.,
80 : /// overlapping steps) it is arbitrary.
81 : /// @{
82 1 : bool operator==(const TimeStepId& a, const TimeStepId& b);
83 1 : bool operator!=(const TimeStepId& a, const TimeStepId& b);
84 1 : bool operator<(const TimeStepId& a, const TimeStepId& b);
85 1 : bool operator<=(const TimeStepId& a, const TimeStepId& b);
86 1 : bool operator>(const TimeStepId& a, const TimeStepId& b);
87 1 : bool operator>=(const TimeStepId& a, const TimeStepId& b);
88 : /// @}
89 :
90 0 : std::ostream& operator<<(std::ostream& s, const TimeStepId& id);
91 :
92 0 : size_t hash_value(const TimeStepId& id);
93 :
94 : namespace std {
95 : template <>
96 : struct hash<TimeStepId> {
97 : size_t operator()(const TimeStepId& id) const;
98 : };
99 : } // namespace std
|