SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Amr/Actions - CollectDataFromChildren.hpp Hit Total Coverage
Commit: b5f497991094937944b0a3f519166bb54739d08a Lines: 3 4 75.0 %
Date: 2024-03-28 18:20:13
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 <array>
       7             : #include <cstddef>
       8             : #include <deque>
       9             : #include <unordered_map>
      10             : #include <utility>
      11             : 
      12             : #include "DataStructures/DataBox/DataBox.hpp"
      13             : #include "Domain/Amr/Flag.hpp"
      14             : #include "Domain/Amr/Helpers.hpp"
      15             : #include "Domain/Amr/Tags/Flags.hpp"
      16             : #include "Domain/Structure/Element.hpp"
      17             : #include "Domain/Structure/ElementId.hpp"
      18             : #include "Domain/Tags.hpp"
      19             : #include "Parallel/ElementRegistration.hpp"
      20             : #include "Parallel/GlobalCache.hpp"
      21             : #include "Parallel/Invoke.hpp"
      22             : #include "ParallelAlgorithms/Amr/Actions/InitializeParent.hpp"
      23             : #include "Utilities/Algorithm.hpp"
      24             : #include "Utilities/TMPL.hpp"
      25             : #include "Utilities/TaggedTuple.hpp"
      26             : 
      27             : namespace amr::Actions {
      28             : /// \brief Collects data from child elements to send to their parent element
      29             : /// during adaptive mesh refinement
      30           1 : struct CollectDataFromChildren {
      31             :   /// \brief  This function should be called after the parent element has been
      32             :   /// created by amr::Actions::CreateParent.
      33             :   ///
      34             :   /// \details This function sends a copy of all items corresponding to the
      35             :   /// mutable_item_creation_tags of `box` of `child_id` to the first sibling in
      36             :   /// `sibling_ids_to_collect` by invoking this action.  Finally, the child
      37             :   /// element destroys itself.
      38             :   template <typename ParallelComponent, typename DbTagList,
      39             :             typename Metavariables>
      40           1 :   static void apply(
      41             :       db::DataBox<DbTagList>& box, Parallel::GlobalCache<Metavariables>& cache,
      42             :       const ElementId<Metavariables::volume_dim>& child_id,
      43             :       const ElementId<Metavariables::volume_dim>& parent_id,
      44             :       std::deque<ElementId<Metavariables::volume_dim>> sibling_ids_to_collect) {
      45             :     std::unordered_map<ElementId<Metavariables::volume_dim>,
      46             :                        tuples::tagged_tuple_from_typelist<typename db::DataBox<
      47             :                            DbTagList>::mutable_item_creation_tags>>
      48             :         children_data{};
      49             :     children_data.emplace(
      50             :         child_id,
      51             :         db::copy_items<
      52             :             typename db::DataBox<DbTagList>::mutable_item_creation_tags>(box));
      53             :     const auto next_child_id = sibling_ids_to_collect.front();
      54             :     sibling_ids_to_collect.pop_front();
      55             :     auto& array_proxy =
      56             :         Parallel::get_parallel_component<ParallelComponent>(cache);
      57             :     Parallel::simple_action<CollectDataFromChildren>(
      58             :         array_proxy[next_child_id], parent_id, sibling_ids_to_collect,
      59             :         std::move(children_data));
      60             : 
      61             :     Parallel::deregister_element<ParallelComponent>(box, cache, child_id);
      62             :     array_proxy[child_id].ckDestroy();
      63             :   }
      64             : 
      65             :   /// \brief  This function should be called after a child element has added its
      66             :   /// data to `children_data` by a previous invocation of this action.
      67             :   ///
      68             :   /// \details This function adds a copy of all items corresponding to the
      69             :   /// mutable_item_creation_tags of `box` of `child_id` to `children_data`.
      70             :   /// In addition, it checks if there are additional siblings that need to be
      71             :   /// added to `sibiling_ids_to_collect`.  (This is necessary as not all
      72             :   /// siblings share a face.) If `sibling_ids_to_collect` is not empty, this
      73             :   /// action is invoked again on the first sibling in `sibling_ids_to_collect`.
      74             :   /// If it is empty, the data is sent to the parent element by calling
      75             :   /// amr::Actions::InitializeParent. Finally, the child element destroys
      76             :   /// itself.
      77             :   template <typename ParallelComponent, typename DbTagList,
      78             :             typename Metavariables>
      79           1 :   static void apply(
      80             :       db::DataBox<DbTagList>& box, Parallel::GlobalCache<Metavariables>& cache,
      81             :       const ElementId<Metavariables::volume_dim>& child_id,
      82             :       const ElementId<Metavariables::volume_dim>& parent_id,
      83             :       std::deque<ElementId<Metavariables::volume_dim>> sibling_ids_to_collect,
      84             :       std::unordered_map<
      85             :           ElementId<Metavariables::volume_dim>,
      86             :           tuples::tagged_tuple_from_typelist<
      87             :               typename db::DataBox<DbTagList>::mutable_item_creation_tags>>
      88             :           children_data) {
      89             :     constexpr size_t volume_dim = Metavariables::volume_dim;
      90             : 
      91             :     // Determine if there are additional siblings that are joining
      92             :     // This is necessary because AMR flags are only communicated to face
      93             :     // neighbors.
      94             :     const auto& element = db::get<::domain::Tags::Element<volume_dim>>(box);
      95             :     const auto& my_amr_flags = db::get<amr::Tags::Info<volume_dim>>(box).flags;
      96             :     auto ids_to_join = amr::ids_of_joining_neighbors(element, my_amr_flags);
      97             :     for (const auto& id_to_check : ids_to_join) {
      98             :       if (alg::count(sibling_ids_to_collect, id_to_check) == 0 and
      99             :           children_data.count(id_to_check) == 0) {
     100             :         sibling_ids_to_collect.emplace_back(id_to_check);
     101             :       }
     102             :     }
     103             : 
     104             :     children_data.emplace(
     105             :         child_id,
     106             :         db::copy_items<
     107             :             typename db::DataBox<DbTagList>::mutable_item_creation_tags>(box));
     108             :     auto& array_proxy =
     109             :         Parallel::get_parallel_component<ParallelComponent>(cache);
     110             : 
     111             :     if (sibling_ids_to_collect.empty()) {
     112             :       Parallel::simple_action<InitializeParent>(array_proxy[parent_id],
     113             :                                                 std::move(children_data));
     114             :     } else {
     115             :       const auto next_child_id = sibling_ids_to_collect.front();
     116             :       sibling_ids_to_collect.pop_front();
     117             :       Parallel::simple_action<CollectDataFromChildren>(
     118             :           array_proxy[next_child_id], parent_id, sibling_ids_to_collect,
     119             :           std::move(children_data));
     120             :     }
     121             : 
     122             :     Parallel::deregister_element<ParallelComponent>(box, cache, child_id);
     123             :     array_proxy[child_id].ckDestroy();
     124             :   }
     125             : };
     126             : }  // namespace amr::Actions

Generated by: LCOV version 1.14