15 #include "ParallelAlgorithms/EventsAndTriggers/Trigger.hpp"
18 #include "Time/TimeSequence.hpp"
19 #include "Utilities/Registration.hpp"
30 template <
typename TriggerRegistrars>
33 namespace Registrars {
37 namespace NearTimes_enums {
38 enum class Unit {
Time,
Slab, Step };
39 enum class Direction { Before, After, Both };
50 template <
typename TriggerRegistrars = tmpl::list<Registrars::NearTimes>>
51 class NearTimes :
public Trigger<TriggerRegistrars> {
54 NearTimes() =
default;
55 explicit NearTimes(CkMigrateMessage* ) noexcept {}
56 using PUP::able::register_constructor;
60 using Unit = NearTimes_enums::Unit;
61 using Direction = NearTimes_enums::Direction;
71 static type lower_bound() noexcept {
return 0.0; }
73 "Maximum time difference to trigger at";
77 using type = NearTimes::Unit;
79 "Interpret Range as 'Time', 'Step's, or 'Slab's";
83 using type = NearTimes::Direction;
85 "Trigger 'Before', 'After', or 'Both' from the times";
90 "Trigger in intervals surrounding particular times.";
96 const Unit unit,
const Direction direction) noexcept
97 : times_(std::move(times)),
100 direction_(direction) {}
102 using argument_tags = tmpl::list<Tags::Time, Tags::TimeStep>;
104 bool operator()(
const double now,
const TimeDelta& time_step)
const noexcept {
105 const bool time_runs_forward = time_step.is_positive();
107 double range_code_units = range_;
108 if (unit_ == Unit::Slab) {
109 range_code_units *= time_step.slab().duration().value();
110 }
else if (unit_ == Unit::Step) {
111 range_code_units *= std::abs(time_step.value());
114 if (not time_runs_forward) {
115 range_code_units = -range_code_units;
119 auto trigger_range = std::make_pair(
120 direction_ == Direction::Before ? now : now - range_code_units,
121 direction_ == Direction::After ? now : now + range_code_units);
123 if (not time_runs_forward) {
124 std::swap(trigger_range.first, trigger_range.second);
127 const auto nearby_times = times_->times_near(trigger_range.first);
128 for (
const auto& time : nearby_times) {
129 if (time and *time >= trigger_range.first and
130 *time <= trigger_range.second) {
138 void pup(PUP::er& p) noexcept
override {
153 template <
typename TriggerRegistrars>
154 PUP::able::PUP_ID NearTimes<TriggerRegistrars>::my_PUP_ID = 0;
160 using type = Triggers::NearTimes_enums::Unit;
161 template <
typename Metavariables>
164 if (unit ==
"Time") {
166 }
else if (unit ==
"Step") {
168 }
else if (unit ==
"Slab") {
171 PARSE_ERROR(options.context(),
"Unit must be 'Time', 'Step', or 'Slab'");
178 typename Triggers::NearTimes_enums::Direction> {
179 using type = Triggers::NearTimes_enums::Direction;
180 template <
typename Metavariables>
183 if (unit ==
"Before") {
185 }
else if (unit ==
"After") {
187 }
else if (unit ==
"Both") {
191 "Direction must be 'Before', 'After', or 'Both'");