Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <limits> 7 : #include <vector> 8 : 9 : #include "DataStructures/DataBox/DataBox.hpp" 10 : #include "Domain/Structure/ElementId.hpp" 11 : #include "Parallel/ElementRegistration.hpp" 12 : #include "Parallel/GlobalCache.hpp" 13 : #include "Parallel/Invoke.hpp" 14 : #include "ParallelAlgorithms/Amr/Actions/InitializeChild.hpp" 15 : #include "ParallelAlgorithms/Amr/Tags.hpp" 16 : 17 : namespace amr::Actions { 18 : /// \brief Sends data from the parent element to its children elements during 19 : /// adaptive mesh refinement 20 : /// 21 : /// \details This action should be called after all children elements have been 22 : /// created by amr::Actions::CreateChild. This action sends a copy of all items 23 : /// corresponding to the mutable_item_creation_tags of `box` to each of the 24 : /// elements with `ids_of_children`. Finally, the parent element destroys 25 : /// itself. 26 1 : struct SendDataToChildren { 27 : template <typename ParallelComponent, typename DbTagList, 28 : typename Metavariables, size_t Dim> 29 0 : static void apply(db::DataBox<DbTagList>& box, 30 : Parallel::GlobalCache<Metavariables>& cache, 31 : const ElementId<Dim>& element_id, 32 : const std::vector<ElementId<Dim>>& ids_of_children) { 33 : auto& array_proxy = 34 : Parallel::get_parallel_component<ParallelComponent>(cache); 35 : for (const auto& child_id : ids_of_children) { 36 : Parallel::simple_action<amr::Actions::InitializeChild>( 37 : array_proxy[child_id], 38 : db::copy_items< 39 : typename db::DataBox<DbTagList>::mutable_item_creation_tags>( 40 : box)); 41 : } 42 : 43 : if constexpr (Metavariables::amr::keep_coarse_grids) { 44 : if (db::get<amr::Tags::MaxCoarseLevels>(box).value_or( 45 : std::numeric_limits<size_t>::max()) > 0) { 46 : // Register the children elements in the parent element 47 : Parallel::deregister_element<ParallelComponent>(box, cache, element_id); 48 : ::Initialization::mutate_assign<tmpl::list<amr::Tags::ChildIds<Dim>>>( 49 : make_not_null(&box), 50 : std::unordered_set<ElementId<Dim>>{ids_of_children.begin(), 51 : ids_of_children.end()}); 52 : Parallel::register_element<ParallelComponent>(box, cache, element_id); 53 : // Note: we don't run AMR projectors on the parent element because the 54 : // parent element didn't change, with the exception of 55 : // `amr::Tags::ChildIds<Dim>`. 56 : // Reset the AMR flags 57 : db::mutate<amr::Tags::Info<Dim>, amr::Tags::NeighborInfo<Dim>>( 58 : [](const gsl::not_null<amr::Info<Dim>*> amr_info, 59 : const gsl::not_null< 60 : std::unordered_map<ElementId<Dim>, amr::Info<Dim>>*> 61 : amr_info_of_neighbors) { 62 : amr_info_of_neighbors->clear(); 63 : for (size_t d = 0; d < Dim; ++d) { 64 : amr_info->flags[d] = amr::Flag::Undefined; 65 : } 66 : }, 67 : make_not_null(&box)); 68 : return; 69 : } 70 : } 71 : 72 : // Destroy the parent element 73 : Parallel::deregister_element<ParallelComponent>(box, cache, element_id); 74 : array_proxy[element_id].ckDestroy(); 75 : } 76 : }; 77 : } // namespace amr::Actions