SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Interpolation/Actions - InterpolatorRegisterElement.hpp Hit Total Coverage
Commit: 361cb8d8406bb752684a5f31c27320ec444a50e3 Lines: 3 10 30.0 %
Date: 2025-11-09 02:02:04
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <cstddef>
       7             : #include <optional>
       8             : 
       9             : #include "DataStructures/DataBox/DataBox.hpp"
      10             : #include "Domain/Creators/Tags/Domain.hpp"
      11             : #include "Parallel/AlgorithmExecution.hpp"
      12             : #include "Parallel/ArrayCollection/IsDgElementCollection.hpp"
      13             : #include "Parallel/GlobalCache.hpp"
      14             : #include "Parallel/Info.hpp"
      15             : #include "Parallel/Invoke.hpp"
      16             : #include "Parallel/Local.hpp"
      17             : #include "Parallel/Protocols/ElementRegistrar.hpp"
      18             : #include "ParallelAlgorithms/Actions/GetItemFromDistributedObject.hpp"
      19             : #include "ParallelAlgorithms/Interpolation/InterpolationTargetDetail.hpp"
      20             : #include "ParallelAlgorithms/Interpolation/Tags.hpp"
      21             : #include "Utilities/Gsl.hpp"
      22             : #include "Utilities/PrettyType.hpp"
      23             : #include "Utilities/ProtocolHelpers.hpp"
      24             : #include "Utilities/Requires.hpp"
      25             : #include "Utilities/StdHelpers.hpp"
      26             : #include "Utilities/TMPL.hpp"
      27             : #include "Utilities/TaggedTuple.hpp"
      28             : 
      29             : /// \cond
      30             : namespace ah::Tags {
      31             : struct BlocksForInterpolation;
      32             : }  // namespace ah::Tags
      33             : namespace db {
      34             : template <typename TagsList>
      35             : class DataBox;
      36             : }  // namespace db
      37             : namespace intrp {
      38             : template <typename Metavariables>
      39             : struct Interpolator;
      40             : }  // namespace intrp
      41             : /// \endcond
      42             : 
      43             : namespace intrp {
      44             : namespace Actions {
      45             : 
      46             : /// \ingroup ActionsGroup
      47             : /// \brief Invoked on the `Interpolator` ParallelComponent to register an
      48             : /// element with the `Interpolator`.
      49             : ///
      50             : /// This is called by `RegisterElementWithInterpolator` below.
      51             : ///
      52             : /// Uses: nothing
      53             : ///
      54             : /// DataBox changes:
      55             : /// - Adds: nothing
      56             : /// - Removes: nothing
      57             : /// - Modifies:
      58             : ///   - `Tags::NumberOfElements`
      59             : ///
      60             : /// For requirements on Metavariables, see `InterpolationTarget`.
      61           1 : struct RegisterElement {
      62             :   template <typename ParallelComponent, typename DbTags, typename Metavariables,
      63             :             typename ArrayIndex>
      64           0 :   static void apply(db::DataBox<DbTags>& box,
      65             :                     const Parallel::GlobalCache<Metavariables>& cache,
      66             :                     const ArrayIndex& /*array_index*/,
      67             :                     const ElementId<Metavariables::volume_dim>& element_id) {
      68             :     using sequential_targets =
      69             :         intrp::InterpolationTarget_detail::get_sequential_target_tags<
      70             :             Metavariables>;
      71             :     const auto& blocks_to_interpolate =
      72             :         Parallel::get<ah::Tags::BlocksForInterpolation>(cache);
      73             :     const auto& blocks =
      74             :         Parallel::get<domain::Tags::Domain<Metavariables::volume_dim>>(cache)
      75             :             .blocks();
      76             :     db::mutate<Tags::NumberOfElements<Metavariables::volume_dim>>(
      77             :         [&](const gsl::not_null<std::unordered_map<
      78             :                 std::string,
      79             :                 std::unordered_set<ElementId<Metavariables::volume_dim>>>*>
      80             :                 num_elements) {
      81             :           const auto& block_name = blocks[element_id.block_id()].name();
      82             : 
      83             :           tmpl::for_each<sequential_targets>([&](auto target_v) {
      84             :             using target = tmpl::type_from<decltype(target_v)>;
      85             :             const std::string& target_name = pretty_type::name<target>();
      86             :             if (not blocks_to_interpolate.contains(target_name)) {
      87             :               ERROR("Target " << target_name
      88             :                               << " not in blocks to interpolate: "
      89             :                               << keys_of(blocks_to_interpolate));
      90             :             }
      91             : 
      92             :             if (blocks_to_interpolate.at(target_name).contains(block_name)) {
      93             :               (*num_elements)[target_name].insert(element_id);
      94             :             }
      95             :           });
      96             :         },
      97             :         make_not_null(&box));
      98             :   }
      99             : };
     100             : 
     101             : /// \ingroup ActionsGroup
     102             : /// \brief Invoked on the `Interpolator` ParallelComponent to deregister an
     103             : /// element with the `Interpolator`.
     104             : ///
     105             : /// This is called by `RegisterElementWithInterpolator` below.
     106             : ///
     107             : /// Uses: nothing
     108             : ///
     109             : /// DataBox changes:
     110             : /// - Adds: nothing
     111             : /// - Removes: nothing
     112             : /// - Modifies:
     113             : ///   - `Tags::NumberOfElements`
     114             : ///
     115             : /// For requirements on Metavariables, see `InterpolationTarget`.
     116           1 : struct DeregisterElement {
     117             :   template <typename ParallelComponent, typename DbTags, typename Metavariables,
     118             :             typename ArrayIndex>
     119           0 :   static void apply(db::DataBox<DbTags>& box,
     120             :                     const Parallel::GlobalCache<Metavariables>& cache,
     121             :                     const ArrayIndex& /*array_index*/,
     122             :                     const ElementId<Metavariables::volume_dim>& element_id) {
     123             :     using sequential_targets =
     124             :         intrp::InterpolationTarget_detail::get_sequential_target_tags<
     125             :             Metavariables>;
     126             :     const auto& blocks_to_interpolate =
     127             :         Parallel::get<ah::Tags::BlocksForInterpolation>(cache);
     128             :     const auto& blocks =
     129             :         Parallel::get<domain::Tags::Domain<Metavariables::volume_dim>>(cache)
     130             :             .blocks();
     131             :     db::mutate<Tags::NumberOfElements<Metavariables::volume_dim>>(
     132             :         [&](const gsl::not_null<std::unordered_map<
     133             :                 std::string,
     134             :                 std::unordered_set<ElementId<Metavariables::volume_dim>>>*>
     135             :                 num_elements) {
     136             :           const auto& block_name = blocks[element_id.block_id()].name();
     137             : 
     138             :           tmpl::for_each<sequential_targets>([&](auto target_v) {
     139             :             using target = tmpl::type_from<decltype(target_v)>;
     140             :             const std::string& target_name = pretty_type::name<target>();
     141             :             if (not blocks_to_interpolate.contains(target_name)) {
     142             :               ERROR("Target " << target_name
     143             :                               << " not in blocks to interpolate: "
     144             :                               << keys_of(blocks_to_interpolate));
     145             :             }
     146             : 
     147             :             if (blocks_to_interpolate.at(target_name).contains(block_name)) {
     148             :               const size_t num_elements_removed =
     149             :                   (*num_elements)[target_name].erase(element_id);
     150             :               if (num_elements_removed == 0) {
     151             :                 ERROR("Unable to remove element "
     152             :                       << element_id << " from interpolator core "
     153             :                       << Parallel::my_proc<size_t>(cache) << " for target "
     154             :                       << target_name);
     155             :               }
     156             :             }
     157             :           });
     158             :         },
     159             :         make_not_null(&box));
     160             :   }
     161             : };
     162             : 
     163             : /// \ingroup ActionsGroup
     164             : /// \brief Invoked on `DgElementArray` to register all its elements with the
     165             : /// `Interpolator`.
     166             : ///
     167             : /// Uses: nothing
     168             : ///
     169             : /// DataBox changes:
     170             : /// - Adds: nothing
     171             : /// - Removes: nothing
     172             : /// - Modifies: nothing
     173             : ///
     174             : /// When this struct is used as an action, the `apply` function will perform the
     175             : /// registration with the interpolator. However, this struct also offers the
     176             : /// static member functions `perform_registration` and `perform_deregistration`
     177             : /// that are needed for either registering when an element is added to a core
     178             : /// outside of initialization or deregistering when an element is being
     179             : /// eliminated from a core. The use of separate functions is necessary to
     180             : /// provide an interface usable outside of iterable actions, e.g. in specialized
     181             : /// `pup` functions.
     182           1 : struct RegisterElementWithInterpolator
     183             :     : tt::ConformsTo<Parallel::protocols::ElementRegistrar> {
     184             :  private:
     185             :   template <typename ParallelComponent, typename RegisterOrDeregisterAction,
     186             :             typename Metavariables, typename ArrayIndex>
     187           0 :   static void register_or_deregister_impl(
     188             :       Parallel::GlobalCache<Metavariables>& cache,
     189             :       const ArrayIndex& array_index) {
     190             :     if constexpr (Parallel::is_dg_element_collection_v<ParallelComponent>) {
     191             :       const auto core_id = static_cast<int>(
     192             :           Parallel::local_synchronous_action<
     193             :               Parallel::Actions::GetItemFromDistributedOject<
     194             :                   typename ParallelComponent::element_collection_tag>>(
     195             :               Parallel::get_parallel_component<ParallelComponent>(cache))
     196             :               ->at(array_index)
     197             :               .get_core());
     198             :       auto interpolator = Parallel::get_parallel_component<
     199             :           ::intrp::Interpolator<Metavariables>>(cache)[core_id];
     200             :       Parallel::simple_action<RegisterOrDeregisterAction>(interpolator,
     201             :                                                           array_index);
     202             :     } else {
     203             :       auto& interpolator =
     204             :           *Parallel::local_branch(Parallel::get_parallel_component<
     205             :                                   ::intrp::Interpolator<Metavariables>>(cache));
     206             :       Parallel::simple_action<RegisterOrDeregisterAction>(interpolator,
     207             :                                                           array_index);
     208             :     }
     209             :   }
     210             : 
     211             :  public:  // ElementRegistrar protocol
     212             :   template <typename ParallelComponent, typename DbTagList,
     213             :             typename Metavariables, typename ArrayIndex>
     214           0 :   static void perform_registration(const db::DataBox<DbTagList>& /*box*/,
     215             :                                    Parallel::GlobalCache<Metavariables>& cache,
     216             :                                    const ArrayIndex& array_index) {
     217             :     register_or_deregister_impl<ParallelComponent, RegisterElement>(
     218             :         cache, array_index);
     219             :   }
     220             : 
     221             :   template <typename ParallelComponent, typename DbTagList,
     222             :             typename Metavariables, typename ArrayIndex>
     223           0 :   static void perform_deregistration(
     224             :       const db::DataBox<DbTagList>& /*box*/,
     225             :       Parallel::GlobalCache<Metavariables>& cache,
     226             :       const ArrayIndex& array_index) {
     227             :     register_or_deregister_impl<ParallelComponent, DeregisterElement>(
     228             :         cache, array_index);
     229             :   }
     230             : 
     231             :  public:  // Iterable action
     232             :   template <typename DbTagList, typename... InboxTags, typename Metavariables,
     233             :             typename ArrayIndex, typename ActionList,
     234             :             typename ParallelComponent>
     235           0 :   static Parallel::iterable_action_return_t apply(
     236             :       db::DataBox<DbTagList>& box,
     237             :       const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
     238             :       Parallel::GlobalCache<Metavariables>& cache,
     239             :       const ArrayIndex& array_index, const ActionList /*meta*/,
     240             :       const ParallelComponent* const /*meta*/) {
     241             :     perform_registration<ParallelComponent>(box, cache, array_index);
     242             :     return {Parallel::AlgorithmExecution::Continue, std::nullopt};
     243             :   }
     244             : };
     245             : 
     246             : }  // namespace Actions
     247             : }  // namespace intrp

Generated by: LCOV version 1.14