Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <cstddef> 7 : #include <unordered_map> 8 : #include <utility> 9 : 10 : #include "DataStructures/ApplyMatrices.hpp" 11 : #include "DataStructures/Variables.hpp" 12 : #include "Domain/Structure/Element.hpp" 13 : #include "Domain/Structure/ElementId.hpp" 14 : #include "Domain/Tags.hpp" 15 : #include "NumericalAlgorithms/Spectral/Mesh.hpp" 16 : #include "NumericalAlgorithms/Spectral/Projection.hpp" 17 : #include "ParallelAlgorithms/Amr/Protocols/Projector.hpp" 18 : #include "Utilities/Gsl.hpp" 19 : #include "Utilities/TMPL.hpp" 20 : #include "Utilities/TaggedTuple.hpp" 21 : 22 : namespace amr::projectors { 23 : 24 : /// \brief Update the Variables corresponding to VariablesTags after an AMR 25 : /// change 26 : /// 27 : /// There is a specialization for 28 : /// `ProjectVariables<tmpl::list<VariablesTags...>>` that can be used if a 29 : /// `tmpl::list` is available. 30 : /// 31 : /// \details For each item corresponding to each tag in VariablesTags, project 32 : /// the data for each variable from the old mesh to the new mesh 33 : /// 34 : /// \see ProjectTensors 35 : template <size_t Dim, typename... VariablesTags> 36 1 : struct ProjectVariables : tt::ConformsTo<amr::protocols::Projector> { 37 0 : using return_tags = tmpl::list<VariablesTags...>; 38 0 : using argument_tags = 39 : tmpl::list<domain::Tags::Element<Dim>, domain::Tags::Mesh<Dim>>; 40 : 41 : // p-refinement 42 0 : static void apply( 43 : const gsl::not_null<typename VariablesTags::type*>... vars, 44 : const Element<Dim>& /*element*/, const Mesh<Dim>& new_mesh, 45 : const std::pair<Mesh<Dim>, Element<Dim>>& old_mesh_and_element) { 46 : const auto& old_mesh = old_mesh_and_element.first; 47 : if (old_mesh == new_mesh) { 48 : return; // mesh was not refined, so no projection needed 49 : } 50 : const auto projection_matrices = 51 : Spectral::p_projection_matrices(old_mesh, new_mesh); 52 : const auto& old_extents = old_mesh.extents(); 53 : expand_pack( 54 : (*vars = apply_matrices(projection_matrices, *vars, old_extents))...); 55 : } 56 : 57 : // h-refinement 58 : template <typename... Tags> 59 0 : static void apply(const gsl::not_null<typename VariablesTags::type*>... vars, 60 : const Element<Dim>& element, const Mesh<Dim>& child_mesh, 61 : const tuples::TaggedTuple<Tags...>& parent_items) { 62 : const auto& element_id = element.id(); 63 : const auto& parent_id = get<domain::Tags::Element<Dim>>(parent_items).id(); 64 : const auto& parent_mesh = get<domain::Tags::Mesh<Dim>>(parent_items); 65 : std::array<Spectral::ChildSize, Dim> child_sizes{Spectral::ChildSize::Full}; 66 : for (size_t d = 0; d < Dim; ++d) { 67 : if (parent_id.segment_id(d) == element_id.segment_id(d)) { 68 : continue; 69 : } else if (parent_id.segment_id(d).id_of_child(Side::Lower) == 70 : element_id.segment_id(d)) { 71 : gsl::at(child_sizes, d) = Spectral::ChildSize::LowerHalf; 72 : } else if (parent_id.segment_id(d).id_of_child(Side::Upper) == 73 : element_id.segment_id(d)) { 74 : gsl::at(child_sizes, d) = Spectral::ChildSize::UpperHalf; 75 : } else { 76 : ERROR("Parent element " << parent_id << " is not a parent of element " 77 : << element_id << ". Please report this bug."); 78 : } 79 : } 80 : const auto prolongation_matrices = 81 : Spectral::projection_matrix_parent_to_child(parent_mesh, child_mesh, 82 : child_sizes); 83 : expand_pack((*vars = apply_matrices(prolongation_matrices, 84 : get<VariablesTags>(parent_items), 85 : parent_mesh.extents()))...); 86 : } 87 : 88 : // h-coarsening 89 : template <typename... Tags> 90 0 : static void apply( 91 : const gsl::not_null<typename VariablesTags::type*>... /*vars*/, 92 : const Element<Dim>& /*element*/, const Mesh<Dim>& /*new_mesh*/, 93 : const std::unordered_map<ElementId<Dim>, tuples::TaggedTuple<Tags...>>& 94 : /*children_items*/) { 95 : ERROR("h-coarsening not implemented yet"); 96 : } 97 : }; 98 : 99 : /// \cond 100 : template <size_t Dim, typename... VariableTags> 101 : struct ProjectVariables<Dim, tmpl::list<VariableTags...>> 102 : : public ProjectVariables<Dim, VariableTags...> {}; 103 : /// \endcond 104 : } // namespace amr::projectors