NearTimes.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <algorithm>
7 #include <cmath>
8 #include <limits>
9 #include <pup.h>
10 #include <pup_stl.h>
11 #include <string>
12 #include <utility>
13 
14 #include "Options/Options.hpp"
16 #include "ParallelAlgorithms/EventsAndTriggers/Trigger.hpp"
17 #include "Time/Slab.hpp"
18 #include "Time/Time.hpp"
19 #include "Time/TimeSequence.hpp"
20 #include "Utilities/TMPL.hpp"
21 
22 /// \cond
23 namespace Tags {
24 struct Time;
25 struct TimeStep;
26 } // namespace Tags
27 /// \endcond
28 
29 namespace Triggers {
30 namespace NearTimes_enums {
31 enum class Unit { Time, Slab, Step };
32 enum class Direction { Before, After, Both };
33 } // namespace NearTimes_enums
34 
35 /// \ingroup EventsAndTriggersGroup
36 /// \ingroup TimeGroup
37 /// Trigger in intervals surrounding particular times.
38 ///
39 /// When using adaptive time stepping, intervals specified in terms of
40 /// slabs or steps are approximate.
41 ///
42 /// \see Times
43 class NearTimes : public Trigger {
44  public:
45  /// \cond
46  NearTimes() = default;
47  explicit NearTimes(CkMigrateMessage* /*unused*/) noexcept {}
48  using PUP::able::register_constructor;
50  /// \endcond
51 
52  using Unit = NearTimes_enums::Unit;
53  using Direction = NearTimes_enums::Direction;
54 
55  struct OptionTags {
56  struct Times {
58  static constexpr Options::String help = "Times to trigger at";
59  };
60 
61  struct Range {
62  using type = double;
63  static type lower_bound() noexcept { return 0.0; }
64  static constexpr Options::String help =
65  "Maximum time difference to trigger at";
66  };
67 
68  struct Unit {
69  using type = NearTimes::Unit;
70  static constexpr Options::String help =
71  "Interpret Range as 'Time', 'Step's, or 'Slab's";
72  };
73 
74  struct Direction {
75  using type = NearTimes::Direction;
76  static constexpr Options::String help =
77  "Trigger 'Before', 'After', or 'Both' from the times";
78  };
79  };
80 
81  static constexpr Options::String help =
82  "Trigger in intervals surrounding particular times.";
83  using options =
84  tmpl::list<typename OptionTags::Times, typename OptionTags::Range,
85  typename OptionTags::Unit, typename OptionTags::Direction>;
86 
87  NearTimes(std::unique_ptr<TimeSequence<double>> times, const double range,
88  const Unit unit, const Direction direction) noexcept
89  : times_(std::move(times)),
90  range_(range),
91  unit_(unit),
92  direction_(direction) {}
93 
94  using argument_tags = tmpl::list<Tags::Time, Tags::TimeStep>;
95 
96  bool operator()(const double now, const TimeDelta& time_step) const noexcept;
97 
98  // NOLINTNEXTLINE(google-runtime-references)
99  void pup(PUP::er& p) noexcept override;
100 
101  private:
104  Unit unit_{};
105  Direction direction_{};
106 };
107 } // namespace Triggers
108 
109 template <>
110 struct Options::create_from_yaml<Triggers::NearTimes_enums::Unit> {
111  using type = Triggers::NearTimes_enums::Unit;
112  template <typename Metavariables>
113  static type create(const Options::Option& options) {
114  const auto unit = options.parse_as<std::string>();
115  if (unit == "Time") {
116  return type::Time;
117  } else if (unit == "Step") {
118  return type::Step;
119  } else if (unit == "Slab") {
120  return type::Slab;
121  } else {
122  PARSE_ERROR(options.context(), "Unit must be 'Time', 'Step', or 'Slab'");
123  }
124  }
125 };
126 
127 template <>
129  typename Triggers::NearTimes_enums::Direction> {
130  using type = Triggers::NearTimes_enums::Direction;
131  template <typename Metavariables>
132  static type create(const Options::Option& options) {
133  const auto unit = options.parse_as<std::string>();
134  if (unit == "Before") {
135  return type::Before;
136  } else if (unit == "After") {
137  return type::After;
138  } else if (unit == "Both") {
139  return type::Both;
140  } else {
141  PARSE_ERROR(options.context(),
142  "Direction must be 'Before', 'After', or 'Both'");
143  }
144  }
145 };
std::string
CharmPupable.hpp
utility
Slab
Definition: Slab.hpp:27
PARSE_ERROR
#define PARSE_ERROR(context, m)
Definition: Options.hpp:71
Options.hpp
Triggers::NearTimes::OptionTags
Definition: NearTimes.hpp:55
cmath
algorithm
Direction
Definition: Direction.hpp:23
Triggers::NearTimes::OptionTags::Range
Definition: NearTimes.hpp:61
Triggers::NearTimes::OptionTags::Times
Definition: NearTimes.hpp:56
Options::Option
Definition: Options.hpp:108
TimeSequence
Represents a sequence of times.
Definition: TimeSequence.hpp:21
WRAPPED_PUPable_decl_template
#define WRAPPED_PUPable_decl_template(className)
Mark derived classes as serializable.
Definition: CharmPupable.hpp:22
Triggers::NearTimes
Definition: NearTimes.hpp:43
Options::create_from_yaml
Definition: MinmodType.hpp:11
TimeDelta
Definition: Time.hpp:88
Trigger
Definition: Trigger.hpp:17
std::numeric_limits::signaling_NaN
T signaling_NaN(T... args)
Time.hpp
limits
Time
Definition: Time.hpp:29
Options::String
const char *const String
The string used in option structs.
Definition: Options.hpp:32
Triggers::NearTimes::OptionTags::Direction
Definition: NearTimes.hpp:74
Triggers::NearTimes::OptionTags::Unit
Definition: NearTimes.hpp:68
Slab.hpp
std::unique_ptr< TimeSequence< double > >
TMPL.hpp
string