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 <vector>
9 
10 #include "Domain/Creators/DomainCreator.hpp" // IWYU pragma: keep
11 #include "Domain/Domain.hpp"
12 #include "Options/Options.hpp"
13 #include "Utilities/TMPL.hpp"
14 
15 /// \cond
16 namespace domain {
17 namespace CoordinateMaps {
18 class Affine;
19 class Equiangular;
20 template <size_t VolumeDim>
21 class Identity;
22 template <typename Map1, typename Map2>
23 class ProductOf2Maps;
24 template <typename Map1, typename Map2, typename Map3>
25 class ProductOf3Maps;
26 class Wedge3D;
27 template <size_t VolumeDim>
28 class DiscreteRotation;
29 class Frustum;
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 
40 /*!
41  * \ingroup DomainCreatorsGroup
42  *
43  * \brief A general domain for two compact objects.
44  *
45  * \image html binary_compact_object_domain.png "A BHNS domain."
46  *
47  * Creates a 3D Domain that represents a binary compact object solution. The
48  * Domain consists of four/five nested layers of blocks; these layers are,
49  * working from the interior toward the exterior:
50  * - 0: (optionally) The block at the center of each compact object, if not
51  * excised. If present, this block is a cube. If excised, the hole left
52  * by its absence is spherical.
53  * - 1: The blocks that resolve each individual compact object. This layer has
54  * a spherical outer boundary - if the corresponding layer-0 block exists,
55  * then the layer is a cube-to-sphere transition; if the layer-0 block is
56  * excised, then the layer is a spherical shell.
57  * - 2: The blocks that surround each object with a cube. Around each compact
58  * object, this layer transitions from a sphere to a cube.
59  * - 3: The blocks that surround each cube with a half-cube. At this layer, the
60  * two compact objects are enclosed in a single cube-shaped grid.
61  * - 4: The blocks that form the outer sphere. This layer transitions back to
62  * spherical and can extend to large radial distances from the compact
63  * objects.
64  * In the code and options below, `ObjectA` and `ObjectB` refer to the two
65  * compact objects, and by extension, also refer to the layers that immediately
66  * surround each compact object. Note that `ObjectA` is located to the left of
67  * the origin (along the negative x-axis) and `ObjectB` is located to the right
68  * of the origin.
69  * `enveloping cube` and `enveloping sphere` refer to the outer surfaces of
70  * layers 3 and 4 respectively. Both of these surfaces are centered at the
71  * origin.
72  * `cutting plane` refers to the plane along which the domain divides into two
73  * hemispheres. In the final coordinates, the cutting plane always intersects
74  * the x-axis at the origin.
75  *
76  * \note The x-coordinate locations of the `ObjectA` and `ObjectB` should be
77  * chosen such that the center of mass is located at x=0.
78  */
80  public:
81  using maps_list = tmpl::list<
84  CoordinateMaps::Affine, CoordinateMaps::Affine,
85  CoordinateMaps::Affine>>,
87  Frame::Logical, Frame::Inertial,
89  CoordinateMaps::Equiangular,
90  CoordinateMaps::Equiangular>>,
92  Frame::Logical, Frame::Inertial,
93  CoordinateMaps::ProductOf3Maps<CoordinateMaps::Affine,
94  CoordinateMaps::Affine,
95  CoordinateMaps::Affine>,
96  CoordinateMaps::ProductOf2Maps<CoordinateMaps::Affine,
98  domain::CoordinateMap<Frame::Logical, Frame::Inertial,
101  CoordinateMaps::Affine, CoordinateMaps::Affine,
102  CoordinateMaps::Affine>>,
103  domain::CoordinateMap<Frame::Logical, Frame::Inertial,
105  CoordinateMaps::Equiangular,
106  CoordinateMaps::Equiangular,
107  CoordinateMaps::Equiangular>>,
109  Frame::Logical, Frame::Inertial,
110  CoordinateMaps::ProductOf3Maps<CoordinateMaps::Equiangular,
111  CoordinateMaps::Equiangular,
112  CoordinateMaps::Equiangular>,
113  CoordinateMaps::ProductOf2Maps<CoordinateMaps::Affine,
114  CoordinateMaps::Identity<2>>>,
115  domain::CoordinateMap<Frame::Logical, Frame::Inertial,
117  domain::CoordinateMap<Frame::Logical, Frame::Inertial,
119 
121  using type = double;
122  static constexpr OptionString help = {
123  "Inner coordinate radius of Layer 1 for Object A."};
124  };
125 
127  using type = double;
128  static constexpr OptionString help = {
129  "Outer coordinate radius of Layer 1 for Object A."};
130  };
131 
132  struct XCoordObjectA {
133  using type = double;
134  static constexpr OptionString help = {
135  "x-coordinate of center for Object A."};
136  };
137 
139  using type = bool;
140  static constexpr OptionString help = {
141  "Exclude Layer 0 for ObjectA. Set to `true` for a BH."};
142  };
143 
145  using type = double;
146  static constexpr OptionString help = {
147  "Inner coordinate radius of Layer 1 for Object B."};
148  };
149 
151  using type = double;
152  static constexpr OptionString help = {
153  "Outer coordinate radius of Layer 1 for Object B."};
154  };
155 
156  struct XCoordObjectB {
157  using type = double;
158  static constexpr OptionString help = {
159  "x-coordinate of the center for Object B."};
160  };
161 
163  using type = bool;
164  static constexpr OptionString help = {
165  "Exclude Layer 0 for ObjectB. Set to `true` for a BH."};
166  };
167 
169  using type = double;
170  static constexpr OptionString help = {
171  "Radius of Layer 3 which circumscribes the Frustums."};
172  };
173 
175  using type = double;
176  static constexpr OptionString help = {"Radius of the entire domain."};
177  };
178 
180  using type = size_t;
181  static constexpr OptionString help = {
182  "Initial refinement level. Applied to each dimension."};
183  };
184 
186  using type = size_t;
187  static constexpr OptionString help = {
188  "Initial number of grid points in each dim per element."};
189  };
190 
192  using type = bool;
193  static constexpr OptionString help = {
194  "Use equiangular instead of equidistant coordinates."};
195  static type default_value() { return false; }
196  };
197 
199  using type = bool;
200  static constexpr OptionString help = {
201  "Use projective scaling on the frustal cloak."};
202  static type default_value() { return true; }
203  };
204 
205  using options =
211 
212  static constexpr OptionString help{
213  "The BinaryCompactObject domain is a general domain for two compact \n"
214  "objects. The user must provide the inner and outer radii of the \n"
215  "spherical shells surrounding each of the two compact objects A and B. \n"
216  "The user must also provide the radius of the sphere that \n"
217  "circumscribes the cube containing both compact objects, and the \n"
218  "radius of the outer boundary. The options ExciseInteriorA and \n"
219  "ExciseInteriorB determine whether the layer-zero blocks are present \n"
220  "inside each compact object. If set to `true`, the domain will not \n"
221  "contain layer zero for that object. The user specifies XCoordObjectA \n"
222  "and XCoordObjectB, the x-coordinates of the locations of the centers \n"
223  "of each compact object. In these coordinates, the location for the \n"
224  "axis of rotation is x=0. ObjectA is located on the left and ObjectB \n"
225  "is located on the right. Please make sure that your choices of \n"
226  "x-coordinate locations are such that the resulting center of mass\n"
227  "is located at zero."};
228 
230  typename InnerRadiusObjectA::type inner_radius_object_A,
231  typename OuterRadiusObjectA::type outer_radius_object_A,
232  typename XCoordObjectA::type xcoord_object_A,
233  typename ExciseInteriorA::type excise_interior_A,
234  typename InnerRadiusObjectB::type inner_radius_object_B,
235  typename OuterRadiusObjectB::type outer_radius_object_B,
236  typename XCoordObjectB::type xcoord_object_B,
237  typename ExciseInteriorB::type excise_interior_B,
238  typename RadiusOuterCube::type radius_enveloping_cube,
239  typename RadiusOuterSphere::type radius_enveloping_sphere,
240  typename InitialRefinement::type initial_refinement,
241  typename InitialGridPoints::type initial_grid_points_per_dim,
242  typename UseEquiangularMap::type use_equiangular_map,
243  typename UseProjectiveMap::type use_projective_map = true,
244  const OptionContext& context = {});
245 
246  BinaryCompactObject() = default;
247  BinaryCompactObject(const BinaryCompactObject&) = delete;
248  BinaryCompactObject(BinaryCompactObject&&) noexcept = default;
249  BinaryCompactObject& operator=(const BinaryCompactObject&) = delete;
250  BinaryCompactObject& operator=(BinaryCompactObject&&) noexcept = default;
251  ~BinaryCompactObject() noexcept override = default;
252 
253  Domain<3> create_domain() const noexcept override;
254 
255  std::vector<std::array<size_t, 3>> initial_extents() const noexcept override;
256 
257  std::vector<std::array<size_t, 3>> initial_refinement_levels() const
258  noexcept override;
259 
260  private:
261  typename InnerRadiusObjectA::type inner_radius_object_A_{};
262  typename OuterRadiusObjectA::type outer_radius_object_A_{};
263  typename XCoordObjectA::type xcoord_object_A_{};
264  typename ExciseInteriorA::type excise_interior_A_{};
265  typename InnerRadiusObjectB::type inner_radius_object_B_{};
266  typename OuterRadiusObjectB::type outer_radius_object_B_{};
267  typename XCoordObjectB::type xcoord_object_B_{};
268  typename ExciseInteriorB::type excise_interior_B_{};
269  typename RadiusOuterCube::type radius_enveloping_cube_{};
270  typename RadiusOuterSphere::type radius_enveloping_sphere_{};
271  typename InitialRefinement::type initial_refinement_{};
272  typename InitialGridPoints::type initial_grid_points_per_dim_{};
273  typename UseEquiangularMap::type use_equiangular_map_ = true;
274  typename UseProjectiveMap::type use_projective_map_ = true;
275  double projective_scale_factor_{};
276  double translation_{};
277  double length_inner_cube_{};
278  double length_outer_cube_{};
279 };
280 } // namespace creators
281 } // namespace domain
Three dimensional map from the cube to a wedge.
Definition: Wedge3D.hpp:216
Definition: BinaryCompactObject.hpp:162
Definition: BlockId.hpp:16
Definition: BinaryCompactObject.hpp:156
Definition: BinaryCompactObject.hpp:168
Definition: BinaryCompactObject.hpp:150
Defines classes and functions for making classes creatable from input files.
Product of three one-dimensional CoordinateMaps.
Definition: ProductMaps.hpp:86
A coordinate map or composition of coordinate maps.
Definition: CoordinateMap.hpp:237
Definition: BinaryCompactObject.hpp:174
Base class for creating Domains from an option string.
Definition: DomainCreator.hpp:88
Definition: BinaryCompactObject.hpp:126
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:30
Definition: BinaryCompactObject.hpp:179
A general domain for two compact objects.
Definition: BinaryCompactObject.hpp:79
Non-linear map from .
Definition: Equiangular.hpp:53
Affine map from .
Definition: Affine.hpp:37
Definition: BinaryCompactObject.hpp:120
Defines class template Domain.
Definition: BinaryCompactObject.hpp:185
Definition: IndexType.hpp:42
Definition: BinaryCompactObject.hpp:191
A reorientable map from the cube to a frustum.
Definition: Frustum.hpp:164
A CoordinateMap that swaps/negates the coordinate axes.
Definition: DiscreteRotation.hpp:32
Identity map from .
Definition: Identity.hpp:28
A wrapper around a vector of Blocks that represent the computational domain.
Definition: Domain.hpp:38
Information about the nested operations being performed by the parser, for use in printing errors...
Definition: Options.hpp:39
Wraps the template metaprogramming library used (brigand)
Definition: IndexType.hpp:44
Definition: BinaryCompactObject.hpp:144
Definition: BinaryCompactObject.hpp:198
Product of two codimension=0 CoordinateMaps.
Definition: ProductMaps.hpp:35
Definition: BinaryCompactObject.hpp:138
Definition: BinaryCompactObject.hpp:132
Defines class DomainCreator.