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 "ParallelAlgorithms/Amr/Protocols/Projector.hpp" 12 : #include "Utilities/ErrorHandling/Assert.hpp" 13 : #include "Utilities/Gsl.hpp" 14 : #include "Utilities/TMPL.hpp" 15 : #include "Utilities/TaggedTuple.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