11 #include "IO/Observer/Actions/ObserverRegistration.hpp"
12 #include "IO/Observer/ArrayComponentId.hpp"
13 #include "IO/Observer/ObserverComponent.hpp"
14 #include "IO/Observer/Tags.hpp"
15 #include "IO/Observer/TypeOfObservation.hpp"
17 #include "Parallel/Invoke.hpp"
21 #include "Utilities/TaggedTuple.hpp"
22 #include "Utilities/TypeTraits/CreateHasTypeAlias.hpp"
27 CREATE_HAS_TYPE_ALIAS_V(observation_registration_tags)
39 template <
typename EventRegistrars,
typename DbTagsList>
42 get_registration_observation_type_and_key(
44 const db::DataBox<DbTagsList>& box) noexcept {
48 bool already_registered =
false;
49 tmpl::for_each<typename Event<EventRegistrars>::creatable_classes>(
50 [&already_registered, &box, &event, &result](
auto event_type_v) noexcept {
51 using EventType =
typename decltype(event_type_v)::type;
52 if constexpr (detail::has_observation_registration_tags_v<EventType>) {
61 const auto*
const derived_class_ptr =
62 dynamic_cast<const EventType*
>(&event);
63 if (derived_class_ptr !=
nullptr) {
64 if (already_registered) {
66 "Already registered the event by casting down to a "
67 "different Event derived class. This means you have an "
68 "Event where A inherits from B and both A and B define "
69 "get_observation_type_and_id_for_registration. This "
70 "behavior is not supported. Please make a separate Event.");
72 already_registered =
true;
74 db::apply<typename EventType::observation_registration_tags>(
75 [&derived_class_ptr](
const auto&... args) noexcept {
76 return derived_class_ptr
77 ->get_observation_type_and_key_for_registration(
98 template <
typename DbTagList,
typename... InboxTags,
typename Metavariables,
99 typename ArrayIndex,
typename ActionList,
100 typename ParallelComponent>
102 db::DataBox<DbTagList>& box,
105 const ArrayIndex& array_index,
const ActionList ,
106 const ParallelComponent*
const ) noexcept {
108 *Parallel::get_parallel_component<observers::Observer<Metavariables>>(
113 type_of_observation_and_observation_key_pairs;
115 const auto& triggers_and_events =
116 db::get<::Tags::EventsAndTriggersBase>(box);
117 for (
const auto& trigger_and_events :
118 triggers_and_events.events_and_triggers()) {
119 for (
const auto& event : trigger_and_events.second) {
120 if (
auto obs_type_and_obs_key =
121 get_registration_observation_type_and_key(*event, box);
122 obs_type_and_obs_key.has_value()) {
123 type_of_observation_and_observation_key_pairs.push_back(
124 *obs_type_and_obs_key);
129 for (
const auto& [type_of_observation, observation_key] :
130 type_of_observation_and_observation_key_pairs) {
131 Parallel::simple_action<RegisterContributorWithObserver>(
132 observer, observation_key,
136 type_of_observation);
138 return {std::move(box)};