Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <array>
7 : #include <optional>
8 : #include <pup.h>
9 : #include <vector>
10 :
11 : #include "Options/Context.hpp"
12 : #include "Options/String.hpp"
13 : #include "Utilities/Serialization/CharmPupable.hpp"
14 : #include "Utilities/TMPL.hpp"
15 :
16 : /// Represents a sequence of times.
17 : ///
18 : /// The template parameter \p T can either be `double` for a sequence
19 : /// of simulation times or std::uint64_t for a sequence of slab
20 : /// numbers.
21 : template <typename T>
22 1 : class TimeSequence : public PUP::able {
23 : protected:
24 : /// \cond HIDDEN_SYMBOLS
25 : TimeSequence() = default;
26 : TimeSequence(const TimeSequence&) = default;
27 : TimeSequence(TimeSequence&&) = default;
28 : TimeSequence& operator=(const TimeSequence&) = default;
29 : TimeSequence& operator=(TimeSequence&&) = default;
30 : /// \endcond
31 :
32 : public:
33 0 : ~TimeSequence() override = default;
34 :
35 0 : WRAPPED_PUPable_abstract(TimeSequence); // NOLINT
36 :
37 : /// Returns the time in the sequence nearest to \p time, the time
38 : /// before that, and the time after, in numerical order. These
39 : /// values allow a consumer to find the times in the sequence
40 : /// bracketing the given time and give enough additional information
41 : /// so that exact or roundoff matches can be handled however the
42 : /// consumer wishes. Any time that does not exist (because the
43 : /// sequence terminates) is returned as an empty std::optional. The
44 : /// central std::optional will be populated unless the sequence is
45 : /// empty.
46 1 : virtual std::array<std::optional<T>, 3> times_near(T time) const = 0;
47 : };
48 :
49 : /// \ingroup TimeGroup
50 : ///
51 : /// Holds all the TimeSequences
52 1 : namespace TimeSequences {
53 : /*!
54 : * \brief A sequence of evenly spaced times.
55 : *
56 : * The sequence of times
57 : * \f{equation}{
58 : * n \times \mathrm{Interval} + \mathrm{Offset}
59 : * \f}
60 : * for all integers $n$.
61 : */
62 : template <typename T>
63 1 : class EvenlySpaced : public TimeSequence<T> {
64 : public:
65 : /// \cond
66 : EvenlySpaced() = default;
67 : explicit EvenlySpaced(CkMigrateMessage* /*unused*/) {}
68 : using PUP::able::register_constructor;
69 : WRAPPED_PUPable_decl_template(EvenlySpaced); // NOLINT
70 : /// \endcond
71 :
72 0 : struct Interval {
73 0 : static constexpr Options::String help = "Spacing between times";
74 0 : using type = T;
75 0 : static constexpr T lower_bound() { return 0; }
76 : };
77 :
78 0 : struct Offset {
79 0 : static constexpr Options::String help = "Offset of sequence";
80 0 : using type = T;
81 : };
82 :
83 0 : static constexpr Options::String help =
84 : "The sequence of times n * Interval + Offset for all integers n.";
85 0 : using options = tmpl::list<Interval, Offset>;
86 :
87 0 : explicit EvenlySpaced(T interval, T offset = 0,
88 : const Options::Context& context = {});
89 :
90 1 : std::array<std::optional<T>, 3> times_near(T time) const override;
91 :
92 : // NOLINTNEXTLINE(google-runtime-references)
93 0 : void pup(PUP::er& p) override;
94 :
95 : private:
96 : // This is
97 : // tmpl::conditional<std::is_integral_v<T>, std::make_signed<T>,
98 : // tmpl::identity<T>>::type
99 : // except avoiding instantiating std::make_signed<double> because,
100 : // depending on the standard version, that is either undefined
101 : // behavior or makes the program ill-formed.
102 0 : using SignedT = tmpl::apply<tmpl::apply<
103 : tmpl::if_<std::is_integral<tmpl::pin<T>>,
104 : tmpl::defer<tmpl::bind<std::make_signed_t, tmpl::pin<T>>>,
105 : tmpl::defer<tmpl::always<tmpl::pin<T>>>>>>;
106 :
107 0 : SignedT interval_{};
108 0 : SignedT offset_{};
109 : };
110 :
111 : /// An explicitly specified sequence of times.
112 : template <typename T>
113 1 : class Specified : public TimeSequence<T> {
114 : public:
115 : /// \cond
116 : Specified() = default;
117 : explicit Specified(CkMigrateMessage* /*unused*/) {}
118 : using PUP::able::register_constructor;
119 : WRAPPED_PUPable_decl_template(Specified); // NOLINT
120 : /// \endcond
121 :
122 0 : struct Values {
123 0 : static constexpr Options::String help = "The times in the sequence";
124 0 : using type = std::vector<T>;
125 : };
126 :
127 0 : static constexpr Options::String help =
128 : "An explicitly specified sequence of times.";
129 0 : using options = tmpl::list<Values>;
130 :
131 0 : explicit Specified(std::vector<T> values);
132 :
133 1 : std::array<std::optional<T>, 3> times_near(T time) const override;
134 :
135 : // NOLINTNEXTLINE(google-runtime-references)
136 0 : void pup(PUP::er& p) override;
137 :
138 : private:
139 0 : std::vector<T> values_;
140 : };
141 :
142 : template <typename T>
143 0 : using all_time_sequences = tmpl::list<EvenlySpaced<T>, Specified<T>>;
144 : } // namespace TimeSequences
|