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 <pup.h>
9 :
10 : #include "Domain/Amr/Flag.hpp"
11 : #include "Domain/Structure/Direction.hpp"
12 : #include "Domain/Structure/Element.hpp"
13 : #include "Domain/Structure/Side.hpp"
14 : #include "Domain/Tags.hpp"
15 : #include "Options/String.hpp"
16 : #include "ParallelAlgorithms/Amr/Criteria/Criterion.hpp"
17 : #include "ParallelAlgorithms/Amr/Criteria/Type.hpp"
18 : #include "Utilities/MakeArray.hpp"
19 : #include "Utilities/TMPL.hpp"
20 :
21 : namespace amr::Criteria {
22 : /*!
23 : * \brief Split boundary elements in the direction of the boundary
24 : */
25 : template <size_t Dim, size_t DimToRefine>
26 1 : class RefineAtBoundary : public amr::Criterion {
27 : static_assert(DimToRefine < Dim);
28 :
29 : public:
30 0 : using options = tmpl::list<>;
31 :
32 0 : static constexpr Options::String help = {
33 : "Split boundary elements in the direction of the boundary."};
34 :
35 0 : RefineAtBoundary() = default;
36 :
37 : /// \cond
38 : explicit RefineAtBoundary(CkMigrateMessage* msg) : amr::Criterion(msg) {}
39 : using PUP::able::register_constructor;
40 : WRAPPED_PUPable_decl_template(RefineAtBoundary); // NOLINT
41 : /// \endcond
42 :
43 0 : amr::Criteria::Type type() override { return amr::Criteria::Type::h; }
44 :
45 0 : static std::string name() {
46 : if constexpr (DimToRefine == 0) {
47 : return "RefineAtBoundaryX";
48 : } else if constexpr (DimToRefine == 1) {
49 : return "RefineAtBoundaryY";
50 : } else {
51 : return "RefineAtBoundaryZ";
52 : }
53 : }
54 :
55 0 : std::string observation_name() override { return name(); }
56 :
57 0 : using compute_tags_for_observation_box = tmpl::list<>;
58 0 : using argument_tags = tmpl::list<domain::Tags::Element<Dim>>;
59 :
60 : template <typename Metavariables>
61 0 : std::array<amr::Flag, Dim> operator()(
62 : const Element<Dim>& element,
63 : Parallel::GlobalCache<Metavariables>& /*cache*/,
64 : const ElementId<Dim>& /*element_id*/) const {
65 : const auto& external_boundaries = element.external_boundaries();
66 : auto result = make_array<Dim>(amr::Flag::DoNothing);
67 : if (external_boundaries.count(Direction<Dim>{DimToRefine, Side::Lower}) ==
68 : 1 or
69 : external_boundaries.count(Direction<Dim>{DimToRefine, Side::Upper}) ==
70 : 1) {
71 : get<DimToRefine>(result) = amr::Flag::Split;
72 : }
73 : return result;
74 : }
75 : };
76 :
77 : /// \cond
78 : template <size_t Dim, size_t DimToRefine>
79 : PUP::able::PUP_ID RefineAtBoundary<Dim, DimToRefine>::my_PUP_ID = 0; // NOLINT
80 : /// \endcond
81 :
82 : } // namespace amr::Criteria
|