DenseTrigger.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <limits>
7 #include <pup.h>
8 #include <type_traits>
9 
12 #include "Parallel/Tags/Metavariables.hpp"
13 #include "Utilities/FakeVirtual.hpp"
14 
15 /// \ingroup EventsAndDenseTriggersGroup
16 namespace DenseTriggers {}
17 
18 /// \ingroup EventsAndTriggersGroup
19 /// Base class for checking whether to run an Event at arbitrary times.
20 ///
21 /// The DataBox passed to the member functions will have
22 /// `::Tags::Time`, and therefore any compute tags depending on that
23 /// value, set to the time to be tested. Any discrete properties of
24 /// steps or slabs, such as the step size, may have the values from
25 /// times off by one step. The evolved variables will be in an
26 /// unspecified state.
27 class DenseTrigger : public PUP::able {
28  public:
29  /// %Result type for the `is_triggered` method.
30  ///
31  /// This indicates whether the trigger has fired and the next time
32  /// the trigger should be checked. The consumer is not required to
33  /// wait until the requested time before testing the trigger again.
34  struct Result {
35  bool is_triggered;
36  double next_check;
37  };
38 
39  protected:
40  /// \cond
41  DenseTrigger() = default;
42  DenseTrigger(const DenseTrigger&) = default;
43  DenseTrigger(DenseTrigger&&) = default;
44  DenseTrigger& operator=(const DenseTrigger&) = default;
45  DenseTrigger& operator=(DenseTrigger&&) = default;
46  /// \endcond
47 
48  public:
49  ~DenseTrigger() override = default;
50 
51  /// \cond
52  explicit DenseTrigger(CkMigrateMessage* const msg) noexcept
53  : PUP::able(msg) {}
55  /// \endcond
56 
57  /// Check whether the trigger fires.
58  template <typename DbTags>
59  Result is_triggered(const db::DataBox<DbTags>& box) const noexcept {
60  using factory_classes =
62  box))>::factory_creation::factory_classes;
64  tmpl::at<factory_classes, DenseTrigger>>(
65  this, [&box](auto* const trigger) noexcept {
66  using TriggerType = std::decay_t<decltype(*trigger)>;
67  return db::apply<typename TriggerType::is_triggered_argument_tags>(
68  [&trigger](const auto&... args) noexcept {
69  return trigger->is_triggered(args...);
70  },
71  box);
72  });
73  }
74 
75  /// Check whether all data required to evaluate the trigger is
76  /// available. The trigger is not responsible for checking whether
77  /// dense output of the evolved variables is possible, but may need
78  /// to check things such as the availability of FunctionOfTime data.
79  template <typename DbTags>
80  bool is_ready(const db::DataBox<DbTags>& box) const noexcept {
81  using factory_classes =
83  box))>::factory_creation::factory_classes;
84  return call_with_dynamic_type<bool,
85  tmpl::at<factory_classes, DenseTrigger>>(
86  this, [&box](auto* const trigger) noexcept {
87  using TriggerType = std::decay_t<decltype(*trigger)>;
88  return db::apply<typename TriggerType::is_ready_argument_tags>(
89  [&trigger](const auto&... args) noexcept {
90  return trigger->is_ready(args...);
91  },
92  box);
93  });
94  }
95 };
CharmPupable.hpp
call_with_dynamic_type
Result call_with_dynamic_type(Base *const obj, Callable &&f) noexcept
Call a functor with the derived type of a base class pointer.
Definition: FakeVirtual.hpp:103
DenseTrigger
Definition: DenseTrigger.hpp:27
DataBox.hpp
WRAPPED_PUPable_abstract
#define WRAPPED_PUPable_abstract(className)
Wraps the Charm++ macro, see the Charm++ documentation.
Definition: CharmPupable.hpp:41
DenseTrigger::Result
Result type for the is_triggered method.
Definition: DenseTrigger.hpp:34
std::decay_t
limits
DenseTrigger::is_ready
bool is_ready(const db::DataBox< DbTags > &box) const noexcept
Check whether all data required to evaluate the trigger is available. The trigger is not responsible ...
Definition: DenseTrigger.hpp:80
type_traits
DenseTrigger::is_triggered
Result is_triggered(const db::DataBox< DbTags > &box) const noexcept
Check whether the trigger fires.
Definition: DenseTrigger.hpp:59