Line data Source code
1 1 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : /// \file
5 : /// Defines class Brick.
6 :
7 : #pragma once
8 :
9 : #include <array>
10 : #include <cstddef>
11 : #include <memory>
12 : #include <string>
13 : #include <vector>
14 :
15 : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
16 : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp"
17 : #include "Domain/Creators/DomainCreator.hpp" // IWYU pragma: keep
18 : #include "Domain/Creators/TimeDependence/TimeDependence.hpp"
19 : #include "Domain/Domain.hpp"
20 : #include "Domain/Structure/DirectionMap.hpp"
21 : #include "Options/Context.hpp"
22 : #include "Options/String.hpp"
23 : #include "Utilities/GetOutput.hpp"
24 : #include "Utilities/MakeArray.hpp"
25 : #include "Utilities/TMPL.hpp"
26 :
27 : /// \cond
28 : namespace domain {
29 : namespace CoordinateMaps {
30 : class Affine;
31 : template <typename Map1, typename Map2, typename Map3>
32 : class ProductOf3Maps;
33 : } // namespace CoordinateMaps
34 :
35 : template <typename SourceFrame, typename TargetFrame, typename... Maps>
36 : class CoordinateMap;
37 : } // namespace domain
38 : /// \endcond
39 :
40 : namespace domain {
41 : namespace creators {
42 :
43 : /// Create a 3D Domain consisting of a single Block.
44 1 : class Brick : public DomainCreator<3> {
45 : public:
46 0 : using maps_list = tmpl::list<
47 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
48 : CoordinateMaps::ProductOf3Maps<
49 : CoordinateMaps::Affine, CoordinateMaps::Affine,
50 : CoordinateMaps::Affine>>>;
51 :
52 0 : struct LowerBound {
53 0 : using type = std::array<double, 3>;
54 0 : static constexpr Options::String help = {
55 : "Sequence of [x,y,z] for lower bounds."};
56 : };
57 :
58 0 : struct UpperBound {
59 0 : using type = std::array<double, 3>;
60 0 : static constexpr Options::String help = {
61 : "Sequence of [x,y,z] for upper bounds."};
62 : };
63 0 : struct IsPeriodicIn {
64 0 : using type = std::array<bool, 3>;
65 0 : static constexpr Options::String help = {
66 : "Sequence for [x,y,z], true if periodic."};
67 : };
68 :
69 0 : struct InitialRefinement {
70 0 : using type = std::array<size_t, 3>;
71 0 : static constexpr Options::String help = {
72 : "Initial refinement level in [x,y,z]."};
73 : };
74 :
75 0 : struct InitialGridPoints {
76 0 : using type = std::array<size_t, 3>;
77 0 : static constexpr Options::String help = {
78 : "Initial number of grid points in [x,y,z]."};
79 : };
80 :
81 0 : struct TimeDependence {
82 0 : using type =
83 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>;
84 0 : static constexpr Options::String help = {
85 : "The time dependence of the moving mesh domain."};
86 : };
87 :
88 : template <typename BoundaryConditionsBase>
89 0 : struct LowerUpperBoundaryCondition {
90 0 : static constexpr Options::String help =
91 : "Lower and upper Boundary Conditions";
92 0 : struct LowerBC {
93 0 : using type = std::unique_ptr<BoundaryConditionsBase>;
94 0 : static constexpr Options::String help = "Lower Boundary Condition";
95 0 : static std::string name() { return "LowerBoundaryCondition"; };
96 : };
97 0 : struct UpperBC {
98 0 : using type = std::unique_ptr<BoundaryConditionsBase>;
99 0 : static constexpr Options::String help = "Upper Boundary Condition";
100 0 : static std::string name() { return "UpperBoundaryCondition"; };
101 : };
102 0 : LowerUpperBoundaryCondition(typename LowerBC::type lower_bc,
103 : typename UpperBC::type upper_bc)
104 : : lower(std::move(lower_bc)), upper(std::move(upper_bc)){};
105 0 : LowerUpperBoundaryCondition() = default;
106 0 : std::unique_ptr<BoundaryConditionsBase> lower;
107 0 : std::unique_ptr<BoundaryConditionsBase> upper;
108 0 : using options = tmpl::list<LowerBC, UpperBC>;
109 : };
110 :
111 : template <typename BoundaryConditionsBase, size_t Dim>
112 0 : struct BoundaryCondition {
113 0 : static std::string name() {
114 : return "BoundaryConditionIn" +
115 : std::string{Dim == 0 ? 'X' : (Dim == 1 ? 'Y' : 'Z')};
116 : };
117 0 : static constexpr Options::String help = {
118 : "The boundary condition to be imposed for boundaries at "
119 : "the given direction. Either specify one B.C. to be imposed for both "
120 : "lower and upper boundary or a pair of B.C. for lower and upper "
121 : "boundary respectively."};
122 0 : using type =
123 : std::variant<std::unique_ptr<BoundaryConditionsBase>,
124 : LowerUpperBoundaryCondition<BoundaryConditionsBase>>;
125 : };
126 :
127 0 : using common_options =
128 : tmpl::list<LowerBound, UpperBound, InitialRefinement, InitialGridPoints>;
129 0 : using options_periodic = tmpl::list<IsPeriodicIn>;
130 :
131 : template <typename Metavariables>
132 0 : using options = tmpl::append<
133 : common_options,
134 : tmpl::conditional_t<
135 : domain::BoundaryConditions::has_boundary_conditions_base_v<
136 : typename Metavariables::system>,
137 : tmpl::list<
138 : BoundaryCondition<
139 : domain::BoundaryConditions::get_boundary_conditions_base<
140 : typename Metavariables::system>,
141 : 0>,
142 : BoundaryCondition<
143 : domain::BoundaryConditions::get_boundary_conditions_base<
144 : typename Metavariables::system>,
145 : 1>,
146 : BoundaryCondition<
147 : domain::BoundaryConditions::get_boundary_conditions_base<
148 : typename Metavariables::system>,
149 : 2>>,
150 : options_periodic>,
151 : tmpl::list<TimeDependence>>;
152 :
153 0 : static constexpr Options::String help{"Creates a 3D brick."};
154 :
155 0 : Brick(std::array<double, 3> lower_xyz, std::array<double, 3> upper_xyz,
156 : std::array<size_t, 3> initial_refinement_level_xyz,
157 : std::array<size_t, 3> initial_number_of_grid_points_in_xyz,
158 : std::array<bool, 3> is_periodic_in_xyz,
159 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
160 : time_dependence = nullptr);
161 :
162 0 : Brick(std::array<double, 3> lower_xyz, std::array<double, 3> upper_xyz,
163 : std::array<size_t, 3> initial_refinement_level_xyz,
164 : std::array<size_t, 3> initial_number_of_grid_points_in_xyz,
165 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
166 : boundary_condition_in_lower_x,
167 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
168 : boundary_condition_in_upper_x,
169 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
170 : boundary_condition_in_lower_y,
171 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
172 : boundary_condition_in_upper_y,
173 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
174 : boundary_condition_in_lower_z,
175 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
176 : boundary_condition_in_upper_z,
177 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
178 : time_dependence = nullptr,
179 : const Options::Context& context = {});
180 :
181 : template <typename BoundaryConditionsBase>
182 0 : Brick(std::array<double, 3> lower_xyz, std::array<double, 3> upper_xyz,
183 : std::array<size_t, 3> initial_refinement_level_xyz,
184 : std::array<size_t, 3> initial_number_of_grid_points_in_xyz,
185 : std::variant<std::unique_ptr<BoundaryConditionsBase>,
186 : LowerUpperBoundaryCondition<BoundaryConditionsBase>>
187 : boundary_conditions_in_x,
188 : std::variant<std::unique_ptr<BoundaryConditionsBase>,
189 : LowerUpperBoundaryCondition<BoundaryConditionsBase>>
190 : boundary_conditions_in_y,
191 : std::variant<std::unique_ptr<BoundaryConditionsBase>,
192 : LowerUpperBoundaryCondition<BoundaryConditionsBase>>
193 : boundary_conditions_in_z,
194 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
195 : time_dependence = nullptr,
196 : const Options::Context& context = {});
197 :
198 0 : Brick() = default;
199 0 : Brick(const Brick&) = delete;
200 0 : Brick(Brick&&) = default;
201 0 : Brick& operator=(const Brick&) = delete;
202 0 : Brick& operator=(Brick&&) = default;
203 0 : ~Brick() override = default;
204 :
205 0 : Domain<3> create_domain() const override;
206 :
207 : std::vector<DirectionMap<
208 : 3, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
209 1 : external_boundary_conditions() const override;
210 :
211 1 : std::vector<std::array<size_t, 3>> initial_extents() const override;
212 :
213 1 : std::vector<std::array<size_t, 3>> initial_refinement_levels() const override;
214 :
215 1 : auto functions_of_time(const std::unordered_map<std::string, double>&
216 : initial_expiration_times = {}) const
217 : -> std::unordered_map<
218 : std::string,
219 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
220 :
221 1 : std::vector<std::string> block_names() const override { return block_names_; }
222 :
223 : private:
224 0 : typename LowerBound::type lower_xyz_{};
225 0 : typename UpperBound::type upper_xyz_{};
226 0 : typename IsPeriodicIn::type is_periodic_in_xyz_{};
227 0 : typename InitialRefinement::type initial_refinement_level_xyz_{};
228 0 : typename InitialGridPoints::type initial_number_of_grid_points_in_xyz_{};
229 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
230 0 : time_dependence_;
231 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
232 0 : boundary_condition_in_lower_x_;
233 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
234 0 : boundary_condition_in_upper_x_;
235 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
236 0 : boundary_condition_in_lower_y_;
237 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
238 0 : boundary_condition_in_upper_y_;
239 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
240 0 : boundary_condition_in_lower_z_;
241 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
242 0 : boundary_condition_in_upper_z_;
243 0 : inline static const std::vector<std::string> block_names_{"Brick"};
244 : };
245 :
246 : template <typename BoundaryConditionsBase>
247 : Brick::Brick(
248 : std::array<double, 3> lower_xyz, std::array<double, 3> upper_xyz,
249 : std::array<size_t, 3> initial_refinement_level_xyz,
250 : std::array<size_t, 3> initial_number_of_grid_points_in_xyz,
251 : std::variant<std::unique_ptr<BoundaryConditionsBase>,
252 : LowerUpperBoundaryCondition<BoundaryConditionsBase>>
253 : boundary_conditions_in_x,
254 : std::variant<std::unique_ptr<BoundaryConditionsBase>,
255 : LowerUpperBoundaryCondition<BoundaryConditionsBase>>
256 : boundary_conditions_in_y,
257 : std::variant<std::unique_ptr<BoundaryConditionsBase>,
258 : LowerUpperBoundaryCondition<BoundaryConditionsBase>>
259 : boundary_conditions_in_z,
260 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
261 : time_dependence,
262 : const Options::Context& context)
263 : : Brick(lower_xyz, upper_xyz, initial_refinement_level_xyz,
264 : initial_number_of_grid_points_in_xyz,
265 : std::holds_alternative<std::unique_ptr<BoundaryConditionsBase>>(
266 : boundary_conditions_in_x)
267 : ? std::get<std::unique_ptr<BoundaryConditionsBase>>(
268 : boundary_conditions_in_x)
269 : ->get_clone()
270 : : std::move(
271 : std::get<
272 : LowerUpperBoundaryCondition<BoundaryConditionsBase>>(
273 : boundary_conditions_in_x)
274 : .lower),
275 :
276 : std::holds_alternative<std::unique_ptr<BoundaryConditionsBase>>(
277 : boundary_conditions_in_x)
278 : ? std::get<std::unique_ptr<BoundaryConditionsBase>>(
279 : boundary_conditions_in_x)
280 : ->get_clone()
281 : : std::move(
282 : std::get<
283 : LowerUpperBoundaryCondition<BoundaryConditionsBase>>(
284 : boundary_conditions_in_x)
285 : .upper),
286 : std::holds_alternative<std::unique_ptr<BoundaryConditionsBase>>(
287 : boundary_conditions_in_y)
288 : ? std::get<std::unique_ptr<BoundaryConditionsBase>>(
289 : boundary_conditions_in_y)
290 : ->get_clone()
291 : : std::move(
292 : std::get<
293 : LowerUpperBoundaryCondition<BoundaryConditionsBase>>(
294 : boundary_conditions_in_y)
295 : .lower),
296 : std::holds_alternative<std::unique_ptr<BoundaryConditionsBase>>(
297 : boundary_conditions_in_y)
298 : ? std::get<std::unique_ptr<BoundaryConditionsBase>>(
299 : boundary_conditions_in_y)
300 : ->get_clone()
301 : : std::move(
302 : std::get<
303 : LowerUpperBoundaryCondition<BoundaryConditionsBase>>(
304 : boundary_conditions_in_y)
305 : .upper),
306 : std::holds_alternative<std::unique_ptr<BoundaryConditionsBase>>(
307 : boundary_conditions_in_z)
308 : ? std::get<std::unique_ptr<BoundaryConditionsBase>>(
309 : boundary_conditions_in_z)
310 : ->get_clone()
311 : : std::move(
312 : std::get<
313 : LowerUpperBoundaryCondition<BoundaryConditionsBase>>(
314 : boundary_conditions_in_z)
315 : .lower),
316 : std::holds_alternative<std::unique_ptr<BoundaryConditionsBase>>(
317 : boundary_conditions_in_z)
318 : ? std::get<std::unique_ptr<BoundaryConditionsBase>>(
319 : boundary_conditions_in_z)
320 : ->get_clone()
321 : : std::move(
322 : std::get<
323 : LowerUpperBoundaryCondition<BoundaryConditionsBase>>(
324 : boundary_conditions_in_z)
325 : .upper),
326 : std::move(time_dependence), context) {}
327 : } // namespace creators
328 : } // namespace domain
|