Or.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <algorithm>
7 #include <memory>
8 #include <pup.h>
9 #include <vector>
10 
11 #include "Evolution/EventsAndDenseTriggers/DenseTrigger.hpp"
12 #include "Options/Options.hpp"
13 #include "Options/ParseOptions.hpp"
15 #include "Time/EvolutionOrdering.hpp"
16 #include "Time/TimeStepId.hpp"
17 #include "Utilities/Algorithm.hpp"
18 #include "Utilities/TMPL.hpp"
19 
20 /// \cond
21 namespace Tags {
22 struct DataBox;
23 struct TimeStepId;
24 } // namespace Tags
25 namespace db {
26 template <typename TagsList> class DataBox;
27 } // namespace db
28 /// \endcond
29 
30 namespace DenseTriggers {
31 /// \ingroup EventsAndTriggersGroup
32 /// Trigger when any of a collection of DenseTriggers triggers.
33 class Or : public DenseTrigger {
34  public:
35  /// \cond
36  Or() = default;
37  explicit Or(CkMigrateMessage* const msg) noexcept : DenseTrigger(msg) {}
38  using PUP::able::register_constructor;
40  /// \endcond
41 
42  static constexpr Options::String help =
43  "Trigger when any of a collection of triggers triggers.";
44 
45  explicit Or(std::vector<std::unique_ptr<DenseTrigger>> triggers) noexcept;
46 
47  using is_triggered_argument_tags =
48  tmpl::list<Tags::TimeStepId, Tags::DataBox>;
49 
50  template <typename DbTags>
51  Result is_triggered(const TimeStepId& time_step_id,
52  const db::DataBox<DbTags>& box) const noexcept {
53  const evolution_less<double> before{time_step_id.time_runs_forward()};
54  Result result{false, before.infinity()};
55  for (const auto& trigger : triggers_) {
56  const auto sub_result = trigger->is_triggered(box);
57  if (sub_result.is_triggered) {
58  // We can't short-circuit because we need to make sure we
59  // report the next time that any of the triggers wants to be
60  // checked, whether they triggered now or not.
61  result.is_triggered = true;
62  }
63  result.next_check =
64  std::min(sub_result.next_check, result.next_check, before);
65  }
66  return result;
67  }
68 
69  using is_ready_argument_tags = tmpl::list<Tags::DataBox>;
70 
71  template <typename DbTags>
72  bool is_ready(const db::DataBox<DbTags>& box) const noexcept {
73  return alg::all_of(
74  triggers_,
75  [&box](const std::unique_ptr<DenseTrigger>& trigger) noexcept {
76  return trigger->is_ready(box);
77  });
78  }
79 
80  // NOLINTNEXTLINE(google-runtime-references)
81  void pup(PUP::er& p) noexcept override;
82 
83  private:
85 };
86 } // namespace DenseTriggers
87 
88 template <>
89 struct Options::create_from_yaml<DenseTriggers::Or> {
90  template <typename Metavariables>
91  static DenseTriggers::Or create(const Option& options) {
92  return DenseTriggers::Or(
94  Metavariables>());
95  }
96 };
DenseTriggers::Or
Definition: Or.hpp:33
CharmPupable.hpp
Options.hpp
vector
evolution_comparator
Definition: EvolutionOrdering.hpp:20
ParseOptions.hpp
algorithm
Options::Option
Definition: Options.hpp:108
DenseTrigger
Definition: DenseTrigger.hpp:27
WRAPPED_PUPable_decl_template
#define WRAPPED_PUPable_decl_template(className)
Mark derived classes as serializable.
Definition: CharmPupable.hpp:22
Options::create_from_yaml
Definition: MinmodType.hpp:11
memory
DenseTrigger::Result
Result type for the is_triggered method.
Definition: DenseTrigger.hpp:34
TimeStepId
Definition: TimeStepId.hpp:25
TimeStepId.hpp
Options::String
const char *const String
The string used in option structs.
Definition: Options.hpp:32
std::unique_ptr< DenseTrigger >
alg::all_of
decltype(auto) all_of(const Container &c, UnaryPredicate &&unary_predicate)
Convenience wrapper around std::all_of.
Definition: Algorithm.hpp:181
TMPL.hpp
db
Namespace for DataBox related things.
Definition: DataBox.hpp:44