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