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 <optional>
10 #include <string>
11 #include <unordered_map>
12 #include <vector>
13 
14 #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
15 #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp"
18 #include "Domain/Creators/TimeDependence/TimeDependence.hpp"
19 #include "Domain/Domain.hpp"
20 #include "Options/Auto.hpp"
21 #include "Options/Options.hpp"
23 #include "Utilities/TMPL.hpp"
24 
25 /// \cond
26 namespace domain {
27 namespace CoordinateMaps {
28 class Affine;
29 class Equiangular;
30 template <size_t VolumeDim>
31 class Identity;
32 template <typename Map1, typename Map2>
33 class ProductOf2Maps;
34 template <typename Map1, typename Map2, typename Map3>
35 class ProductOf3Maps;
36 template <size_t Dim>
37 class Wedge;
38 template <size_t VolumeDim>
39 class DiscreteRotation;
40 class Frustum;
41 } // namespace CoordinateMaps
42 
43 template <typename SourceFrame, typename TargetFrame, typename... Maps>
44 class CoordinateMap;
45 
46 namespace FunctionsOfTime {
47 class FunctionOfTime;
48 } // namespace FunctionsOfTime
49 } // namespace domain
50 
51 namespace Frame {
52 struct Inertial;
53 struct Logical;
54 } // namespace Frame
55 /// \endcond
56 
57 namespace domain {
58 namespace creators {
59 
60 /*!
61  * \ingroup ComputationalDomainGroup
62  *
63  * \brief A general domain for two compact objects.
64  *
65  * \image html binary_compact_object_domain.png "A BHNS domain."
66  *
67  * Creates a 3D Domain that represents a binary compact object solution. The
68  * Domain consists of 4, 5, or 6 nested layers of blocks; these layers are,
69  * working from the interior toward the exterior:
70  * - 0: (optionally) The block at the center of each compact object, if not
71  * excised. If present, this block is a cube. If excised, the hole left
72  * by its absence is spherical.
73  * - 1: The blocks that resolve each individual compact object. This layer has
74  * a spherical outer boundary - if the corresponding layer-0 block exists,
75  * then the layer is a cube-to-sphere transition; if the layer-0 block is
76  * excised, then the layer is a spherical shell.
77  * - 2: The blocks that surround each object with a cube. Around each compact
78  * object, this layer transitions from a sphere to a cube.
79  * - 3: The blocks that surround each cube with a half-cube. At this layer, the
80  * two compact objects are enclosed in a single cube-shaped grid.
81  * - 4: The 10 blocks that form the first outer shell. This layer transitions
82  * back to spherical. The gridpoints are distributed linearly with respect
83  * to radius.
84  * - 5: The 10 blocks that form a second outer shell. This layer is
85  * spherical, so a logarithmic map can optionally be used in this layer.
86  * This allows the domain to extend to large radial distances from the
87  * compact objects. This layer can be h-refined radially,
88  * creating a layer of multiple concentric spherical shells.
89  *
90  * In the code and options below, `ObjectA` and `ObjectB` refer to the two
91  * compact objects, and by extension, also refer to the layers that immediately
92  * surround each compact object. Note that `ObjectA` is located to the left of
93  * the origin (along the negative x-axis) and `ObjectB` is located to the right
94  * of the origin. `enveloping cube` refers to the outer surface of Layer 3.
95  * `outer sphere` is the radius of the spherical outer boundary, which is
96  * the outer boundary of Layer 5. The `enveloping cube` and `outer sphere`
97  * are both centered at the origin. `cutting plane` refers to the plane along
98  * which the domain divides into two hemispheres. In the final coordinates, the
99  * cutting plane always intersects the x-axis at the origin.
100  *
101  * \note The x-coordinate locations of the `ObjectA` and `ObjectB` should be
102  * chosen such that the center of mass is located at x=0.
103  */
105  public:
106  using maps_list = tmpl::list<
144 
145  /// Options for an excision region in the domain
146  struct Excision {
147  static constexpr Options::String help = {
148  "Excise the interior of the object, leaving a spherical hole in its "
149  "absence."};
150  template <typename BoundaryConditionsBase>
152  static std::string name() noexcept {
153  return "ExciseWithBoundaryCondition";
154  }
156  static constexpr Options::String help = {
157  "The boundary condition to impose on the excision surface."};
158  };
159  template <typename Metavariables>
160  using options = tmpl::list<BoundaryCondition<
162  typename Metavariables::system>>>;
164  boundary_condition;
165  };
166 
167  /// Options for one of the two objects in the binary domain
168  struct Object {
169  static constexpr Options::String help = {
170  "Options for an object in a binary domain."};
171  struct InnerRadius {
172  using type = double;
173  static constexpr Options::String help = {
174  "Inner coordinate radius of Layer 1."};
175  static double lower_bound() noexcept { return 0.; }
176  };
177  struct OuterRadius {
178  using type = double;
179  static constexpr Options::String help = {
180  "Outer coordinate radius of Layer 1"};
181  static double lower_bound() noexcept { return 0.; }
182  };
183  struct XCoord {
184  using type = double;
185  static constexpr Options::String help = {"x-coordinate of center."};
186  };
187  struct Interior {
189  static constexpr Options::String help = {
190  "Specify 'ExciseWithBoundaryCondition' and a boundary condition to "
191  "excise Layer 0, leaving a spherical hole in its absence, or set to "
192  "'Auto' to fill the interior."};
193  };
194  struct ExciseInterior {
195  using type = bool;
196  static constexpr Options::String help = {
197  "Excise Layer 0, leaving a spherical hole in its absence."};
198  };
200  using type = bool;
201  static constexpr Options::String help = {
202  "Use a logarithmically spaced radial grid in the part of Layer 1 "
203  "enveloping the object (requires the interior is excised)"};
204  };
206  using type = size_t;
207  static constexpr Options::String help = {
208  "Addition to radial refinement level in the part of Layer 1 "
209  "enveloping the object, beyond the refinement level set by "
210  "InitialRefinement."};
211  };
212  template <typename Metavariables>
213  using options = tmpl::list<
215  tmpl::conditional_t<
216  domain::BoundaryConditions::has_boundary_conditions_base_v<
217  typename Metavariables::system>,
220  Object() = default;
221  Object(double local_inner_radius, double local_outer_radius,
222  double local_x_coord, std::optional<Excision> interior,
223  bool local_use_logarithmic_map,
224  size_t local_addition_to_radial_refinement_level) noexcept
225  : inner_radius(local_inner_radius),
226  outer_radius(local_outer_radius),
227  x_coord(local_x_coord),
228  inner_boundary_condition(
229  interior.has_value()
230  ? std::make_optional(std::move(interior->boundary_condition))
231  : std::nullopt),
232  use_logarithmic_map(local_use_logarithmic_map),
233  addition_to_radial_refinement_level(
234  local_addition_to_radial_refinement_level) {}
235  Object(double local_inner_radius, double local_outer_radius,
236  double local_x_coord, bool local_excise_interior,
237  bool local_use_logarithmic_map,
238  size_t local_addition_to_radial_refinement_level) noexcept
239  : inner_radius(local_inner_radius),
240  outer_radius(local_outer_radius),
241  x_coord(local_x_coord),
242  inner_boundary_condition(
243  local_excise_interior
246  : std::nullopt),
247  use_logarithmic_map(local_use_logarithmic_map),
248  addition_to_radial_refinement_level(
249  local_addition_to_radial_refinement_level) {}
250 
251  /// Whether or not the object should be excised from the domain, leaving a
252  /// spherical hole. When this is true, `inner_boundary_condition` is
253  /// guaranteed to hold a value (though it might be a `nullptr` if we are not
254  /// working with boundary conditions).
255  bool is_excised() const noexcept;
256 
257  double inner_radius;
258  double outer_radius;
259  double x_coord;
260  std::optional<
261  std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>
262  inner_boundary_condition;
263  bool use_logarithmic_map;
264  size_t addition_to_radial_refinement_level;
265  };
266 
267  struct ObjectA {
268  using type = Object;
269  static constexpr Options::String help = {
270  "Options for the object to the left of the origin (along the negative "
271  "x-axis)."};
272  };
273 
274  struct ObjectB {
275  using type = Object;
276  static constexpr Options::String help = {
277  "Options for the object to the right of the origin (along the positive "
278  "x-axis)."};
279  };
280 
281  struct EnvelopingCube {
282  static constexpr Options::String help = {
283  "Options for the cube enveloping the two objects."};
284  };
285 
287  using group = EnvelopingCube;
288  static std::string name() noexcept { return "Radius"; }
289  using type = double;
290  static constexpr Options::String help = {
291  "Radius of Layer 3 which circumscribes the Frustums."};
292  };
293 
294  struct OuterSphere {
295  static constexpr Options::String help = {
296  "Options for the outer spherical shell."};
297  };
298 
300  using group = OuterSphere;
301  static std::string name() noexcept { return "Radius"; }
302  using type = double;
303  static constexpr Options::String help = {"Radius of the entire domain."};
304  };
305 
307  using type = size_t;
308  static constexpr Options::String help = {
309  "Initial refinement level. Applied to each dimension."};
310  };
311 
313  using type = size_t;
314  static constexpr Options::String help = {
315  "Initial number of grid points in each dim per element."};
316  };
317 
319  using type = bool;
320  static constexpr Options::String help = {
321  "Use projective scaling on the frustal cloak."};
322  };
323 
325  using group = OuterSphere;
326  static std::string name() noexcept { return "UseLogarithmicMap"; }
327  using type = bool;
328  static constexpr Options::String help = {
329  "Use a logarithmically spaced radial grid in Layer 5, the outer "
330  "spherical shell that covers the wave zone."};
331  };
332 
334  using group = OuterSphere;
335  static std::string name() noexcept {
336  return "AdditionToRadialRefinementLevel";
337  }
338  using type = size_t;
339  static constexpr Options::String help = {
340  "Addition to radial refinement level in Layer 5 (the outer spherical "
341  "shell that covers that wave zone), beyond the refinement "
342  "level set by InitialRefinement."};
343  };
344 
345  struct TimeDependence {
346  using type =
348  static constexpr Options::String help = {
349  "The time dependence of the moving mesh domain."};
350  };
351 
352  template <typename BoundaryConditionsBase>
354  using group = OuterSphere;
355  static std::string name() noexcept { return "BoundaryCondition"; }
356  static constexpr Options::String help =
357  "Options for the outer boundary conditions.";
359  };
360 
361  template <typename Metavariables>
362  using options = tmpl::append<
367  tmpl::conditional_t<
368  domain::BoundaryConditions::has_boundary_conditions_base_v<
369  typename Metavariables::system>,
370  tmpl::list<OuterBoundaryCondition<
372  typename Metavariables::system>>>,
373  tmpl::list<>>>;
374 
375  static constexpr Options::String help{
376  "The BinaryCompactObject domain is a general domain for two compact "
377  "objects. The user must provide the inner and outer radii of the "
378  "spherical shells surrounding each of the two compact objects A and "
379  "B. The radial refinement levels for these shells are (InitialRefinement "
380  "+ Object{A,B}.AdditionToRadialRefinementLevel).\n\n"
381  "The user must also provide the radius of the sphere that "
382  "circumscribes the cube containing both compact objects, and the "
383  "radius of the outer boundary. The options Object{A,B}.Interior (or "
384  "Object{A,B}.ExciseInterior if we're not working with boundary "
385  "conditions) determine whether the layer-zero blocks are present "
386  "inside each compact object. If set to a boundary condition or 'false', "
387  "the domain will not contain layer zero for that object. The user "
388  "specifies Object{A,B}.XCoord, the x-coordinates of the locations of the "
389  "centers of each compact object. In these coordinates, the location for "
390  "the axis of rotation is x=0. ObjectA is located on the left and ObjectB "
391  "is located on the right. Please make sure that your choices of "
392  "x-coordinate locations are such that the resulting center of mass "
393  "is located at zero.\n\n"
394  "Two radial layers join the enveloping cube to the spherical outer "
395  "boundary. The first of these layers transitions from sphericity == 0.0 "
396  "on the inner boundary to sphericity == 1.0 on the outer boundary. The "
397  "second has sphericity == 1 (so either linear or logarithmic mapping can "
398  "be used in the radial direction), extends to the spherical outer "
399  "boundary of the domain, and has a radial refinement level of "
400  "(InitialRefinement + OuterSphere.AdditionToRadialRefinementLevel)."};
401 
403  Object object_A, Object object_B, double radius_enveloping_cube,
404  double radius_enveloping_sphere, size_t initial_refinement,
405  size_t initial_grid_points_per_dim, bool use_projective_map = true,
406  bool use_logarithmic_map_outer_spherical_shell = false,
407  size_t addition_to_outer_layer_radial_refinement_level = 0,
409  time_dependence = nullptr,
411  outer_boundary_condition = nullptr,
412  const Options::Context& context = {});
413 
414  BinaryCompactObject() = default;
415  BinaryCompactObject(const BinaryCompactObject&) = delete;
416  BinaryCompactObject(BinaryCompactObject&&) noexcept = default;
417  BinaryCompactObject& operator=(const BinaryCompactObject&) = delete;
418  BinaryCompactObject& operator=(BinaryCompactObject&&) noexcept = default;
419  ~BinaryCompactObject() noexcept override = default;
420 
421  Domain<3> create_domain() const noexcept override;
422 
423  std::vector<std::array<size_t, 3>> initial_extents() const noexcept override;
424 
425  std::vector<std::array<size_t, 3>> initial_refinement_levels() const
426  noexcept override;
427 
428  auto functions_of_time() const noexcept -> std::unordered_map<
429  std::string,
430  std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
431 
432  private:
433  Object object_A_{};
434  Object object_B_{};
435  double radius_enveloping_cube_{};
436  double radius_enveloping_sphere_{};
437  size_t initial_refinement_{};
438  size_t initial_grid_points_per_dim_{};
439  static constexpr bool use_equiangular_map_ =
440  false; // Doesn't work properly yet
441  bool use_projective_map_ = true;
442  bool use_logarithmic_map_outer_spherical_shell_ = false;
443  size_t addition_to_outer_layer_radial_refinement_level_{};
444  double projective_scale_factor_{};
445  double translation_{};
446  double length_inner_cube_{};
447  double length_outer_cube_{};
448  size_t number_of_blocks_{};
450  time_dependence_;
452  outer_boundary_condition_;
453 };
454 } // namespace creators
455 } // namespace domain
domain::CoordinateMaps::ProductOf3Maps
Product of three one-dimensional CoordinateMaps.
Definition: ProductMaps.hpp:90
domain::BoundaryConditions::get_boundary_conditions_base
typename detail::get_boundary_conditions_base< T >::type get_boundary_conditions_base
Returns T::boundary_condition_base or a placeholder class.
Definition: GetBoundaryConditionsBase.hpp:33
domain::creators::BinaryCompactObject::Excision::BoundaryCondition
Definition: BinaryCompactObject.hpp:151
std::string
domain::creators::BinaryCompactObject::EnvelopingCube
Definition: BinaryCompactObject.hpp:281
domain::BoundaryConditions::BoundaryCondition
Base class from which all system-specific base classes must inherit.
Definition: BoundaryCondition.hpp:18
domain::creators::BinaryCompactObject::RadiusEnvelopingCube
Definition: BinaryCompactObject.hpp:286
Frame::Inertial
Definition: IndexType.hpp:44
domain::creators::BinaryCompactObject::OuterBoundaryCondition
Definition: BinaryCompactObject.hpp:353
domain::creators::BinaryCompactObject::Object::UseLogarithmicMap
Definition: BinaryCompactObject.hpp:199
Options.hpp
vector
domain::creators::BinaryCompactObject
A general domain for two compact objects.
Definition: BinaryCompactObject.hpp:104
Domain.hpp
domain::creators::BinaryCompactObject::UseProjectiveMap
Definition: BinaryCompactObject.hpp:318
domain::CoordinateMaps::ProductOf2Maps
Product of two codimension=0 CoordinateMaps.
Definition: ProductMaps.hpp:35
domain::creators::BinaryCompactObject::Object
Options for one of the two objects in the binary domain.
Definition: BinaryCompactObject.hpp:168
domain::CoordinateMaps::Equiangular
Non-linear map from .
Definition: Equiangular.hpp:53
CoordinateMap.hpp
Options::Context
Definition: Options.hpp:41
domain::creators::BinaryCompactObject::RadiusOuterSphere
Definition: BinaryCompactObject.hpp:299
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::OuterSphere
Definition: BinaryCompactObject.hpp:294
cstddef
Assert.hpp
domain::creators::BinaryCompactObject::InitialRefinement
Definition: BinaryCompactObject.hpp:306
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:60
array
Domain
A wrapper around a vector of Blocks that represent the computational domain.
Definition: Domain.hpp:40
domain::creators::BinaryCompactObject::ObjectA
Definition: BinaryCompactObject.hpp:267
memory
domain::creators::BinaryCompactObject::InitialGridPoints
Definition: BinaryCompactObject.hpp:312
domain::creators::BinaryCompactObject::UseLogarithmicMapOuterSphericalShell
Definition: BinaryCompactObject.hpp:324
Options::Auto
A class indicating that a parsed value can be automatically computed instead of specified.
Definition: Auto.hpp:33
domain::creators::BinaryCompactObject::Excision
Options for an excision region in the domain.
Definition: BinaryCompactObject.hpp:146
DomainCreator
Base class for creating Domains from an option string.
Definition: DomainCreator.hpp:88
domain::creators::BinaryCompactObject::TimeDependence
Definition: BinaryCompactObject.hpp:345
domain::creators::BinaryCompactObject::Object::Interior
Definition: BinaryCompactObject.hpp:187
domain::CoordinateMaps::Identity
Definition: Identity.hpp:28
domain::creators::BinaryCompactObject::Object::AdditionToRadialRefinementLevel
Definition: BinaryCompactObject.hpp:205
domain::CoordinateMaps::Frustum
A reorientable map from the cube to a frustum.
Definition: Frustum.hpp:164
Options::String
const char *const String
The string used in option structs.
Definition: Options.hpp:32
Frame
Definition: IndexType.hpp:36
domain::creators::BinaryCompactObject::AdditionToOuterLayerRadialRefinementLevel
Definition: BinaryCompactObject.hpp:333
domain::creators::BinaryCompactObject::Object::XCoord
Definition: BinaryCompactObject.hpp:183
domain::creators::BinaryCompactObject::ObjectB
Definition: BinaryCompactObject.hpp:274
Frame::Logical
Definition: IndexType.hpp:42
optional
domain::creators::BinaryCompactObject::Object::ExciseInterior
Definition: BinaryCompactObject.hpp:194
DomainCreator.hpp
std::unique_ptr
unordered_map
domain::creators::BinaryCompactObject::Object::OuterRadius
Definition: BinaryCompactObject.hpp:177
TMPL.hpp
domain::creators::BinaryCompactObject::Object::is_excised
bool is_excised() const noexcept
Whether or not the object should be excised from the domain, leaving a spherical hole....
domain::creators::BinaryCompactObject::Object::InnerRadius
Definition: BinaryCompactObject.hpp:171
domain::CoordinateMaps::Wedge
Map from a square or cube to a wedge.
Definition: Wedge.hpp:247
domain::CoordinateMap
A coordinate map or composition of coordinate maps.
Definition: CoordinateMap.hpp:240
string