BinaryCompactObject.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <array>
7 #include <cstddef>
8 #include <memory>
9 #include <string>
10 #include <unordered_map>
11 #include <vector>
12 
15 #include "Domain/Creators/TimeDependence/TimeDependence.hpp"
16 #include "Domain/Domain.hpp"
17 #include "ErrorHandling/Assert.hpp"
18 #include "Options/Options.hpp"
19 #include "Utilities/TMPL.hpp"
20 
21 /// \cond
22 namespace domain {
23 namespace CoordinateMaps {
24 class Affine;
25 class Equiangular;
26 template <size_t VolumeDim>
27 class Identity;
28 template <typename Map1, typename Map2>
29 class ProductOf2Maps;
30 template <typename Map1, typename Map2, typename Map3>
31 class ProductOf3Maps;
32 class Wedge3D;
33 template <size_t VolumeDim>
34 class DiscreteRotation;
35 class Frustum;
36 } // namespace CoordinateMaps
37 
38 template <typename SourceFrame, typename TargetFrame, typename... Maps>
39 class CoordinateMap;
40 
41 namespace FunctionsOfTime {
42 class FunctionOfTime;
43 } // namespace FunctionsOfTime
44 } // namespace domain
45 
46 namespace Frame {
47 struct Inertial;
48 struct Logical;
49 } // namespace Frame
50 /// \endcond
51 
52 namespace domain {
53 namespace creators {
54 
55 /*!
56  * \ingroup ComputationalDomainGroup
57  *
58  * \brief A general domain for two compact objects.
59  *
60  * \image html binary_compact_object_domain.png "A BHNS domain."
61  *
62  * Creates a 3D Domain that represents a binary compact object solution. The
63  * Domain consists of 4, 5, or 6 nested layers of blocks; these layers are,
64  * working from the interior toward the exterior:
65  * - 0: (optionally) The block at the center of each compact object, if not
66  * excised. If present, this block is a cube. If excised, the hole left
67  * by its absence is spherical.
68  * - 1: The blocks that resolve each individual compact object. This layer has
69  * a spherical outer boundary - if the corresponding layer-0 block exists,
70  * then the layer is a cube-to-sphere transition; if the layer-0 block is
71  * excised, then the layer is a spherical shell.
72  * - 2: The blocks that surround each object with a cube. Around each compact
73  * object, this layer transitions from a sphere to a cube.
74  * - 3: The blocks that surround each cube with a half-cube. At this layer, the
75  * two compact objects are enclosed in a single cube-shaped grid.
76  * - 4: The 10 blocks that form the first outer shell. This layer transitions
77  * back to spherical. The gridpoints are distributed linearly with respect
78  * to radius.
79  * - 5: The 10 blocks that form a second outer shell. This layer is
80  * spherical, so a logarithmic map can optionally be used in this layer.
81  * This allows the domain to extend to large radial distances from the
82  * compact objects. This layer can be h-refined radially,
83  * creating a layer of multiple concentric spherical shells.
84  *
85  * In the code and options below, `ObjectA` and `ObjectB` refer to the two
86  * compact objects, and by extension, also refer to the layers that immediately
87  * surround each compact object. Note that `ObjectA` is located to the left of
88  * the origin (along the negative x-axis) and `ObjectB` is located to the right
89  * of the origin. `enveloping cube` refers to the outer surface of Layer 3.
90  * `enveloping sphere` is the radius of the spherical outer boundary, which is
91  * the outer boundary of Layer 5. The `enveloping cube` and `enveloping sphere`
92  * are both centered at the origin. `cutting plane` refers to the plane along
93  * which the domain divides into two hemispheres. In the final coordinates, the
94  * cutting plane always intersects the x-axis at the origin.
95  *
96  * \note The x-coordinate locations of the `ObjectA` and `ObjectB` should be
97  * chosen such that the center of mass is located at x=0.
98  */
100  public:
101  using maps_list = tmpl::list<
139 
141  using type = double;
142  static constexpr OptionString help = {
143  "Inner coordinate radius of Layer 1 for Object A."};
144  };
145 
147  using type = double;
148  static constexpr OptionString help = {
149  "Outer coordinate radius of Layer 1 for Object A."};
150  };
151 
152  struct XCoordObjectA {
153  using type = double;
154  static constexpr OptionString help = {
155  "x-coordinate of center for Object A."};
156  };
157 
159  using type = bool;
160  static constexpr OptionString help = {
161  "Exclude Layer 0 for ObjectA. Set to `true` for a BH."};
162  };
163 
165  using type = double;
166  static constexpr OptionString help = {
167  "Inner coordinate radius of Layer 1 for Object B."};
168  };
169 
171  using type = double;
172  static constexpr OptionString help = {
173  "Outer coordinate radius of Layer 1 for Object B."};
174  };
175 
176  struct XCoordObjectB {
177  using type = double;
178  static constexpr OptionString help = {
179  "x-coordinate of the center for Object B."};
180  };
181 
183  using type = bool;
184  static constexpr OptionString help = {
185  "Exclude Layer 0 for ObjectB. Set to `true` for a BH."};
186  };
187 
189  using type = double;
190  static constexpr OptionString help = {
191  "Radius of Layer 3 which circumscribes the Frustums."};
192  };
193 
195  using type = double;
196  static constexpr OptionString help = {"Radius of the entire domain."};
197  };
198 
200  using type = size_t;
201  static constexpr OptionString help = {
202  "Initial refinement level. Applied to each dimension."};
203  };
204 
206  using type = size_t;
207  static constexpr OptionString help = {
208  "Initial number of grid points in each dim per element."};
209  };
210 
212  using type = bool;
213  static constexpr OptionString help = {
214  "Use equiangular instead of equidistant coordinates."};
215  static type default_value() { return false; }
216  };
217 
219  using type = bool;
220  static constexpr OptionString help = {
221  "Use projective scaling on the frustal cloak."};
222  static type default_value() { return true; }
223  };
224 
226  using type = bool;
227  static constexpr OptionString help = {
228  "Use a logarithmically spaced radial grid in Layer 5, the outer "
229  "spherical shell that covers the wave zone."};
230  static type default_value() noexcept { return false; }
231  };
232 
234  using type = size_t;
235  static constexpr OptionString help = {
236  "Addition to radial refinement level in Layer 5 (the outer spherical "
237  "shell that covers that wave zone), beyond the refinement "
238  "level set by InitialRefinement."};
239  static constexpr type default_value() noexcept { return 0; }
240  static type lower_bound() noexcept { return 0; }
241  };
242 
244  using type = bool;
245  static constexpr OptionString help = {
246  "Use a logarithmically spaced radial grid in the part of Layer 1 "
247  "enveloping Object A (requires ExciseInteriorA == true)"};
248  static type default_value() noexcept { return false; }
249  };
250 
252  using type = size_t;
253  static constexpr OptionString help = {
254  "Addition to radial refinement level in the part of Layer 1 enveloping "
255  "Object A, beyond the refinement level set by InitialRefinement."};
256  static constexpr type default_value() noexcept { return 0; }
257  static type lower_bound() noexcept { return 0; }
258  };
259 
261  using type = bool;
262  static constexpr OptionString help = {
263  "Use a logarithmically spaced radial grid in the part of Layer 1 "
264  "enveloping Object B (requires ExciseInteriorB == true)"};
265  static type default_value() noexcept { return false; }
266  };
267 
269  using type = size_t;
270  static constexpr OptionString help = {
271  "Addition to radial refinement level in the part of Layer 1 enveloping "
272  "Object B, beyond the refinement level set by InitialRefinement."};
273  static constexpr type default_value() noexcept { return 0; }
274  static type lower_bound() noexcept { return 0; }
275  };
276 
277  struct TimeDependence {
278  using type =
280  static constexpr OptionString help = {
281  "The time dependence of the moving mesh domain."};
282  static type default_value() noexcept;
283  };
284 
285  using options = tmpl::list<
293 
294  static constexpr OptionString help{
295  "The BinaryCompactObject domain is a general domain for two compact "
296  "objects. The user must provide the inner and outer radii of the "
297  "spherical shells surrounding each of the two compact objects A and "
298  "B. The radial refinement levels for these shells are (InitialRefinement "
299  "+ AdditionToObjectARadialRefinementLevel) and (InitialRefinement + "
300  "AdditionToObjectBRadialRefinementLevel), respectively.\n\n"
301  "The user must also provide the radius of the sphere that "
302  "circumscribes the cube containing both compact objects, and the "
303  "radius of the outer boundary. The options ExciseInteriorA and "
304  "ExciseInteriorB determine whether the layer-zero blocks are present "
305  "inside each compact object. If set to `true`, the domain will not "
306  "contain layer zero for that object. The user specifies XCoordObjectA "
307  "and XCoordObjectB, the x-coordinates of the locations of the centers "
308  "of each compact object. In these coordinates, the location for the "
309  "axis of rotation is x=0. ObjectA is located on the left and ObjectB "
310  "is located on the right. Please make sure that your choices of "
311  "x-coordinate locations are such that the resulting center of mass "
312  "is located at zero.\n\n"
313  "Two radial layers join the outer cube to the spherical outer boundary. "
314  "The first of these layers transitions from sphericity == 0.0 on the "
315  "inner boundary to sphericity == 1.0 on the outer boundary. The second "
316  "has sphericity == 1 (so either linear or logarithmic mapping can be "
317  "used in the radial direction), extends to the spherical outer boundary "
318  "of the domain, and has a radial refinement level of (InitialRefinement "
319  "+ AdditionToOuterLayerRadialRefinementLevel)."};
320 
322  typename InnerRadiusObjectA::type inner_radius_object_A,
323  typename OuterRadiusObjectA::type outer_radius_object_A,
324  typename XCoordObjectA::type xcoord_object_A,
325  typename ExciseInteriorA::type excise_interior_A,
326  typename InnerRadiusObjectB::type inner_radius_object_B,
327  typename OuterRadiusObjectB::type outer_radius_object_B,
328  typename XCoordObjectB::type xcoord_object_B,
329  typename ExciseInteriorB::type excise_interior_B,
330  typename RadiusOuterCube::type radius_enveloping_cube,
331  typename RadiusOuterSphere::type radius_enveloping_sphere,
332  typename InitialRefinement::type initial_refinement,
333  typename InitialGridPoints::type initial_grid_points_per_dim,
334  typename UseEquiangularMap::type use_equiangular_map,
335  typename UseProjectiveMap::type use_projective_map = true,
336  typename UseLogarithmicMapOuterSphericalShell::type
337  use_logarithmic_map_outer_spherical_shell = false,
338  typename AdditionToOuterLayerRadialRefinementLevel::type
339  addition_to_outer_layer_radial_refinement_level = 0,
340  typename UseLogarithmicMapObjectA::type use_logarithmic_map_object_A =
341  false,
342  typename AdditionToObjectARadialRefinementLevel::type
343  addition_to_object_A_radial_refinement_level = 0,
344  typename UseLogarithmicMapObjectB::type use_logarithmic_map_object_B =
345  false,
346  typename AdditionToObjectBRadialRefinementLevel::type
347  addition_to_object_B_radial_refinement_level = 0,
349  time_dependence = nullptr,
350  const OptionContext& context = {});
351 
352  BinaryCompactObject() = default;
353  BinaryCompactObject(const BinaryCompactObject&) = delete;
354  BinaryCompactObject(BinaryCompactObject&&) noexcept = default;
355  BinaryCompactObject& operator=(const BinaryCompactObject&) = delete;
356  BinaryCompactObject& operator=(BinaryCompactObject&&) noexcept = default;
357  ~BinaryCompactObject() noexcept override = default;
358 
359  Domain<3> create_domain() const noexcept override;
360 
361  std::vector<std::array<size_t, 3>> initial_extents() const noexcept override;
362 
363  std::vector<std::array<size_t, 3>> initial_refinement_levels() const
364  noexcept override;
365 
366  auto functions_of_time() const noexcept -> std::unordered_map<
367  std::string,
368  std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
369 
370  private:
371  typename InnerRadiusObjectA::type inner_radius_object_A_{};
372  typename OuterRadiusObjectA::type outer_radius_object_A_{};
373  typename XCoordObjectA::type xcoord_object_A_{};
374  typename ExciseInteriorA::type excise_interior_A_{};
375  typename InnerRadiusObjectB::type inner_radius_object_B_{};
376  typename OuterRadiusObjectB::type outer_radius_object_B_{};
377  typename XCoordObjectB::type xcoord_object_B_{};
378  typename ExciseInteriorB::type excise_interior_B_{};
379  typename RadiusOuterCube::type radius_enveloping_cube_{};
380  typename RadiusOuterSphere::type radius_enveloping_sphere_{};
381  typename InitialRefinement::type initial_refinement_{};
382  typename InitialGridPoints::type initial_grid_points_per_dim_{};
383  typename UseEquiangularMap::type use_equiangular_map_ = true;
384  typename UseProjectiveMap::type use_projective_map_ = true;
385  typename UseLogarithmicMapOuterSphericalShell::type
386  use_logarithmic_map_outer_spherical_shell_ = false;
387  typename AdditionToOuterLayerRadialRefinementLevel::type
388  addition_to_outer_layer_radial_refinement_level_{};
389  typename UseLogarithmicMapObjectA::type use_logarithmic_map_object_A_ = false;
390  typename AdditionToObjectARadialRefinementLevel::type
391  addition_to_object_A_radial_refinement_level_{};
392  typename UseLogarithmicMapObjectB::type use_logarithmic_map_object_B_ = false;
393  typename AdditionToObjectBRadialRefinementLevel::type
394  addition_to_object_B_radial_refinement_level_{};
395  double projective_scale_factor_{};
396  double translation_{};
397  double length_inner_cube_{};
398  double length_outer_cube_{};
399  size_t number_of_blocks_{};
401  time_dependence_;
402 };
403 } // namespace creators
404 } // namespace domain
domain::creators::BinaryCompactObject::InnerRadiusObjectB
Definition: BinaryCompactObject.hpp:164
domain::CoordinateMaps::ProductOf3Maps
Product of three one-dimensional CoordinateMaps.
Definition: ProductMaps.hpp:86
domain::creators::BinaryCompactObject::XCoordObjectA
Definition: BinaryCompactObject.hpp:152
domain::creators::BinaryCompactObject::OuterRadiusObjectB
Definition: BinaryCompactObject.hpp:170
Frame::Inertial
Definition: IndexType.hpp:44
domain::creators::BinaryCompactObject::ExciseInteriorA
Definition: BinaryCompactObject.hpp:158
Options.hpp
vector
domain::creators::BinaryCompactObject
A general domain for two compact objects.
Definition: BinaryCompactObject.hpp:99
Domain.hpp
OptionContext
Definition: Options.hpp:39
domain::creators::BinaryCompactObject::UseProjectiveMap
Definition: BinaryCompactObject.hpp:218
domain::CoordinateMaps::ProductOf2Maps
Product of two codimension=0 CoordinateMaps.
Definition: ProductMaps.hpp:35
domain::CoordinateMaps::Equiangular
Non-linear map from .
Definition: Equiangular.hpp:53
domain::creators::BinaryCompactObject::XCoordObjectB
Definition: BinaryCompactObject.hpp:176
CoordinateMap.hpp
domain::creators::BinaryCompactObject::OuterRadiusObjectA
Definition: BinaryCompactObject.hpp:146
domain::creators::BinaryCompactObject::RadiusOuterSphere
Definition: BinaryCompactObject.hpp:194
domain::CoordinateMaps::DiscreteRotation
A CoordinateMap that swaps/negates the coordinate axes.
Definition: DiscreteRotation.hpp:32
domain::CoordinateMaps::Affine
Affine map from .
Definition: Affine.hpp:37
domain::creators::BinaryCompactObject::UseLogarithmicMapObjectB
Definition: BinaryCompactObject.hpp:260
cstddef
Assert.hpp
domain::creators::BinaryCompactObject::InitialRefinement
Definition: BinaryCompactObject.hpp:199
domain::creators::time_dependence::TimeDependence
The abstract base class off of which specific classes for adding time dependence into a domain creato...
Definition: TimeDependence.hpp:55
array
domain::creators::BinaryCompactObject::UseLogarithmicMapObjectA
Definition: BinaryCompactObject.hpp:243
Domain
A wrapper around a vector of Blocks that represent the computational domain.
Definition: Domain.hpp:38
memory
domain::creators::BinaryCompactObject::InitialGridPoints
Definition: BinaryCompactObject.hpp:205
domain::creators::BinaryCompactObject::UseLogarithmicMapOuterSphericalShell
Definition: BinaryCompactObject.hpp:225
domain::creators::BinaryCompactObject::UseEquiangularMap
Definition: BinaryCompactObject.hpp:211
DomainCreator
Base class for creating Domains from an option string.
Definition: DomainCreator.hpp:88
domain::CoordinateMaps::Wedge3D
Three dimensional map from the cube to a wedge.
Definition: Wedge3D.hpp:216
domain::creators::BinaryCompactObject::RadiusOuterCube
Definition: BinaryCompactObject.hpp:188
domain::creators::BinaryCompactObject::TimeDependence
Definition: BinaryCompactObject.hpp:277
domain::CoordinateMaps::Identity
Definition: Identity.hpp:28
domain::creators::BinaryCompactObject::AdditionToObjectARadialRefinementLevel
Definition: BinaryCompactObject.hpp:251
domain::CoordinateMaps::Frustum
A reorientable map from the cube to a frustum.
Definition: Frustum.hpp:164
Frame
Definition: IndexType.hpp:36
domain::creators::BinaryCompactObject::AdditionToOuterLayerRadialRefinementLevel
Definition: BinaryCompactObject.hpp:233
domain::creators::BinaryCompactObject::InnerRadiusObjectA
Definition: BinaryCompactObject.hpp:140
domain::creators::BinaryCompactObject::AdditionToObjectBRadialRefinementLevel
Definition: BinaryCompactObject.hpp:268
Frame::Logical
Definition: IndexType.hpp:42
DomainCreator.hpp
domain::creators::BinaryCompactObject::ExciseInteriorB
Definition: BinaryCompactObject.hpp:182
std::unique_ptr< domain::creators::time_dependence::TimeDependence< 3 > >
unordered_map
OptionString
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:30
TMPL.hpp
domain::CoordinateMap
A coordinate map or composition of coordinate maps.
Definition: CoordinateMap.hpp:237
string