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 <unordered_map> 9 : #include <utility> 10 : 11 : #include "DataStructures/TaggedTuple.hpp" 12 : #include "DataStructures/Variables.hpp" 13 : #include "Domain/Structure/ChildSize.hpp" 14 : #include "Domain/Structure/Element.hpp" 15 : #include "Domain/Structure/ElementId.hpp" 16 : #include "Domain/Tags.hpp" 17 : #include "NumericalAlgorithms/Spectral/Mesh.hpp" 18 : #include "NumericalAlgorithms/Spectral/Projection.hpp" 19 : #include "NumericalAlgorithms/Spectral/SegmentSize.hpp" 20 : #include "ParallelAlgorithms/Amr/Protocols/Projector.hpp" 21 : #include "Utilities/Gsl.hpp" 22 : #include "Utilities/MakeArray.hpp" 23 : #include "Utilities/TMPL.hpp" 24 : 25 : namespace amr::projectors { 26 : 27 : /// \brief Update the Variables corresponding to VariablesTags after an AMR 28 : /// change 29 : /// 30 : /// There is a specialization for 31 : /// `ProjectVariables<tmpl::list<VariablesTags...>>` that can be used if a 32 : /// `tmpl::list` is available. 33 : /// 34 : /// \details For each item corresponding to each tag in VariablesTags, project 35 : /// the data for each variable from the old mesh to the new mesh 36 : /// 37 : /// \see ProjectTensors 38 : template <size_t Dim, typename... VariablesTags> 39 1 : struct ProjectVariables : tt::ConformsTo<amr::protocols::Projector> { 40 0 : using return_tags = tmpl::list<VariablesTags...>; 41 0 : using argument_tags = 42 : tmpl::list<domain::Tags::Element<Dim>, domain::Tags::Mesh<Dim>>; 43 : 44 : // p-refinement 45 0 : static void apply( 46 : const gsl::not_null<typename VariablesTags::type*>... vars, 47 : const Element<Dim>& /*element*/, const Mesh<Dim>& new_mesh, 48 : const std::pair<Mesh<Dim>, Element<Dim>>& old_mesh_and_element) { 49 : const auto& old_mesh = old_mesh_and_element.first; 50 : if (old_mesh == new_mesh) { 51 : return; // mesh was not refined, so no projection needed 52 : } 53 : expand_pack((*vars = Spectral::project( 54 : *vars, old_mesh, new_mesh, 55 : make_array<Dim>(Spectral::SegmentSize::Full), 56 : make_array<Dim>(Spectral::SegmentSize::Full)))...); 57 : } 58 : 59 : // h-refinement 60 : template <typename... Tags> 61 0 : static void apply(const gsl::not_null<typename VariablesTags::type*>... vars, 62 : const Element<Dim>& element, const Mesh<Dim>& new_mesh, 63 : const tuples::TaggedTuple<Tags...>& parent_items) { 64 : const auto& element_id = element.id(); 65 : const auto& parent_id = get<domain::Tags::Element<Dim>>(parent_items).id(); 66 : const auto& parent_mesh = get<domain::Tags::Mesh<Dim>>(parent_items); 67 : const auto child_sizes = 68 : domain::child_size(element_id.segment_ids(), parent_id.segment_ids()); 69 : expand_pack((Spectral::project(vars, get<VariablesTags>(parent_items), 70 : parent_mesh, new_mesh, 71 : make_array<Dim>(Spectral::SegmentSize::Full), 72 : child_sizes), 73 : 0)...); 74 : } 75 : 76 : // h-coarsening 77 : template <typename... Tags> 78 0 : static void apply( 79 : const gsl::not_null<typename VariablesTags::type*>... vars, 80 : const Element<Dim>& element, const Mesh<Dim>& new_mesh, 81 : const std::unordered_map<ElementId<Dim>, tuples::TaggedTuple<Tags...>>& 82 : children_items) { 83 : const auto& element_id = element.id(); 84 : bool first_child = true; 85 : for (const auto& [child_id, child_items] : children_items) { 86 : const auto& child_mesh = get<domain::Tags::Mesh<Dim>>(child_items); 87 : const auto child_sizes = 88 : domain::child_size(child_id.segment_ids(), element_id.segment_ids()); 89 : if (first_child) { 90 : expand_pack( 91 : (Spectral::project(vars, get<VariablesTags>(child_items), 92 : child_mesh, new_mesh, child_sizes, 93 : make_array<Dim>(Spectral::SegmentSize::Full)), 94 : 0)...); 95 : first_child = false; 96 : } else { 97 : expand_pack((*vars += Spectral::project( 98 : get<VariablesTags>(child_items), child_mesh, new_mesh, 99 : child_sizes, 100 : make_array<Dim>(Spectral::SegmentSize::Full)))...); 101 : } 102 : } 103 : } 104 : }; 105 : 106 : /// \cond 107 : template <size_t Dim, typename... VariableTags> 108 : struct ProjectVariables<Dim, tmpl::list<VariableTags...>> 109 : : public ProjectVariables<Dim, VariableTags...> {}; 110 : /// \endcond 111 : } // namespace amr::projectors