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;
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
double slab_rounding_error(const Time &time) noexcept
Scale of the roundoff error incurred from inexact slab operations near the given time.
Definition: Utilities.cpp:12
The time in a simulation. Times can be safely compared for exact equality as long as they do not belo...
Definition: Time.hpp:29
Defines class TimeStepId.
Defines classes and functions for making classes creatable from input files.
Defines macros to allow serialization of abstract template base classes.
#define WRAPPED_PUPable_decl_template(className)
Mark derived classes as serializable.
Definition: CharmPupable.hpp:22
Defines Time and TimeDelta.
A unique identifier for the temporal state of an integrated system.
Definition: TimeStepId.hpp:25
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:29
Definition: SpecifiedTimes.hpp:55
const Time & substep_time() const noexcept
Time of the current substep.
Definition: TimeStepId.hpp:61
A template for defining a registrar.
Definition: Registration.hpp:42
Defines class Slab.
Definition: DataBoxTag.hpp:29
Wraps the template metaprogramming library used (brigand)
Base class for checking whether to run an Event.
Definition: Trigger.hpp:34
Trigger at particular times.
Definition: SpecifiedTimes.hpp:32
Definition: LogicalTriggers.hpp:13