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 <limits>
9 : #include <memory>
10 : #include <vector>
11 :
12 : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
13 : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp"
14 : #include "Domain/Creators/DomainCreator.hpp"
15 : #include "Domain/Creators/TimeDependence/TimeDependence.hpp"
16 : #include "Domain/Domain.hpp"
17 : #include "Domain/Structure/DirectionMap.hpp"
18 : #include "Options/Context.hpp"
19 : #include "Options/String.hpp"
20 : #include "Utilities/TMPL.hpp"
21 :
22 : /// \cond
23 : namespace domain {
24 : namespace CoordinateMaps {
25 : class Affine;
26 : template <size_t VolumeDim>
27 : class DiscreteRotation;
28 : template <typename Map1, typename Map2>
29 : class ProductOf2Maps;
30 : } // namespace CoordinateMaps
31 :
32 : template <typename SourceFrame, typename TargetFrame, typename... Maps>
33 : class CoordinateMap;
34 : } // namespace domain
35 : /// \endcond
36 :
37 : namespace domain {
38 : namespace creators {
39 : /// Create a 2D Domain consisting of four rotated Blocks.
40 : /// - The lower left block has its logical \f$\xi\f$-axis aligned with
41 : /// the grid x-axis.
42 : ///
43 : /// - The lower right block is rotated a half-turn (180 degrees) relative to the
44 : /// lower left block.
45 : ///
46 : /// - The upper left block is rotated a quarter-turn counterclockwise
47 : /// (+90 degrees) relative to the lower left block.
48 : //
49 : /// - The upper right block is rotated a quarter-turn clockwise
50 : /// (-90 degrees) relative to the lower left block.
51 : ///
52 : /// This DomainCreator is useful for testing code that deals with
53 : /// unaligned blocks.
54 1 : class RotatedRectangles : public DomainCreator<2> {
55 : public:
56 0 : using maps_list =
57 : tmpl::list<domain::CoordinateMap<
58 : Frame::BlockLogical, Frame::Inertial,
59 : CoordinateMaps::ProductOf2Maps<CoordinateMaps::Affine,
60 : CoordinateMaps::Affine>>,
61 : domain::CoordinateMap<
62 : Frame::BlockLogical, Frame::Inertial,
63 : CoordinateMaps::DiscreteRotation<2>,
64 : CoordinateMaps::ProductOf2Maps<CoordinateMaps::Affine,
65 : CoordinateMaps::Affine>>>;
66 :
67 0 : struct LowerBound {
68 0 : using type = std::array<double, 2>;
69 0 : static constexpr Options::String help = {
70 : "Sequence of [x,y] for lower bounds in the target frame."};
71 : };
72 :
73 0 : struct Midpoint {
74 0 : using type = std::array<double, 2>;
75 0 : static constexpr Options::String help = {
76 : "Sequence of [x,y] for midpoints in the target frame."};
77 : };
78 :
79 0 : struct UpperBound {
80 0 : using type = std::array<double, 2>;
81 0 : static constexpr Options::String help = {
82 : "Sequence of [x,y] for upper bounds in the target frame."};
83 : };
84 :
85 0 : struct IsPeriodicIn {
86 0 : using type = std::array<bool, 2>;
87 0 : static constexpr Options::String help = {
88 : "Sequence for [x], true if periodic."};
89 : };
90 :
91 0 : struct TimeDependence {
92 0 : using type =
93 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<2>>;
94 0 : static constexpr Options::String help = {
95 : "The time dependence of the moving mesh domain."};
96 : };
97 :
98 0 : struct InitialRefinement {
99 0 : using type = std::array<size_t, 2>;
100 0 : static constexpr Options::String help = {
101 : "Initial refinement level in [x, y]."};
102 : };
103 :
104 0 : struct InitialGridPoints {
105 0 : using type = std::array<std::array<size_t, 2>, 2>;
106 0 : static constexpr Options::String help = {
107 : "Initial number of grid points in [[x], [y]]."};
108 : };
109 :
110 : template <typename BoundaryConditionsBase>
111 0 : struct BoundaryCondition {
112 0 : static std::string name() { return "BoundaryCondition"; }
113 0 : static constexpr Options::String help =
114 : "The boundary condition to impose on all sides.";
115 0 : using type = std::unique_ptr<BoundaryConditionsBase>;
116 : };
117 :
118 0 : using common_options = tmpl::list<LowerBound, Midpoint, UpperBound,
119 : InitialRefinement, InitialGridPoints>;
120 0 : using options_periodic = tmpl::list<IsPeriodicIn>;
121 :
122 : template <typename Metavariables>
123 0 : using options = tmpl::append<
124 : common_options,
125 : tmpl::conditional_t<
126 : domain::BoundaryConditions::has_boundary_conditions_base_v<
127 : typename Metavariables::system>,
128 : tmpl::list<BoundaryCondition<
129 : domain::BoundaryConditions::get_boundary_conditions_base<
130 : typename Metavariables::system>>>,
131 : options_periodic>,
132 : tmpl::list<TimeDependence>>;
133 :
134 0 : static constexpr Options::String help = {
135 : "A DomainCreator useful for testing purposes.\n"
136 : "RotatedRectangles uses four rotated Blocks to create the rectangle\n"
137 : "[LowerX,UpperX] x [LowerY,UpperY]. The outermost index to\n"
138 : "InitialGridPoints is the dimension index, and the innermost index is\n"
139 : "the block index along that dimension."};
140 :
141 0 : RotatedRectangles(
142 : typename LowerBound::type lower_xy, typename Midpoint::type midpoint_xy,
143 : typename UpperBound::type upper_xy,
144 : typename InitialRefinement::type initial_refinement_level_xy,
145 : typename InitialGridPoints::type initial_number_of_grid_points_in_xy,
146 : typename IsPeriodicIn::type is_periodic_in,
147 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<2>>
148 : time_dependence);
149 :
150 0 : RotatedRectangles(
151 : typename LowerBound::type lower_xy, typename Midpoint::type midpoint_xy,
152 : typename UpperBound::type upper_xy,
153 : typename InitialRefinement::type initial_refinement_level_xy,
154 : typename InitialGridPoints::type initial_number_of_grid_points_in_xy,
155 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
156 : boundary_condition,
157 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<2>>
158 : time_dependence,
159 : const Options::Context& context = {});
160 :
161 0 : RotatedRectangles() = default;
162 0 : RotatedRectangles(const RotatedRectangles&) = delete;
163 0 : RotatedRectangles(RotatedRectangles&&) = default;
164 0 : RotatedRectangles& operator=(const RotatedRectangles&) = delete;
165 0 : RotatedRectangles& operator=(RotatedRectangles&&) = default;
166 0 : ~RotatedRectangles() override = default;
167 :
168 0 : Domain<2> create_domain() const override;
169 :
170 : std::vector<DirectionMap<
171 : 2, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
172 1 : external_boundary_conditions() const override;
173 :
174 1 : auto functions_of_time(const std::unordered_map<std::string, double>&
175 : initial_expiration_times = {}) const
176 : -> std::unordered_map<
177 : std::string,
178 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
179 :
180 1 : std::vector<std::string> block_names() const override;
181 :
182 1 : std::vector<std::array<size_t, 2>> initial_extents() const override;
183 :
184 1 : std::vector<std::array<size_t, 2>> initial_refinement_levels() const override;
185 :
186 : private:
187 0 : typename LowerBound::type lower_xy_{
188 : {std::numeric_limits<double>::signaling_NaN()}};
189 0 : typename Midpoint::type midpoint_xy_{
190 : {std::numeric_limits<double>::signaling_NaN()}};
191 0 : typename UpperBound::type upper_xy_{
192 : {std::numeric_limits<double>::signaling_NaN()}};
193 0 : typename IsPeriodicIn::type is_periodic_in_{{false, false}};
194 0 : typename InitialRefinement::type initial_refinement_level_xy_{
195 : {std::numeric_limits<size_t>::max()}};
196 0 : typename InitialGridPoints::type initial_number_of_grid_points_in_xy_{
197 : {{{std::numeric_limits<size_t>::max()}}}};
198 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
199 0 : boundary_condition_;
200 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<2>>
201 0 : time_dependence_{nullptr};
202 : };
203 : } // namespace creators
204 : } // namespace domain
|