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
|