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 <tuple> 9 : #include <unordered_map> 10 : #include <unordered_set> 11 : #include <vector> 12 : 13 : #include "DataStructures/DataBox/DataBox.hpp" 14 : #include "Domain/Amr/NeighborsOfParent.hpp" 15 : #include "Domain/Amr/Tags/Flags.hpp" 16 : #include "Domain/Amr/Tags/NeighborFlags.hpp" 17 : #include "Domain/Structure/Direction.hpp" 18 : #include "Domain/Structure/DirectionMap.hpp" 19 : #include "Domain/Structure/DirectionalIdMap.hpp" 20 : #include "Domain/Structure/Element.hpp" 21 : #include "Domain/Structure/ElementId.hpp" 22 : #include "Domain/Structure/Neighbors.hpp" 23 : #include "Domain/Tags.hpp" 24 : #include "Domain/Tags/NeighborMesh.hpp" 25 : #include "NumericalAlgorithms/Spectral/Mesh.hpp" 26 : #include "Parallel/ElementRegistration.hpp" 27 : #include "ParallelAlgorithms/Amr/Projectors/Mesh.hpp" 28 : #include "ParallelAlgorithms/Initialization/MutateAssign.hpp" 29 : #include "Utilities/Gsl.hpp" 30 : #include "Utilities/TMPL.hpp" 31 : #include "Utilities/TaggedTuple.hpp" 32 : 33 : /// \cond 34 : namespace Parallel { 35 : template <typename Metavariables> 36 : class GlobalCache; 37 : } // namespace Parallel 38 : /// \endcond 39 : 40 : namespace amr::Actions { 41 : /// \brief Initializes the data of a newly created parent element from the data 42 : /// of its children elements 43 : /// 44 : /// DataBox: 45 : /// - Modifies: 46 : /// * domain::Tags::Element<volume_dim> 47 : /// * domain::Tags::Mesh<volume_dim> 48 : /// * all return_tags of Metavariables::amr::projectors 49 : /// 50 : /// \details This action is meant to be invoked by 51 : /// amr::Actions::CollectDataFromChildren 52 1 : struct InitializeParent { 53 : template <typename ParallelComponent, typename DbTagList, 54 : typename Metavariables> 55 0 : static void apply( 56 : db::DataBox<DbTagList>& box, Parallel::GlobalCache<Metavariables>& cache, 57 : const ElementId<Metavariables::volume_dim>& parent_id, 58 : std::unordered_map< 59 : ElementId<Metavariables::volume_dim>, 60 : tuples::tagged_tuple_from_typelist< 61 : typename db::DataBox<DbTagList>::mutable_item_creation_tags>> 62 : children_items) { 63 : constexpr size_t volume_dim = Metavariables::volume_dim; 64 : std::vector<std::tuple< 65 : const Element<volume_dim>&, 66 : const std::unordered_map<ElementId<volume_dim>, Info<volume_dim>>&>> 67 : children_elements_and_neighbor_info; 68 : for (const auto& [_, child_items] : children_items) { 69 : children_elements_and_neighbor_info.emplace_back(std::forward_as_tuple( 70 : tuples::get<::domain::Tags::Element<volume_dim>>(child_items), 71 : tuples::get<amr::Tags::NeighborInfo<volume_dim>>(child_items))); 72 : } 73 : auto parent_neighbors = amr::neighbors_of_parent( 74 : parent_id, children_elements_and_neighbor_info); 75 : Element<volume_dim> parent(parent_id, std::move(parent_neighbors.first)); 76 : 77 : std::vector<Mesh<volume_dim>> projected_children_meshes{}; 78 : projected_children_meshes.reserve(children_items.size()); 79 : for (const auto& [child_id, child_items] : children_items) { 80 : const auto& child_mesh = 81 : tuples::get<::domain::Tags::Mesh<volume_dim>>(child_items); 82 : const auto& child_flags = 83 : tuples::get<amr::Tags::Info<volume_dim>>(child_items).flags; 84 : projected_children_meshes.emplace_back( 85 : amr::projectors::mesh(child_mesh, child_flags)); 86 : } 87 : Mesh<volume_dim> parent_mesh = 88 : amr::projectors::parent_mesh(projected_children_meshes); 89 : 90 : // Default initialization of amr::Tags::Info and amr::Tags::NeighborInfo 91 : // is okay 92 : ::Initialization::mutate_assign<tmpl::list< 93 : ::domain::Tags::Element<volume_dim>, ::domain::Tags::Mesh<volume_dim>, 94 : ::domain::Tags::NeighborMesh<volume_dim>>>( 95 : make_not_null(&box), std::move(parent), std::move(parent_mesh), 96 : std::move(parent_neighbors.second)); 97 : 98 : tmpl::for_each<typename Metavariables::amr::projectors>( 99 : [&box, &children_items](auto projector_v) { 100 : using projector = typename decltype(projector_v)::type; 101 : try { 102 : db::mutate_apply<projector>(make_not_null(&box), children_items); 103 : } catch (std::exception& e) { 104 : ERROR("Error in AMR projector '" 105 : << pretty_type::get_name<projector>() << "':\n" 106 : << e.what()); 107 : } 108 : }); 109 : 110 : Parallel::register_element<ParallelComponent>(box, cache, parent_id); 111 : } 112 : }; 113 : } // namespace amr::Actions