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 <unordered_map>
9 : #include <utility>
10 :
11 : #include "DataStructures/TaggedTuple.hpp"
12 : #include "ParallelAlgorithms/Amr/Protocols/Projector.hpp"
13 : #include "Utilities/ErrorHandling/Assert.hpp"
14 : #include "Utilities/Gsl.hpp"
15 : #include "Utilities/TMPL.hpp"
16 :
17 : /// \cond
18 : template <size_t Dim>
19 : class Element;
20 : template <size_t Dim>
21 : class ElementId;
22 : template <size_t Dim>
23 : class Mesh;
24 : /// \endcond
25 :
26 1 : namespace amr::projectors {
27 :
28 : /// \brief For h-refinement copy the items from the parent/child, while for
29 : /// p-refinement leave the items unchanged
30 : ///
31 : /// There is a specialization for
32 : /// `CopyFromCreatorOrLeaveAsIs<tmpl::list<Tags...>>` that can be used if a
33 : /// `tmpl::list` is available.
34 : ///
35 : /// \details For each item corresponding to each tag:
36 : /// - When changing resolution (p-refinement), leave unchanged
37 : /// - When splitting, copy the value from the parent to the child
38 : /// - When joining, check that the children have the same value, and copy to
39 : /// the parent
40 : template <typename... Tags>
41 1 : struct CopyFromCreatorOrLeaveAsIs : tt::ConformsTo<amr::protocols::Projector> {
42 0 : using return_tags = tmpl::list<Tags...>;
43 0 : using argument_tags = tmpl::list<>;
44 :
45 : template <size_t Dim>
46 0 : static void apply(
47 : const gsl::not_null<typename Tags::type*>... /*items*/,
48 : const std::pair<Mesh<Dim>, Element<Dim>>& /*old_mesh_and_element*/) {
49 : // do nothing, i.e. leave the items unchanged
50 : }
51 :
52 : template <typename... ParentTags>
53 0 : static void apply(const gsl::not_null<typename Tags::type*>... items,
54 : const tuples::TaggedTuple<ParentTags...>& parent_items) {
55 : ::expand_pack((*items = tuples::get<Tags>(parent_items))...);
56 : }
57 :
58 : template <size_t Dim, typename... ChildrenTags>
59 0 : static void apply(const gsl::not_null<typename Tags::type*>... items,
60 : const std::unordered_map<
61 : ElementId<Dim>, tuples::TaggedTuple<ChildrenTags...>>&
62 : children_items) {
63 : const auto& first_child_items = children_items.begin();
64 : #ifdef SPECTRE_DEBUG
65 : for (auto it = std::next(first_child_items); it != children_items.end();
66 : ++it) {
67 : const bool children_agree =
68 : ((tuples::get<Tags>(first_child_items->second) ==
69 : tuples::get<Tags>(it->second)) and
70 : ...);
71 : ASSERT(children_agree, "Children do not agree on all items!");
72 : }
73 : #endif // #ifdef SPECTRE_DEBUG
74 : ::expand_pack((*items = tuples::get<Tags>(first_child_items->second))...);
75 : }
76 : };
77 :
78 : /// \cond
79 : template <typename... Tags>
80 : struct CopyFromCreatorOrLeaveAsIs<tmpl::list<Tags...>>
81 : : public CopyFromCreatorOrLeaveAsIs<Tags...> {};
82 : /// \endcond
83 : } // namespace amr::projectors
|