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
|