Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <optional> 7 : #include <type_traits> 8 : #include <utility> 9 : #include <vector> 10 : 11 : #include "DataStructures/DataBox/DataBox.hpp" 12 : #include "IO/Observer/Actions/ObserverRegistration.hpp" 13 : #include "IO/Observer/ObservationId.hpp" 14 : #include "IO/Observer/ObserverComponent.hpp" 15 : #include "IO/Observer/TypeOfObservation.hpp" 16 : #include "Parallel/AlgorithmExecution.hpp" 17 : #include "Parallel/ArrayIndex.hpp" 18 : #include "Parallel/GlobalCache.hpp" 19 : #include "Parallel/Invoke.hpp" 20 : #include "Parallel/Local.hpp" 21 : #include "Parallel/Protocols/ElementRegistrar.hpp" 22 : #include "Utilities/ProtocolHelpers.hpp" 23 : 24 : /// \cond 25 : template <class... Tags> 26 : class TaggedTuple; 27 : /// \endcond 28 : 29 : namespace observers::Actions { 30 : /*! 31 : * \brief Register an observation ID with the observers. 32 : * 33 : * \warning If registering events, you should use RegisterEventsWithObservers 34 : * instead. If your event is not compatible with RegisterEventsWithObservers, 35 : * please make it so. 36 : * 37 : * The `RegisterHelper` passed as a template parameter must have a static 38 : * `register_info` function that takes as its first template parameter the 39 : * `ParallelComponent` and as function arguments a `db::DataBox` and the array 40 : * component index. The function must return a 41 : * `std::pair<observers::TypeOfObservation, observers::ObservationId>` 42 : * 43 : * When this struct is used as an action, the `apply` function will perform the 44 : * registration with observers. However, this struct also offers the static 45 : * member functions `perform_registriation` and `perform_deregistration` that 46 : * are needed for either registering when an element is added to a core outside 47 : * of initialization or deregistering when an element is being eliminated from a 48 : * core. The use of separate functions is necessary to provide an interface 49 : * usable outside of iterable actions, e.g. in specialized `pup` functions. 50 : */ 51 : template <typename RegisterHelper> 52 1 : struct RegisterWithObservers 53 : : tt::ConformsTo<Parallel::protocols::ElementRegistrar> { 54 : private: 55 : template <typename ParallelComponent, typename RegisterOrDeregisterAction, 56 : typename DbTagList, typename Metavariables, typename ArrayIndex> 57 0 : static void register_or_deregister_impl( 58 : db::DataBox<DbTagList>& box, Parallel::GlobalCache<Metavariables>& cache, 59 : const ArrayIndex& array_index) { 60 : auto& observer = *Parallel::local_branch( 61 : Parallel::get_parallel_component<observers::Observer<Metavariables>>( 62 : cache)); 63 : const auto [type_of_observation, observation_id] = 64 : RegisterHelper::template register_info<ParallelComponent>(box, 65 : array_index); 66 : 67 : Parallel::simple_action<RegisterOrDeregisterAction>( 68 : observer, observation_id, 69 : Parallel::make_array_component_id<ParallelComponent>(array_index), 70 : type_of_observation); 71 : } 72 : 73 : public: // ElementRegistrar protocol 74 : template <typename ParallelComponent, typename DbTagList, 75 : typename Metavariables, typename ArrayIndex> 76 0 : static void perform_registration(db::DataBox<DbTagList>& box, 77 : Parallel::GlobalCache<Metavariables>& cache, 78 : const ArrayIndex& array_index) { 79 : register_or_deregister_impl<ParallelComponent, 80 : RegisterContributorWithObserver>(box, cache, 81 : array_index); 82 : } 83 : 84 : template <typename ParallelComponent, typename DbTagList, 85 : typename Metavariables, typename ArrayIndex> 86 0 : static void perform_deregistration( 87 : db::DataBox<DbTagList>& box, Parallel::GlobalCache<Metavariables>& cache, 88 : const ArrayIndex& array_index) { 89 : register_or_deregister_impl<ParallelComponent, 90 : DeregisterContributorWithObserver>(box, cache, 91 : array_index); 92 : } 93 : 94 : public: // Iterable action 95 : template <typename DbTagList, typename... InboxTags, typename Metavariables, 96 : typename ArrayIndex, typename ActionList, 97 : typename ParallelComponent> 98 0 : static Parallel::iterable_action_return_t apply( 99 : db::DataBox<DbTagList>& box, 100 : const tuples::TaggedTuple<InboxTags...>& /*inboxes*/, 101 : Parallel::GlobalCache<Metavariables>& cache, 102 : const ArrayIndex& array_index, const ActionList /*meta*/, 103 : const ParallelComponent* const /*meta*/) { 104 : perform_registration<ParallelComponent>(box, cache, array_index); 105 : return {Parallel::AlgorithmExecution::Continue, std::nullopt}; 106 : } 107 : }; 108 : } // namespace observers::Actions