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 <optional>
11 : #include <string>
12 : #include <type_traits>
13 : #include <unordered_map>
14 : #include <unordered_set>
15 : #include <variant>
16 : #include <vector>
17 :
18 : #include "DataStructures/Tensor/Tensor.hpp"
19 : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
20 : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp"
21 : #include "Domain/CoordinateMaps/CoordinateMap.hpp"
22 : #include "Domain/CoordinateMaps/Distribution.hpp"
23 : #include "Domain/Creators/DomainCreator.hpp"
24 : #include "Domain/Creators/TimeDependentOptions/BinaryCompactObject.hpp"
25 : #include "Domain/Domain.hpp"
26 : #include "Domain/Structure/DirectionMap.hpp"
27 : #include "Options/Auto.hpp"
28 : #include "Options/Context.hpp"
29 : #include "Options/String.hpp"
30 : #include "Utilities/ErrorHandling/Assert.hpp"
31 : #include "Utilities/TMPL.hpp"
32 :
33 : /// \cond
34 : namespace domain {
35 : namespace CoordinateMaps {
36 : class Affine;
37 : class Equiangular;
38 : template <size_t VolumeDim>
39 : class Identity;
40 : template <typename Map1, typename Map2>
41 : class ProductOf2Maps;
42 : template <typename Map1, typename Map2, typename Map3>
43 : class ProductOf3Maps;
44 : template <size_t Dim>
45 : class Wedge;
46 : template <size_t VolumeDim>
47 : class DiscreteRotation;
48 : class Frustum;
49 : } // namespace CoordinateMaps
50 :
51 : template <typename SourceFrame, typename TargetFrame, typename... Maps>
52 : class CoordinateMap;
53 :
54 : namespace FunctionsOfTime {
55 : class FunctionOfTime;
56 : } // namespace FunctionsOfTime
57 : } // namespace domain
58 :
59 : namespace Frame {
60 : struct Grid;
61 : struct Distorted;
62 : struct Inertial;
63 : struct BlockLogical;
64 : } // namespace Frame
65 : /// \endcond
66 :
67 : namespace domain::creators {
68 1 : namespace bco {
69 : /*!
70 : * \brief Create a set of centers of objects for the binary domains.
71 : *
72 : * \details Will add the following centers to the set:
73 : *
74 : * - Center: The origin
75 : * - CenterA: Center of object A
76 : * - CenterB: Center of object B
77 : *
78 : * \return Object required by the DomainCreator%s
79 : */
80 : std::unordered_map<std::string, tnsr::I<double, 3, Frame::Grid>>
81 1 : create_grid_anchors(const std::array<double, 3>& center_a,
82 : const std::array<double, 3>& center_b);
83 : } // namespace bco
84 :
85 : /*!
86 : * \ingroup ComputationalDomainGroup
87 : *
88 : * \brief A general domain for two compact objects.
89 : *
90 : * \image html binary_compact_object_domain.png "A BHNS domain."
91 : *
92 : * Creates a 3D Domain that represents a binary compact object solution. The
93 : * Domain consists of 4 or 5 nested layers of blocks; these layers are, working
94 : * from the interior toward the exterior:
95 : *
96 : * - **Object A/B interior**: (optional) The block at the center of each
97 : * compact object, if not excised. If present, this block is a cube. If
98 : * excised, the hole left by its absence is spherical.
99 : * - **Object A/B shell**: The 6 blocks that resolve each individual compact
100 : * object. This layer has a spherical outer boundary - if the corresponding
101 : * interior block exists, then the layer is a cube-to-sphere transition; if
102 : * the interior block is excised, then the layer is a spherical shell.
103 : * - **Object A/B cube**: The 6 blocks that surround each object with a cube.
104 : * Around each compact object, this layer transitions from a sphere to a cube.
105 : * - **Envelope**: The 10 blocks that transition from the two inner cubes to a
106 : * sphere centered at the origin.
107 : * - **Outer shell**: The 10 blocks that form an outer shell centered at the
108 : * origin, consisting of 2 endcap Wedges on the +x and -x axes, and 8 half
109 : * Wedges along the yz plane. This layer is spherical, so a logarithmic map
110 : * can optionally be used in this layer. This allows the domain to extend to
111 : * large radial distances from the compact objects. This layer can be
112 : * h-refined radially, creating a layer of multiple concentric spherical
113 : * shells.
114 : *
115 : * \par Notes:
116 : * - Object A is located to the right of the origin (along the positive x-axis)
117 : * and Object B is located to the left of the origin in the Grid frame.
118 : * - This domain offers some grid anchors. See
119 : * `domain::creators::bco::create_grid_anchors` for which ones are offered.
120 : * - "Cutting plane" refers to the plane along which the domain divides into two
121 : * hemispheres. The cutting plane always intersects the x-axis at the origin.
122 : * - The x-coordinate locations of the two objects should be chosen such that
123 : * the center of mass is located at x=0 at the initial time (typically t=0).
124 : * - The cubes are first constructed at the origin. Then, they are translated
125 : * left/right by their Object's x-coordinate and offset depending on the cube
126 : * length.
127 : * - The CubeScale option describes how to scale the length of the cube
128 : * surrounding object A/B. It must be greater than or equal to 1.0 with 1.0
129 : * meaning the side length of the cube is the initial physical separation
130 : * between the two objects. If CubeScale is greater than 1.0, the centers of
131 : * the two objects will be offset relative to the centers of the cubes.
132 : * - Alternatively, one can replace the inner shell and cube blocks of each
133 : * object with a single cartesian cube. This is less efficient, but allows
134 : * testing of methods only coded on cartesian grids.
135 : *
136 : * \par Time dependence:
137 : * The following time-dependent maps are applied:
138 : *
139 : * - A piecewise `Expansion`, a `Rotation` and a piecewise `Translation` is
140 : * applied to all blocks from the Grid to the Inertial frame. However, if there
141 : * is a shape map in the block (defined below), then the expansion, rotation,
142 : * and translation maps go from the Distorted to the Inertial frame.
143 : * - If an object is excised, then the corresponding shell has a
144 : * `Shape` map. The shape map goes from the Grid to the Distorted frame.
145 : *
146 : * All time dependent maps are optional to specify. To include a map, specify
147 : * its options. Otherwise specify `None` for that map. You can also turn off
148 : * time dependent maps all together by specifying `None` for the
149 : * `TimeDependentMaps` option. See
150 : * `domain::creators::bco::TimeDependentMapOptions`. This class must pass a
151 : * template parameter of `false` to
152 : * `domain::creators::bco::TimeDependentMapOptions`.
153 : *
154 : * The `UseWorldtube` template parameter is set to false by default. When set to
155 : * true, some of the functions of time will be `IntegratedFunctionOfTime` used
156 : * to control the orbit of the worldtube.
157 : */
158 : template <bool UseWorldtube = false>
159 1 : class BinaryCompactObject : public DomainCreator<3> {
160 : private:
161 : // Time-independent maps
162 0 : using Affine = CoordinateMaps::Affine;
163 0 : using Affine3D = CoordinateMaps::ProductOf3Maps<Affine, Affine, Affine>;
164 0 : using Identity2D = CoordinateMaps::Identity<2>;
165 : // The Translation type is no longer needed, but it is kept here for backwards
166 : // compatibility with old domains.
167 0 : using Translation = CoordinateMaps::ProductOf2Maps<Affine, Identity2D>;
168 0 : using Equiangular = CoordinateMaps::Equiangular;
169 0 : using Equiangular3D =
170 : CoordinateMaps::ProductOf3Maps<Equiangular, Equiangular, Equiangular>;
171 :
172 : public:
173 0 : using maps_list = tmpl::flatten<tmpl::list<
174 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial, Affine3D>,
175 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
176 : Equiangular3D>,
177 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial, Affine3D,
178 : Translation>,
179 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
180 : CoordinateMaps::DiscreteRotation<3>, Affine3D>,
181 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
182 : Equiangular3D>,
183 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial, Equiangular3D,
184 : Translation>,
185 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
186 : CoordinateMaps::Frustum>,
187 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
188 : CoordinateMaps::Wedge<3>>,
189 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
190 : CoordinateMaps::Wedge<3>, Translation>,
191 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial, Affine3D,
192 : Affine3D>,
193 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial, Equiangular3D,
194 : Affine3D>,
195 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
196 : CoordinateMaps::Wedge<3>, Affine3D>,
197 : bco::TimeDependentMapOptions<false>::maps_list>>;
198 :
199 : /// Options for an excision region in the domain
200 1 : struct Excision {
201 0 : static constexpr Options::String help = {
202 : "Excise the interior of the object, leaving a spherical hole in its "
203 : "absence."};
204 : template <typename BoundaryConditionsBase>
205 0 : struct BoundaryCondition {
206 0 : static std::string name() { return "ExciseWithBoundaryCondition"; }
207 0 : using type = std::unique_ptr<BoundaryConditionsBase>;
208 0 : static constexpr Options::String help = {
209 : "The boundary condition to impose on the excision surface."};
210 : };
211 : template <typename Metavariables>
212 0 : using options = tmpl::list<BoundaryCondition<
213 : domain::BoundaryConditions::get_boundary_conditions_base<
214 : typename Metavariables::system>>>;
215 0 : Excision() = default;
216 : // NOLINTNEXTLINE(google-explicit-constructor)
217 0 : Excision(std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
218 : boundary_condition_in)
219 : : boundary_condition(std::move(boundary_condition_in)) {}
220 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
221 0 : boundary_condition;
222 : };
223 :
224 : /// Options for one of the two objects in the binary domain
225 1 : struct Object {
226 0 : static constexpr Options::String help = {
227 : "Options for an object in a binary domain."};
228 0 : struct InnerRadius {
229 0 : using type = double;
230 0 : static constexpr Options::String help = {
231 : "Inner coordinate radius of Layer 1."};
232 0 : static double lower_bound() { return 0.; }
233 : };
234 0 : struct OuterRadius {
235 0 : using type = double;
236 0 : static constexpr Options::String help = {
237 : "Outer coordinate radius of Layer 1"};
238 0 : static double lower_bound() { return 0.; }
239 : };
240 0 : struct XCoord {
241 0 : using type = double;
242 0 : static constexpr Options::String help = {"x-coordinate of center."};
243 : };
244 0 : struct Interior {
245 0 : using type = Options::Auto<Excision>;
246 0 : static constexpr Options::String help = {
247 : "Specify 'ExciseWithBoundaryCondition' and a boundary condition to "
248 : "excise Layer 0, leaving a spherical hole in its absence, or set to "
249 : "'Auto' to fill the interior."};
250 : };
251 0 : struct ExciseInterior {
252 0 : using type = bool;
253 0 : static constexpr Options::String help = {
254 : "Excise Layer 0, leaving a spherical hole in its absence."};
255 : };
256 0 : struct UseLogarithmicMap {
257 0 : using type = bool;
258 0 : static constexpr Options::String help = {
259 : "Use a logarithmically spaced radial grid in the part of Layer 1 "
260 : "enveloping the object (requires the interior is excised)"};
261 : };
262 : template <typename Metavariables>
263 0 : using options = tmpl::list<
264 : InnerRadius, OuterRadius, XCoord,
265 : tmpl::conditional_t<
266 : domain::BoundaryConditions::has_boundary_conditions_base_v<
267 : typename Metavariables::system>,
268 : Interior, ExciseInterior>,
269 : UseLogarithmicMap>;
270 0 : Object() = default;
271 0 : Object(double local_inner_radius, double local_outer_radius,
272 : double local_x_coord, std::optional<Excision> interior,
273 : bool local_use_logarithmic_map)
274 : : inner_radius(local_inner_radius),
275 : outer_radius(local_outer_radius),
276 : x_coord(local_x_coord),
277 : inner_boundary_condition(
278 : interior.has_value()
279 : ? std::make_optional(std::move(interior->boundary_condition))
280 : : std::nullopt),
281 : use_logarithmic_map(local_use_logarithmic_map) {}
282 0 : Object(double local_inner_radius, double local_outer_radius,
283 : double local_x_coord, bool local_excise_interior,
284 : bool local_use_logarithmic_map)
285 : : inner_radius(local_inner_radius),
286 : outer_radius(local_outer_radius),
287 : x_coord(local_x_coord),
288 : inner_boundary_condition(
289 : local_excise_interior
290 : ? std::optional<std::unique_ptr<
291 : domain::BoundaryConditions::BoundaryCondition>>{nullptr}
292 : : std::nullopt),
293 : use_logarithmic_map(local_use_logarithmic_map) {}
294 :
295 : /// Whether or not the object should be excised from the domain, leaving a
296 : /// spherical hole. When this is true, `inner_boundary_condition` is
297 : /// guaranteed to hold a value (though it might be a `nullptr` if we are not
298 : /// working with boundary conditions).
299 1 : bool is_excised() const;
300 :
301 0 : double inner_radius{};
302 0 : double outer_radius{};
303 0 : double x_coord{};
304 : std::optional<
305 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>
306 0 : inner_boundary_condition;
307 0 : bool use_logarithmic_map{};
308 : };
309 :
310 : // Simpler version of an object: a single cube centered on (xCoord,0,0)
311 0 : struct CartesianCubeAtXCoord {
312 0 : static constexpr Options::String help = {
313 : "Options to set a single cube at a location on the x-axis"};
314 0 : struct XCoord {
315 0 : static std::string name() { return "CartesianCubeAtXCoord"; }
316 0 : using type = double;
317 0 : static constexpr Options::String help = {"x-coordinate of center."};
318 : };
319 0 : using options = tmpl::list<XCoord>;
320 0 : CartesianCubeAtXCoord() = default;
321 : // NOLINTNEXTLINE(google-explicit-constructor)
322 0 : CartesianCubeAtXCoord(const double x_coord_in) : x_coord(x_coord_in) {}
323 0 : bool is_excised() const { return false; }
324 0 : double x_coord;
325 : };
326 :
327 0 : struct ObjectA {
328 0 : using type = std::variant<Object, CartesianCubeAtXCoord>;
329 0 : static constexpr Options::String help = {
330 : "Options for the object to the right of the origin (along the positive "
331 : "x-axis)."};
332 : };
333 :
334 0 : struct ObjectB {
335 0 : using type = std::variant<Object, CartesianCubeAtXCoord>;
336 0 : static constexpr Options::String help = {
337 : "Options for the object to the left of the origin (along the negative "
338 : "x-axis)."};
339 : };
340 :
341 0 : struct CenterOfMassOffset {
342 0 : using type = std::array<double, 2>;
343 0 : static constexpr Options::String help = {
344 : "Offset in the y and z axes applied to both object A and B in order to "
345 : "control the center of mass. This moves the location of the two objects"
346 : " in the grid frame but keeps the Envelope and OuterShell centered on "
347 : "the origin in the grid frame."};
348 : };
349 :
350 0 : struct Envelope {
351 0 : static constexpr Options::String help = {
352 : "Options for the sphere enveloping the two objects."};
353 : };
354 :
355 0 : struct EnvelopeRadius {
356 0 : using group = Envelope;
357 0 : static std::string name() { return "Radius"; }
358 0 : using type = double;
359 0 : static constexpr Options::String help = {
360 : "Radius of the sphere enveloping the two objects."};
361 : };
362 :
363 0 : struct OuterShell {
364 0 : static constexpr Options::String help = {
365 : "Options for the outer spherical shell."};
366 : };
367 :
368 0 : struct OuterRadius {
369 0 : using group = OuterShell;
370 0 : static std::string name() { return "Radius"; }
371 0 : using type = double;
372 0 : static constexpr Options::String help = {"Radius of the entire domain."};
373 : };
374 :
375 0 : struct RadialPartitioningOuterShell {
376 0 : static std::string name() { return "RadialPartitioning"; }
377 0 : using group = OuterShell;
378 0 : using type = std::vector<double>;
379 0 : static constexpr Options::String help = {
380 : "Radial coordinates of the boundaries splitting the outer spherical "
381 : "shells between the envelope radius and OuterRadius. They must be "
382 : "given in ascending order. This should be used if boundaries need to "
383 : "be set at specific radii. If the number but not the specific "
384 : "locations of the boundaries are important, use InitialRefinement "
385 : "instead."};
386 : };
387 :
388 0 : struct RadialDistributionOuterShell {
389 0 : static std::string name() { return "RadialDistribution"; }
390 0 : using group = OuterShell;
391 0 : using type =
392 : std::variant<domain::CoordinateMaps::Distribution,
393 : std::vector<domain::CoordinateMaps::Distribution>>;
394 0 : static constexpr Options::String help = {
395 : "Select the radial distribution of grid points in each outer spherical "
396 : "shell. There must be N+1 radial distributions specified for N radial "
397 : "partitions. You can also specify just a single radial distribution "
398 : "(not in a vector) which will use the same distribution for all "
399 : "partitions."};
400 : };
401 :
402 0 : struct OpeningAngle {
403 0 : using group = OuterShell;
404 0 : static std::string name() { return "OpeningAngle"; }
405 0 : using type = double;
406 0 : static constexpr Options::String help = {
407 : "The combined opening angle of the two half wedges of the outer shell"
408 : " in degrees. A value of 120.0 partitions the x-y and x-z slices of the"
409 : " outer shell into six Blocks of equal angular size."};
410 : };
411 :
412 0 : struct CubeScale {
413 0 : using type = double;
414 0 : static constexpr Options::String help = {
415 : "Specify the desired cube scale that must be greater than or equal to "
416 : "1.0. The initial separation is multiplied by this cube scale to "
417 : "produce larger cubes around each object which is desirable when "
418 : "closer to merger."};
419 0 : static double lower_bound() { return 1.0; }
420 : };
421 :
422 0 : struct InitialRefinement {
423 0 : using type =
424 : std::variant<size_t, std::array<size_t, 3>,
425 : std::vector<std::array<size_t, 3>>,
426 : std::unordered_map<std::string, std::array<size_t, 3>>>;
427 0 : static constexpr Options::String help = {
428 : "Initial refinement level in each block of the domain. See main help "
429 : "text for details."};
430 : };
431 :
432 0 : struct InitialGridPoints {
433 0 : using type =
434 : std::variant<size_t, std::array<size_t, 3>,
435 : std::vector<std::array<size_t, 3>>,
436 : std::unordered_map<std::string, std::array<size_t, 3>>>;
437 0 : static constexpr Options::String help = {
438 : "Initial number of grid points in the elements of each block of the "
439 : "domain. See main help text for details."};
440 : };
441 :
442 0 : struct UseEquiangularMap {
443 0 : using type = bool;
444 0 : static constexpr Options::String help = {
445 : "Distribute grid points equiangularly."};
446 0 : static bool suggested_value() { return true; }
447 : };
448 :
449 0 : struct RadialDistributionEnvelope {
450 0 : using group = Envelope;
451 0 : static std::string name() { return "RadialDistribution"; }
452 0 : using type = CoordinateMaps::Distribution;
453 0 : static constexpr Options::String help = {
454 : "The distribution of radial grid points in the envelope, the layer "
455 : "made of ten bulged Frustums."};
456 : };
457 :
458 : template <typename BoundaryConditionsBase>
459 0 : struct OuterBoundaryCondition {
460 0 : using group = OuterShell;
461 0 : static std::string name() { return "BoundaryCondition"; }
462 0 : static constexpr Options::String help =
463 : "Options for the outer boundary conditions.";
464 0 : using type = std::unique_ptr<BoundaryConditionsBase>;
465 : };
466 :
467 : // This is for optional time dependent maps
468 0 : struct TimeDependentMaps {
469 0 : using type = Options::Auto<bco::TimeDependentMapOptions<false>,
470 : Options::AutoLabel::None>;
471 0 : static constexpr Options::String help =
472 : bco::TimeDependentMapOptions<false>::help;
473 : };
474 :
475 : template <typename Metavariables>
476 0 : using options = tmpl::append<
477 : tmpl::list<ObjectA, ObjectB, CenterOfMassOffset, EnvelopeRadius,
478 : OuterRadius, CubeScale, InitialRefinement, InitialGridPoints,
479 : UseEquiangularMap, RadialDistributionEnvelope,
480 : RadialPartitioningOuterShell, RadialDistributionOuterShell,
481 : OpeningAngle, TimeDependentMaps>,
482 : tmpl::conditional_t<
483 : domain::BoundaryConditions::has_boundary_conditions_base_v<
484 : typename Metavariables::system>,
485 : tmpl::list<OuterBoundaryCondition<
486 : domain::BoundaryConditions::get_boundary_conditions_base<
487 : typename Metavariables::system>>>,
488 : tmpl::list<>>>;
489 :
490 0 : static constexpr Options::String help{
491 : "A general domain for two compact objects. Each object is represented by "
492 : "a cube along the x-axis. Object A is located on the right and Object B "
493 : "is located on the left. Their locations should be chosen such that "
494 : "their center of mass is located at the origin."
495 : "The interior of each object can have a spherical excision to "
496 : "represent a black hole."
497 : "\n"
498 : "The two objects are enveloped by a sphere centered at the origin, "
499 : "and by an outer shell that can transition to large outer radii."
500 : "\n"
501 : "Both the InitialRefinement and the InitialGridPoints can be one of "
502 : "the following:\n"
503 : " - A single number: Uniform refinement in all blocks and "
504 : "dimensions\n"
505 : " - Three numbers: Refinement in [polar, azimuthal, radial] direction "
506 : "in all blocks\n"
507 : " - A map from block names or groups to three numbers: Per-block "
508 : "refinement in [polar, azimuthal, radial] direction\n"
509 : " - A list, with [polar, azimuthal, radial] refinement for each block\n"
510 : "\n"
511 : "The domain can rotate around the "
512 : "z-axis and expand/compress radially. The two objects can each have a "
513 : "spherical distortion (shape map)."};
514 :
515 0 : BinaryCompactObject(
516 : typename ObjectA::type object_A, typename ObjectB::type object_B,
517 : std::array<double, 2> center_of_mass_offset, double envelope_radius,
518 : double outer_radius, double cube_scale,
519 : const typename InitialRefinement::type& initial_refinement,
520 : const typename InitialGridPoints::type& initial_number_of_grid_points,
521 : bool use_equiangular_map = true,
522 : CoordinateMaps::Distribution radial_distribution_envelope =
523 : CoordinateMaps::Distribution::Projective,
524 : const std::vector<double>& radial_partitioning_outer_shell = {},
525 : const typename RadialDistributionOuterShell::type&
526 : radial_distribution_outer_shell =
527 : CoordinateMaps::Distribution::Linear,
528 : double opening_angle_in_degrees = 90.0,
529 : std::optional<bco::TimeDependentMapOptions<false>>
530 : time_dependent_options = std::nullopt,
531 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
532 : outer_boundary_condition = nullptr,
533 : const Options::Context& context = {});
534 :
535 0 : BinaryCompactObject() = default;
536 0 : BinaryCompactObject(const BinaryCompactObject&) = delete;
537 0 : BinaryCompactObject(BinaryCompactObject&&) = default;
538 0 : BinaryCompactObject& operator=(const BinaryCompactObject&) = delete;
539 0 : BinaryCompactObject& operator=(BinaryCompactObject&&) = default;
540 0 : ~BinaryCompactObject() override = default;
541 :
542 0 : Domain<3> create_domain() const override;
543 :
544 : std::unordered_map<std::string, tnsr::I<double, 3, Frame::Grid>>
545 1 : grid_anchors() const override {
546 : return grid_anchors_;
547 : }
548 :
549 : std::vector<DirectionMap<
550 : 3, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
551 1 : external_boundary_conditions() const override;
552 :
553 1 : std::vector<std::array<size_t, 3>> initial_extents() const override {
554 : return initial_number_of_grid_points_;
555 : }
556 :
557 1 : std::vector<std::array<size_t, 3>> initial_refinement_levels()
558 : const override {
559 : return initial_refinement_;
560 : }
561 :
562 1 : std::vector<std::string> block_names() const override { return block_names_; }
563 :
564 : std::unordered_map<std::string, std::unordered_set<std::string>>
565 1 : block_groups() const override {
566 : return block_groups_;
567 : }
568 :
569 1 : auto functions_of_time(const std::unordered_map<std::string, double>&
570 : initial_expiration_times = {}) const
571 : -> std::unordered_map<
572 : std::string,
573 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
574 :
575 : private:
576 0 : typename ObjectA::type object_A_{};
577 0 : typename ObjectB::type object_B_{};
578 0 : std::array<double, 2> center_of_mass_offset_{};
579 0 : double envelope_radius_ = std::numeric_limits<double>::signaling_NaN();
580 0 : double outer_radius_ = std::numeric_limits<double>::signaling_NaN();
581 0 : std::vector<std::array<size_t, 3>> initial_refinement_;
582 0 : std::vector<std::array<size_t, 3>> initial_number_of_grid_points_;
583 0 : bool use_equiangular_map_ = true;
584 0 : CoordinateMaps::Distribution radial_distribution_envelope_ =
585 : CoordinateMaps::Distribution::Projective;
586 0 : std::vector<double> radial_partitioning_outer_shell_;
587 0 : std::vector<CoordinateMaps::Distribution> radial_distribution_outer_shell_ = {
588 : CoordinateMaps::Distribution::Linear};
589 0 : double translation_{};
590 0 : double length_inner_cube_{};
591 0 : double length_outer_cube_{};
592 0 : size_t number_of_outer_shells_{};
593 0 : size_t number_of_blocks_{};
594 0 : size_t first_outer_shell_block_{};
595 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
596 0 : outer_boundary_condition_;
597 0 : std::vector<std::string> block_names_;
598 : std::unordered_map<std::string, std::unordered_set<std::string>>
599 0 : block_groups_;
600 : std::unordered_map<std::string, tnsr::I<double, 3, Frame::Grid>>
601 0 : grid_anchors_;
602 0 : double offset_x_coord_a_{};
603 0 : double offset_x_coord_b_{};
604 :
605 : // Variables to handle std::variant on Object A and B
606 0 : double x_coord_a_{};
607 0 : double x_coord_b_{};
608 0 : bool is_excised_a_ = false;
609 0 : bool is_excised_b_ = false;
610 0 : bool use_single_block_a_ = false;
611 0 : bool use_single_block_b_ = false;
612 0 : std::optional<bco::TimeDependentMapOptions<false>> time_dependent_options_;
613 0 : double opening_angle_ = std::numeric_limits<double>::signaling_NaN();
614 : };
615 : } // namespace domain::creators
|