SpecifiedTimes.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 <utility>
11 #include <vector>
12 
13 #include "Options/Options.hpp"
15 #include "ParallelAlgorithms/EventsAndTriggers/Trigger.hpp"
16 #include "Time/Slab.hpp"
17 #include "Time/Time.hpp"
18 #include "Time/TimeStepId.hpp"
19 #include "Time/Utilities.hpp"
20 #include "Utilities/Registration.hpp"
21 #include "Utilities/TMPL.hpp"
22 
23 /// \cond
24 namespace Tags {
25 struct Time;
26 struct TimeStepId;
27 } // namespace Tags
28 /// \endcond
29 
30 namespace Triggers {
31 template <typename TriggerRegistrars>
33 
34 namespace Registrars {
36 } // namespace Registrars
37 
38 /// \ingroup EventsAndTriggersGroup
39 /// \ingroup TimeGroup
40 /// Trigger at particular times.
41 ///
42 /// \warning This trigger will only fire if it is actually checked at
43 /// the times specified. The StepToTimes StepChooser can be useful
44 /// for this.
45 template <typename TriggerRegistrars = tmpl::list<Registrars::SpecifiedTimes>>
46 class SpecifiedTimes : public Trigger<TriggerRegistrars> {
47  public:
48  /// \cond
49  SpecifiedTimes() = default;
50  explicit SpecifiedTimes(CkMigrateMessage* /*unused*/) noexcept {}
51  using PUP::able::register_constructor;
52  WRAPPED_PUPable_decl_template(SpecifiedTimes); // NOLINT
53  /// \endcond
54 
55  struct Times {
56  using type = std::vector<double>;
57  static constexpr OptionString help{"Times to trigger at"};
58  };
59 
60  static constexpr OptionString help{"Trigger at particular times."};
61  using options = tmpl::list<Times>;
62 
63  explicit SpecifiedTimes(std::vector<double> times) noexcept
64  : times_(std::move(times)) {
65  std::sort(times_.begin(), times_.end());
66  }
67 
68  using argument_tags = tmpl::list<Tags::Time, Tags::TimeStepId>;
69 
70  bool operator()(const double now, const TimeStepId& time_id) const noexcept {
71  const auto& substep_time = time_id.substep_time();
72  // Trying to step to a given time might not get us exactly there
73  // because of rounding errors.
74  const double sloppiness = slab_rounding_error(substep_time);
75 
76  const auto triggered_times = std::equal_range(
77  times_.begin(), times_.end(), now,
78  [&sloppiness](const double a, const double b) noexcept {
79  return a < b - sloppiness;
80  });
81  return triggered_times.first != triggered_times.second;
82  }
83 
84  // NOLINTNEXTLINE(google-runtime-references)
85  void pup(PUP::er& p) noexcept { p | times_; }
86 
87  private:
88  std::vector<double> times_;
89 };
90 
91 /// \cond
92 template <typename TriggerRegistrars>
93 PUP::able::PUP_ID SpecifiedTimes<TriggerRegistrars>::my_PUP_ID = 0; // NOLINT
94 /// \endcond
95 } // namespace Triggers
CharmPupable.hpp
utility
Options.hpp
vector
slab_rounding_error
double slab_rounding_error(const Time &time) noexcept
Definition: Utilities.cpp:12
cmath
algorithm
Triggers::SpecifiedTimes
Definition: SpecifiedTimes.hpp:32
Registration::Registrar
A template for defining a registrar.
Definition: Registration.hpp:42
WRAPPED_PUPable_decl_template
#define WRAPPED_PUPable_decl_template(className)
Mark derived classes as serializable.
Definition: CharmPupable.hpp:22
Triggers::SpecifiedTimes::Times
Definition: SpecifiedTimes.hpp:55
Trigger
Definition: Trigger.hpp:34
Time.hpp
TimeStepId
Definition: TimeStepId.hpp:25
TimeStepId.hpp
limits
Time
Definition: Time.hpp:29
Slab.hpp
OptionString
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:30
TMPL.hpp