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