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, typename Map3>
29 : class ProductOf3Maps;
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 3D Domain consisting of eight rotated Blocks.
40 : ///
41 : /// \image html eightcubes_rotated_exploded.png
42 : ///
43 : /// The orientations of the blocks are described in two different ways:
44 : ///
45 : /// - 1 - As orientations of blocks relative to the physical cartesian axes.
46 : ///
47 : /// - 2 - As rotations relative to the physical cartesian axes written using
48 : /// Rubik's cube rotation notation, for the sake of shorter variable names.
49 : ///
50 : /// For reference, this is the notation used:
51 : ///
52 : /// - U - A clockwise 90 degree rotation about the +z axis (The "up" side)
53 : ///
54 : /// - R - A clockwise 90 degree rotation about the +x axis (The "right" side)
55 : ///
56 : /// - F - A clockwise 90 degree rotation about the -y axis (The "front" side)
57 : ///
58 : /// For reference, D, L, and B ("down", "left", and "back") are the inverse
59 : /// rotation to the aforementioned ones, respectively.
60 : /// Note: Whereas Rubik's cube rotations rotate a layer of the 3x3 puzzle
61 : /// cube, we are adopting the notation to apply to rotations of the
62 : /// cube itself.
63 : ///
64 : /// - The -x, -y, -z block has the aligned orientation, that is,
65 : /// xi is aligned with x, eta is aligned with y, and zeta with z.
66 : /// This has block ID 0.
67 : ///
68 : /// - The +x, -y, -z block has the orientation (zeta, eta, -xi).
69 : /// It corresponds to the orientation obtained by the rotation F.
70 : /// This has block ID 1.
71 : ///
72 : /// - The -x, +y, -z block has the orientation (xi, zeta, -eta).
73 : /// It corresponds to the orientation obtained by the rotation R.
74 : /// This has block ID 2.
75 : ///
76 : /// - The +x, +y, -z block has the orientation (zeta, -xi, -eta).
77 : /// It corresponds to the orientation obtained by the rotation F
78 : /// followed by the rotation R.
79 : /// This has block ID 3.
80 : ///
81 : /// - The -x, -y, +z block has the orientation (eta, -xi, zeta).
82 : /// It corresponds to the orientation obtained by the rotation U.
83 : /// This has block ID 4.
84 : ///
85 : /// - The +x, -y, +z block has the orientation (eta, -zeta, -xi).
86 : /// It corresponds to the orientation obtained by the rotation F
87 : /// followed by the rotation U.
88 : /// This has block ID 5.
89 : ///
90 : /// - The -x, +y, +z block has the orientation (zeta, -xi, -eta).
91 : /// It corresponds to the orientation obtained by the rotation R
92 : /// followed by the rotation U (equivalently, F followed by R).
93 : /// This has block ID 6.
94 : ///
95 : /// - The +x, +y, +z block also has the aligned orientation
96 : /// (xi, eta, zeta), relative to the edifice. It is not aligned
97 : /// relative to its neighbors.
98 : /// This has block ID 7.
99 : ///
100 : /// This DomainCreator is useful for testing code that deals with
101 : /// unaligned blocks.
102 1 : class RotatedBricks : public DomainCreator<3> {
103 : public:
104 0 : using maps_list = tmpl::list<
105 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
106 : CoordinateMaps::ProductOf3Maps<
107 : CoordinateMaps::Affine, CoordinateMaps::Affine,
108 : CoordinateMaps::Affine>>,
109 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
110 : CoordinateMaps::DiscreteRotation<3>,
111 : CoordinateMaps::ProductOf3Maps<
112 : CoordinateMaps::Affine, CoordinateMaps::Affine,
113 : CoordinateMaps::Affine>>>;
114 :
115 0 : struct LowerBound {
116 0 : using type = std::array<double, 3>;
117 0 : static constexpr Options::String help = {
118 : "Sequence [x,y,z] for lower bound in the target frame."};
119 : };
120 :
121 0 : struct Midpoint {
122 0 : using type = std::array<double, 3>;
123 0 : static constexpr Options::String help = {
124 : "Sequence [x,y,z] for midpoint in the target frame."};
125 : };
126 :
127 0 : struct UpperBound {
128 0 : using type = std::array<double, 3>;
129 0 : static constexpr Options::String help = {
130 : "Sequence [x,y,z] for upper bound in the target frame."};
131 : };
132 :
133 0 : struct IsPeriodicIn {
134 0 : using type = std::array<bool, 3>;
135 0 : static constexpr Options::String help = {
136 : "Sequence in [x,y,z], true if periodic."};
137 : };
138 :
139 0 : struct TimeDependence {
140 0 : using type =
141 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>;
142 0 : static constexpr Options::String help = {
143 : "The time dependence of the moving mesh domain."};
144 : };
145 :
146 0 : struct InitialRefinement {
147 0 : using type = std::array<size_t, 3>;
148 0 : static constexpr Options::String help = {
149 : "Initial refinement level in [x, y, z]."};
150 : };
151 :
152 0 : struct InitialGridPoints {
153 0 : using type = std::array<std::array<size_t, 2>, 3>;
154 0 : static constexpr Options::String help = {
155 : "Initial number of grid points in [[x], [y], [z]]."};
156 : };
157 :
158 : template <typename BoundaryConditionsBase>
159 0 : struct BoundaryCondition {
160 0 : static std::string name() { return "BoundaryCondition"; }
161 0 : static constexpr Options::String help =
162 : "The boundary condition to impose on all sides.";
163 0 : using type = std::unique_ptr<BoundaryConditionsBase>;
164 : };
165 :
166 0 : using common_options = tmpl::list<LowerBound, Midpoint, UpperBound,
167 : InitialRefinement, InitialGridPoints>;
168 0 : using options_periodic = tmpl::list<IsPeriodicIn>;
169 :
170 : template <typename Metavariables>
171 0 : using options = tmpl::append<
172 : common_options,
173 : tmpl::conditional_t<
174 : domain::BoundaryConditions::has_boundary_conditions_base_v<
175 : typename Metavariables::system>,
176 : tmpl::list<BoundaryCondition<
177 : domain::BoundaryConditions::get_boundary_conditions_base<
178 : typename Metavariables::system>>>,
179 : options_periodic>,
180 : tmpl::list<TimeDependence>>;
181 :
182 0 : static constexpr Options::String help = {
183 : "A DomainCreator useful for testing purposes.\n"
184 : "RotatedBricks uses eight rotated Blocks to create the rectangular\n"
185 : "prism [LowerX,UpperX] x [LowerY,UpperY] x [LowerZ,UpperZ]. The\n"
186 : "outermost index to InitialGridPoints is the dimension index, and\n"
187 : "the innermost index is the block index along that dimension."};
188 :
189 0 : RotatedBricks(
190 : typename LowerBound::type lower_xyz, typename Midpoint::type midpoint_xyz,
191 : typename UpperBound::type upper_xyz,
192 : typename InitialRefinement::type initial_refinement_level_xyz,
193 : typename InitialGridPoints::type initial_number_of_grid_points_in_xyz,
194 : typename IsPeriodicIn::type is_periodic_in,
195 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
196 : time_dependence);
197 :
198 0 : RotatedBricks(
199 : typename LowerBound::type lower_xyz, typename Midpoint::type midpoint_xyz,
200 : typename UpperBound::type upper_xyz,
201 : typename InitialRefinement::type initial_refinement_level_xyz,
202 : typename InitialGridPoints::type initial_number_of_grid_points_in_xyz,
203 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
204 : boundary_condition,
205 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
206 : time_dependence,
207 : const Options::Context& context = {});
208 :
209 0 : RotatedBricks() = default;
210 0 : RotatedBricks(const RotatedBricks&) = delete;
211 0 : RotatedBricks(RotatedBricks&&) = default;
212 0 : RotatedBricks& operator=(const RotatedBricks&) = delete;
213 0 : RotatedBricks& operator=(RotatedBricks&&) = default;
214 0 : ~RotatedBricks() override = default;
215 :
216 0 : Domain<3> create_domain() const override;
217 :
218 : std::vector<DirectionMap<
219 : 3, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
220 1 : external_boundary_conditions() const override;
221 :
222 1 : auto functions_of_time(const std::unordered_map<std::string, double>&
223 : initial_expiration_times = {}) const
224 : -> std::unordered_map<
225 : std::string,
226 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
227 :
228 1 : std::vector<std::string> block_names() const override;
229 :
230 1 : std::vector<std::array<size_t, 3>> initial_extents() const override;
231 :
232 1 : std::vector<std::array<size_t, 3>> initial_refinement_levels() const override;
233 :
234 : private:
235 0 : typename LowerBound::type lower_xyz_{
236 : {std::numeric_limits<double>::signaling_NaN()}};
237 0 : typename Midpoint::type midpoint_xyz_{
238 : {std::numeric_limits<double>::signaling_NaN()}};
239 0 : typename UpperBound::type upper_xyz_{
240 : {std::numeric_limits<double>::signaling_NaN()}};
241 0 : typename IsPeriodicIn::type is_periodic_in_{{false, false, false}};
242 0 : typename InitialRefinement::type initial_refinement_level_xyz_{
243 : {std::numeric_limits<size_t>::max()}};
244 0 : typename InitialGridPoints::type initial_number_of_grid_points_in_xyz_{
245 : {{{std::numeric_limits<size_t>::max()}}}};
246 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
247 0 : boundary_condition_;
248 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
249 0 : time_dependence_{nullptr};
250 : };
251 : } // namespace creators
252 : } // namespace domain
|