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 : 8 : #include "DataStructures/DataBox/DataBox.hpp" 9 : #include "Parallel/AlgorithmExecution.hpp" 10 : #include "Parallel/GlobalCache.hpp" 11 : #include "Parallel/Invoke.hpp" 12 : #include "Parallel/Local.hpp" 13 : #include "Parallel/Protocols/ElementRegistrar.hpp" 14 : #include "ParallelAlgorithms/Interpolation/Tags.hpp" // IWYU pragma: keep 15 : #include "Utilities/Gsl.hpp" 16 : #include "Utilities/ProtocolHelpers.hpp" 17 : #include "Utilities/Requires.hpp" 18 : #include "Utilities/TaggedTuple.hpp" 19 : 20 : /// \cond 21 : namespace db { 22 : template <typename TagsList> 23 : class DataBox; 24 : } // namespace db 25 : namespace intrp { 26 : template <typename Metavariables> 27 : struct Interpolator; 28 : } // namespace intrp 29 : /// \endcond 30 : 31 : namespace intrp { 32 : namespace Actions { 33 : 34 : /// \ingroup ActionsGroup 35 : /// \brief Invoked on the `Interpolator` ParallelComponent to register an 36 : /// element with the `Interpolator`. 37 : /// 38 : /// This is called by `RegisterElementWithInterpolator` below. 39 : /// 40 : /// Uses: nothing 41 : /// 42 : /// DataBox changes: 43 : /// - Adds: nothing 44 : /// - Removes: nothing 45 : /// - Modifies: 46 : /// - `Tags::NumberOfElements` 47 : /// 48 : /// For requirements on Metavariables, see `InterpolationTarget`. 49 1 : struct RegisterElement { 50 : template <typename ParallelComponent, typename DbTags, typename Metavariables, 51 : typename ArrayIndex> 52 0 : static void apply(db::DataBox<DbTags>& box, 53 : const Parallel::GlobalCache<Metavariables>& /*cache*/, 54 : const ArrayIndex& /*array_index*/) { 55 : db::mutate<Tags::NumberOfElements>( 56 : [](const gsl::not_null<size_t*> num_elements) { ++(*num_elements); }, 57 : make_not_null(&box)); 58 : } 59 : }; 60 : 61 : /// \ingroup ActionsGroup 62 : /// \brief Invoked on the `Interpolator` ParallelComponent to deregister an 63 : /// element with the `Interpolator`. 64 : /// 65 : /// This is called by `RegisterElementWithInterpolator` below. 66 : /// 67 : /// Uses: nothing 68 : /// 69 : /// DataBox changes: 70 : /// - Adds: nothing 71 : /// - Removes: nothing 72 : /// - Modifies: 73 : /// - `Tags::NumberOfElements` 74 : /// 75 : /// For requirements on Metavariables, see `InterpolationTarget`. 76 1 : struct DeregisterElement { 77 : template <typename ParallelComponent, typename DbTags, typename Metavariables, 78 : typename ArrayIndex> 79 0 : static void apply(db::DataBox<DbTags>& box, 80 : const Parallel::GlobalCache<Metavariables>& /*cache*/, 81 : const ArrayIndex& /*array_index*/) { 82 : db::mutate<Tags::NumberOfElements>( 83 : [](const gsl::not_null<size_t*> num_elements) { --(*num_elements); }, 84 : make_not_null(&box)); 85 : } 86 : }; 87 : 88 : /// \ingroup ActionsGroup 89 : /// \brief Invoked on `DgElementArray` to register all its elements with the 90 : /// `Interpolator`. 91 : /// 92 : /// Uses: nothing 93 : /// 94 : /// DataBox changes: 95 : /// - Adds: nothing 96 : /// - Removes: nothing 97 : /// - Modifies: nothing 98 : /// 99 : /// When this struct is used as an action, the `apply` function will perform the 100 : /// registration with the interpolator. However, this struct also offers the 101 : /// static member functions `perform_registration` and `perform_deregistration` 102 : /// that are needed for either registering when an element is added to a core 103 : /// outside of initialization or deregistering when an element is being 104 : /// eliminated from a core. The use of separate functions is necessary to 105 : /// provide an interface usable outside of iterable actions, e.g. in specialized 106 : /// `pup` functions. 107 1 : struct RegisterElementWithInterpolator 108 : : tt::ConformsTo<Parallel::protocols::ElementRegistrar> { 109 : private: 110 : template <typename ParallelComponent, typename RegisterOrDeregisterAction, 111 : typename Metavariables, typename ArrayIndex> 112 0 : static void register_or_deregister_impl( 113 : Parallel::GlobalCache<Metavariables>& cache, 114 : const ArrayIndex& /*array_index*/) { 115 : auto& interpolator = *Parallel::local_branch( 116 : Parallel::get_parallel_component<::intrp::Interpolator<Metavariables>>( 117 : cache)); 118 : Parallel::simple_action<RegisterOrDeregisterAction>(interpolator); 119 : } 120 : 121 : public: // ElementRegistrar protocol 122 : template <typename ParallelComponent, typename DbTagList, 123 : typename Metavariables, typename ArrayIndex> 124 0 : static void perform_registration(const db::DataBox<DbTagList>& /*box*/, 125 : Parallel::GlobalCache<Metavariables>& cache, 126 : const ArrayIndex& array_index) { 127 : register_or_deregister_impl<ParallelComponent, RegisterElement>( 128 : cache, array_index); 129 : } 130 : 131 : template <typename ParallelComponent, typename DbTagList, 132 : typename Metavariables, typename ArrayIndex> 133 0 : static void perform_deregistration( 134 : const db::DataBox<DbTagList>& /*box*/, 135 : Parallel::GlobalCache<Metavariables>& cache, 136 : const ArrayIndex& array_index) { 137 : register_or_deregister_impl<ParallelComponent, DeregisterElement>( 138 : cache, array_index); 139 : } 140 : 141 : public: // Iterable action 142 : template <typename DbTagList, typename... InboxTags, typename Metavariables, 143 : typename ArrayIndex, typename ActionList, 144 : typename ParallelComponent> 145 0 : static Parallel::iterable_action_return_t apply( 146 : db::DataBox<DbTagList>& box, 147 : const tuples::TaggedTuple<InboxTags...>& /*inboxes*/, 148 : Parallel::GlobalCache<Metavariables>& cache, 149 : const ArrayIndex& array_index, const ActionList /*meta*/, 150 : const ParallelComponent* const /*meta*/) { 151 : perform_registration<ParallelComponent>(box, cache, array_index); 152 : return {Parallel::AlgorithmExecution::Continue, std::nullopt}; 153 : } 154 : }; 155 : 156 : } // namespace Actions 157 : } // namespace intrp