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
|