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 <iterator> 8 : #include <memory> 9 : #include <unordered_map> 10 : #include <utility> 11 : 12 : #include "DataStructures/TaggedTuple.hpp" 13 : #include "Domain/Structure/Element.hpp" 14 : #include "Domain/Structure/ElementId.hpp" 15 : #include "NumericalAlgorithms/LinearOperators/Filters/Filter.hpp" 16 : #include "NumericalAlgorithms/LinearOperators/Filters/Tag.hpp" 17 : #include "NumericalAlgorithms/Spectral/Mesh.hpp" 18 : #include "ParallelAlgorithms/Amr/Protocols/Projector.hpp" 19 : #include "Utilities/ErrorHandling/Error.hpp" 20 : #include "Utilities/Gsl.hpp" 21 : #include "Utilities/TMPL.hpp" 22 : 23 : namespace evolution::dg::Initialization { 24 : 25 : /// \brief AMR projector for `Filters::Tags::SpectralFilter<Dim, TagList>`. 26 : /// 27 : /// \details 28 : /// - For p-refinement: leaves the filter unchanged. 29 : /// - For h-refinement (splitting): clones the parent's filter for the child. 30 : /// - For h-coarsening (joining): clones the first child's filter for the 31 : /// parent (all siblings share the same block and mesh basis/quadrature, so 32 : /// they carry identical filters). 33 : template <size_t Dim, typename TagList> 34 1 : struct ProjectSpectralFilters : tt::ConformsTo<amr::protocols::Projector> { 35 0 : using return_tags = tmpl::list<Filters::Tags::SpectralFilter<Dim, TagList>>; 36 0 : using argument_tags = tmpl::list<>; 37 : 38 : // p-refinement: leave the filter unchanged. 39 0 : static void apply( 40 : const gsl::not_null< 41 : std::unique_ptr<Filters::Filter<Dim, TagList>>*> /*filter*/, 42 : const std::pair<Mesh<Dim>, Element<Dim>>& /*old_mesh_and_element*/) {} 43 : 44 : // Splitting: clone the parent's filter for the new child. 45 : template <typename... ParentTags> 46 0 : static void apply( 47 : const gsl::not_null<std::unique_ptr<Filters::Filter<Dim, TagList>>*> 48 : filter, 49 : const tuples::TaggedTuple<ParentTags...>& parent_items) { 50 : *filter = 51 : tuples::get<Filters::Tags::SpectralFilter<Dim, TagList>>(parent_items) 52 : ->get_clone(); 53 : } 54 : 55 : // Joining: clone the first child's filter for the parent. 56 : template <typename... ChildrenTags> 57 0 : static void apply( 58 : const gsl::not_null<std::unique_ptr<Filters::Filter<Dim, TagList>>*> 59 : filter, 60 : const std::unordered_map<ElementId<Dim>, 61 : tuples::TaggedTuple<ChildrenTags...>>& 62 : children_items) { 63 : const auto first_child_items = children_items.begin(); 64 : const auto& first_filter = 65 : tuples::get<Filters::Tags::SpectralFilter<Dim, TagList>>( 66 : first_child_items->second); 67 : for (auto it = std::next(first_child_items); it != children_items.end(); 68 : ++it) { 69 : const auto& other_filter = 70 : tuples::get<Filters::Tags::SpectralFilter<Dim, TagList>>(it->second); 71 : if (not first_filter->is_equal(*other_filter)) { 72 : ERROR("Children do not agree on all items!"); 73 : } 74 : } 75 : *filter = first_filter->get_clone(); 76 : } 77 : }; 78 : 79 : } // namespace evolution::dg::Initialization