SpECTRE Documentation Coverage Report
Current view: top level - Domain/Creators - BinaryNeutronStars.hpp Coverage Total Hit
Commit: a37d7b3c1803b88b537d2aef1c27ca5e6b499398 Lines: 23.8 % 126 30
Test Date: 2026-11-12 04:47:19
Legend: Lines:     hit not hit

            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 <memory>
       9              : #include <optional>
      10              : #include <string>
      11              : #include <unordered_map>
      12              : #include <unordered_set>
      13              : #include <variant>
      14              : #include <vector>
      15              : 
      16              : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
      17              : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp"
      18              : #include "Domain/CoordinateMaps/Affine.hpp"
      19              : #include "Domain/CoordinateMaps/CoordinateMap.hpp"
      20              : #include "Domain/CoordinateMaps/CylindricalFlatEndcapInterior.hpp"
      21              : #include "Domain/CoordinateMaps/CylindricalSphericalShell.hpp"
      22              : #include "Domain/CoordinateMaps/DiscreteRotation.hpp"
      23              : #include "Domain/CoordinateMaps/FlatOffsetWedge.hpp"
      24              : #include "Domain/CoordinateMaps/Identity.hpp"
      25              : #include "Domain/CoordinateMaps/Interval.hpp"
      26              : #include "Domain/CoordinateMaps/PolarToCartesian.hpp"
      27              : #include "Domain/CoordinateMaps/ProductMaps.hpp"
      28              : #include "Domain/CoordinateMaps/SphericalToCartesianPfaffian.hpp"
      29              : #include "Domain/CoordinateMaps/UniformCylindricalSide.hpp"
      30              : #include "Domain/CoordinateMaps/Wedge.hpp"
      31              : #include "Domain/Creators/DomainCreator.hpp"
      32              : #include "Domain/Creators/TimeDependentOptions/BinaryCompactObject.hpp"
      33              : #include "Domain/Domain.hpp"
      34              : #include "Domain/Structure/DirectionMap.hpp"
      35              : #include "Options/Auto.hpp"
      36              : #include "Options/Context.hpp"
      37              : #include "Options/String.hpp"
      38              : #include "Utilities/TMPL.hpp"
      39              : 
      40              : /// \cond
      41              : namespace domain::FunctionsOfTime {
      42              : class FunctionOfTime;
      43              : }  // namespace domain::FunctionsOfTime
      44              : 
      45              : namespace Frame {
      46              : struct Grid;
      47              : struct Distorted;
      48              : struct Inertial;
      49              : struct BlockLogical;
      50              : }  // namespace Frame
      51              : /// \endcond
      52              : 
      53              : namespace domain::creators {
      54              : 
      55              : /*!
      56              :  * \ingroup ComputationalDomainGroup
      57              :  *
      58              :  * \brief A domain for a binary of two filled (non-excised) objects, such as
      59              :  * two neutron stars.
      60              :  *
      61              :  * \image html BinaryNeutronStars.png "Domain with bulge set to true or false."
      62              :  *
      63              :  * \details The `XAxisPoints` option gives four \f$x\f$-coordinates
      64              :  * [\f$x_{\rm left}\f$, \f$x_B\f$, \f$x_A\f$, \f$x_{\rm right}\f$]. If doing
      65              :  * subcell, ideally these value plus \f$x=0\f$ would be equally spaced, with
      66              :  * the object centers lying on the \f$x\f$-axis at \f$x_A\f$ and \f$x_B\f$,
      67              :  * with \f$x_B < 0 < x_A\f$. The cubed cylinders extend from \f$x_{\rm left} <
      68              :  * x_B\f$ to \f$x_{\rm right} > x_A\f$. The  domain has three layers, from the
      69              :  * inside out:
      70              :  *
      71              :  * 1. **Cubed cylinders.** Four groups of five blocks each surround the
      72              :  *    \f$x\f$-axis out to `WedgeOuterRadius` (see `Bulge` below for the shape
      73              :  *    of their outer faces). From left to right, the groups (`BLeft`,
      74              :  *    `BRight`, `ALeft`, `ARight`) span \f$x\f$ in
      75              :  *    [\f$x_{\rm left}\f$, \f$x_B\f$], [\f$x_B\f$, 0], [0, \f$x_A\f$], and
      76              :  *    [\f$x_A\f$, \f$x_{\rm right}\f$]. Each group
      77              :  *    has a central cube with half-width `WedgeInnerRadius`\f$/\sqrt{2}\f$ in
      78              :  *    \f$y\f$ and \f$z\f$ (so its edges lie at radius `WedgeInnerRadius` from
      79              :  *    the \f$x\f$-axis) and four deformed-cube wedges around it.
      80              :  * 2. **Cylinders.** A hollow cylinder surrounds each of the four cubed-cylinder
      81              :  *    groups, and a filled cylinder (with a ZernikeB2 cross-section) caps each
      82              :  *    end, at \f$x = x_{\rm left}\f$ and \f$x = x_{\rm right}\f$. The outer
      83              :  *    faces of these six blocks together form a sphere of radius
      84              :  *    `CylinderOuterRadius` centered at the origin.
      85              :  * 3. **Spherical shells.** One or more spherical shells extend from
      86              :  *    `CylinderOuterRadius` to `OuterRadius`. The number of shells is set by
      87              :  *    `SphericalShellsRadialPartitioning`.
      88              :  *
      89              :  * The interfaces between the cubed cylinders and the cylinders, and between
      90              :  * the cylinders and the innermost spherical shell, are non-conforming.
      91              :  *
      92              :  * The `Bulge` option selects the maps for the deformed-cube wedges and the
      93              :  * hollow cylinders. When `false`, the wedges are extruded 2D wedges, so their
      94              :  * outer faces lie on a circular cylinder of radius `WedgeOuterRadius`. When
      95              :  * `true`, the wedges use FlatOffsetWedge maps whose outer faces lie on spheres
      96              :  * centered on each object. The sphere around the object farther from the
      97              :  * origin has radius `WedgeOuterRadius`, and the radius of the other sphere is
      98              :  * chosen so that the two spheres meet the \f$x = 0\f$ plane in the same
      99              :  * circle.
     100              :  *
     101              :  * Time-dependent maps (expansion, rotation, and translation) are supported
     102              :  * through `TimeDependentMaps`. Shape maps are not supported, because there are
     103              :  * no excision surfaces. The time-dependent maps are a `RotScaleTrans` map
     104              :  * centered at the origin. All blocks inside `CylinderOuterRadius` are mapped
     105              :  * rigidly. In the spherical shells the expansion transitions to
     106              :  * `ExpansionOuterBoundary` and the translation falls off to zero at
     107              :  * `OuterRadius`, while the rotation is applied everywhere.
     108              :  */
     109            1 : class BinaryNeutronStars : public DomainCreator<3> {
     110              :  public:
     111            0 :   using maps_list = tmpl::flatten<tmpl::list<
     112              :       // Central cubes (blocks 0, 5, 10, 15): Affine3D
     113              :       domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
     114              :                             CoordinateMaps::ProductOf3Maps<
     115              :                                 CoordinateMaps::Affine, CoordinateMaps::Affine,
     116              :                                 CoordinateMaps::Affine>>,
     117              :       // Bulge=false: Wedge prisms (blocks 1-4, 6-9, 11-14, 16-19):
     118              :       // Wedge<2> x Affine + rotation to final orientation
     119              :       domain::CoordinateMap<
     120              :           Frame::BlockLogical, Frame::Inertial,
     121              :           CoordinateMaps::ProductOf2Maps<CoordinateMaps::Wedge<2>,
     122              :                                          CoordinateMaps::Affine>,
     123              :           CoordinateMaps::DiscreteRotation<3>>,
     124              :       // Bulge=true: ALeft/BLeft FOW blocks: FOW + ShiftX + Rotation
     125              :       domain::CoordinateMap<
     126              :           Frame::BlockLogical, Frame::Inertial, CoordinateMaps::FlatOffsetWedge,
     127              :           CoordinateMaps::ProductOf3Maps<CoordinateMaps::Affine,
     128              :                                          CoordinateMaps::Identity<1>,
     129              :                                          CoordinateMaps::Identity<1>>,
     130              :           CoordinateMaps::DiscreteRotation<3>>,
     131              :       // Bulge=true: BRight FOW blocks: FOW + Rotation
     132              :       domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
     133              :                             CoordinateMaps::FlatOffsetWedge,
     134              :                             CoordinateMaps::DiscreteRotation<3>>,
     135              :       // Bulge=true: ARight FOW blocks:
     136              :       // FOW + Rotation + ShiftX + Rotation
     137              :       domain::CoordinateMap<
     138              :           Frame::BlockLogical, Frame::Inertial, CoordinateMaps::FlatOffsetWedge,
     139              :           CoordinateMaps::DiscreteRotation<3>,
     140              :           CoordinateMaps::ProductOf3Maps<CoordinateMaps::Affine,
     141              :                                          CoordinateMaps::Identity<1>,
     142              :                                          CoordinateMaps::Identity<1>>,
     143              :           CoordinateMaps::DiscreteRotation<3>>,
     144              :       // Filled cylinders (blocks 20, 25): radial Affine +
     145              :       // polar-to-Cartesian + half-turn + interior endcap + rotation to
     146              :       // x-axis + rotation to align angle
     147              :       domain::CoordinateMap<
     148              :           Frame::BlockLogical, Frame::Inertial,
     149              :           CoordinateMaps::ProductOf3Maps<CoordinateMaps::Affine,
     150              :                                          CoordinateMaps::Identity<1>,
     151              :                                          CoordinateMaps::Identity<1>>,
     152              :           CoordinateMaps::ProductOf2Maps<CoordinateMaps::PolarToCartesian,
     153              :                                          CoordinateMaps::Identity<1>>,
     154              :           CoordinateMaps::DiscreteRotation<3>,
     155              :           CoordinateMaps::CylindricalFlatEndcapInterior,
     156              :           CoordinateMaps::DiscreteRotation<3>>,
     157              :       // Hollow cylinders (blocks 21-24): bulge = false
     158              :       domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
     159              :                             CoordinateMaps::CylindricalSphericalShell,
     160              :                             CoordinateMaps::DiscreteRotation<3>>,
     161              :       // Hollow cylinders (blocks 21-24): bulge = true
     162              :       domain::CoordinateMap<
     163              :           Frame::BlockLogical, Frame::Inertial,
     164              :           CoordinateMaps::ProductOf3Maps<CoordinateMaps::Affine,
     165              :                                          CoordinateMaps::Identity<1>,
     166              :                                          CoordinateMaps::Identity<1>>,
     167              :           CoordinateMaps::ProductOf2Maps<CoordinateMaps::PolarToCartesian,
     168              :                                          CoordinateMaps::Identity<1>>,
     169              :           CoordinateMaps::DiscreteRotation<3>,
     170              :           CoordinateMaps::UniformCylindricalSide,
     171              :           CoordinateMaps::DiscreteRotation<3>>,
     172              :       // Spherical shells (blocks 26 and up): radial Interval + S2
     173              :       domain::CoordinateMap<
     174              :           Frame::BlockLogical, Frame::Inertial,
     175              :           CoordinateMaps::ProductOf2Maps<CoordinateMaps::Interval,
     176              :                                          CoordinateMaps::Identity<2>>,
     177              :           CoordinateMaps::SphericalToCartesianPfaffian>,
     178              :       bco::TimeDependentMapOptions<true>::maps_list>>;
     179              : 
     180              :   /*!
     181              :    * \brief Grid \f$x\f$-coordinates of the ends of the cubed cylinders and the
     182              :    * centers of the objects
     183              :    *
     184              :    * Given in ascending order as [\f$x_{\rm left}\f$, \f$x_B\f$, \f$x_A\f$,
     185              :    * \f$x_{\rm right}\f$], where \f$x_{\rm left}\f$ and \f$x_{\rm right}\f$
     186              :    * are the left and right faces of the cubed cylinders and \f$x_B\f$ and
     187              :    * \f$x_A\f$ are the centers of Objects B and A. Must satisfy
     188              :    * \f$x_{\rm left} < x_B < 0 < x_A < x_{\rm right}\f$.
     189              :    */
     190            1 :   struct XAxisPoints {
     191            0 :     using type = std::array<double, 4>;
     192            0 :     static constexpr Options::String help = {
     193              :         "Grid x-coordinates [LeftEnd, CenterB, CenterA, RightEnd] in ascending "
     194              :         "order: the left face of the cubed cylinders, the centers of Objects B "
     195              :         "and A, and the right face of the cubed cylinders. Must satisfy "
     196              :         "LeftEnd < CenterB < 0 < CenterA < RightEnd."};
     197              :   };
     198              :   /*!
     199              :    * \brief Grid-coordinate distance from the \f$x\f$-axis to the edges of the
     200              :    * central cubes, which is also the inner radius of the deformed-cube wedges
     201              :    *
     202              :    * The central cubes have half-width WedgeInnerRadius\f$/\sqrt{2}\f$ in
     203              :    * \f$y\f$ and \f$z\f$.
     204              :    */
     205            1 :   struct WedgeInnerRadius {
     206            0 :     using type = double;
     207            0 :     static constexpr Options::String help = {
     208              :         "Grid-coordinate distance from the x-axis to the edges of the central "
     209              :         "cubes. The cubes have half-width WedgeInnerRadius/sqrt(2) in y and "
     210              :         "z."};
     211              :   };
     212              :   /*!
     213              :    * \brief Grid-coordinate radius of the outer faces of the deformed-cube
     214              :    * wedges
     215              :    *
     216              :    * With `Bulge: false` this is the radius of the cylinder about the
     217              :    * \f$x\f$-axis. With `Bulge: true` this is the radius of the sphere
     218              :    * centered on the object farther from the origin; the radius of the sphere
     219              :    * centered on the other object is adjusted so that the two spheres meet at
     220              :    * \f$x = 0\f$.
     221              :    */
     222            1 :   struct WedgeOuterRadius {
     223            0 :     using type = double;
     224            0 :     static constexpr Options::String help = {
     225              :         "Grid-coordinate radius of the outer faces of the deformed-cube wedges "
     226              :         "around the central cubes. With Bulge=false this is a cylinder about "
     227              :         "the x-axis. With Bulge=true this is a sphere centered on the object "
     228              :         "farther from the origin (the sphere around the other object is "
     229              :         "adjusted to meet it at x=0)."};
     230              :   };
     231              :   /*!
     232              :    * \brief Grid-coordinate radius of the sphere, centered at the origin,
     233              :    * formed by the outer faces of the cylinders
     234              :    *
     235              :    * This is also the inner radius of the innermost spherical shell.
     236              :    */
     237            1 :   struct CylinderOuterRadius {
     238            0 :     using type = double;
     239            0 :     static constexpr Options::String help = {
     240              :         "Grid-coordinate radius of the sphere, centered at the origin, formed "
     241              :         "by the outer faces of the filled and hollow cylinders. This is also "
     242              :         "the inner radius of the spherical shells."};
     243              :   };
     244              :   /*!
     245              :    * \brief Grid-coordinate radius of the outer boundary of the domain
     246              :    */
     247            1 :   struct OuterRadius {
     248            0 :     using type = double;
     249            0 :     static constexpr Options::String help = {
     250              :         "Grid-coordinate radius for outer boundary of spherical shells."};
     251              :   };
     252              : 
     253              :   /*!
     254              :    * \brief Initial number of grid points for each cubed-cylinder group
     255              :    *
     256              :    * One entry per group, ordered [BLeft, BRight, ALeft, ARight], or a single
     257              :    * value used for all groups. This sets the grid points in all three
     258              :    * directions of the central cube, and in the directions tangent to the outer
     259              :    * face of the four surrounding deformed-cube wedges.
     260              :    */
     261            1 :   struct CubeInitialGridPoints {
     262            0 :     using type = std::variant<size_t, std::array<size_t, 4>>;
     263            0 :     static constexpr Options::String help = {
     264              :         "Initial number of grid points for each cubed-cylinder group, ordered "
     265              :         "[BLeft, BRight, ALeft, ARight], or a single value used for all "
     266              :         "groups. Sets all directions of the central cube and the directions "
     267              :         "tangent to the outer face of the surrounding deformed-cube wedges."};
     268              :   };
     269              :   /*!
     270              :    * \brief Initial \f$x\f$ refinement for each cubed-cylinder group
     271              :    *
     272              :    * One entry per group, ordered [BLeft, BRight, ALeft, ARight], or a single
     273              :    * value used for all groups. This sets the \f$x\f$ refinement of both the
     274              :    * central cube and the four surrounding deformed-cube wedges.
     275              :    */
     276            1 :   struct CubeInitialXRefinement {
     277            0 :     using type = std::variant<size_t, std::array<size_t, 4>>;
     278            0 :     static constexpr Options::String help = {
     279              :         "Initial x refinement for each cubed-cylinder group, ordered [BLeft, "
     280              :         "BRight, ALeft, ARight], or a single value used for all groups. "
     281              :         "Applies to both the central cube and the surrounding deformed-cube "
     282              :         "wedges."};
     283              :   };
     284              :   /*!
     285              :    * \brief Initial \f$y\f$ and \f$z\f$ refinement for each cubed-cylinder
     286              :    * group
     287              :    *
     288              :    * One entry per group, ordered [BLeft, BRight, ALeft, ARight], or a single
     289              :    * value used for all groups. This sets the \f$y\f$ and \f$z\f$ refinement
     290              :    * of the central cube and the angular refinement of the four surrounding
     291              :    * deformed-cube wedges.
     292              :    */
     293            1 :   struct CubeInitialYZRefinement {
     294            0 :     using type = std::variant<size_t, std::array<size_t, 4>>;
     295            0 :     static constexpr Options::String help = {
     296              :         "Initial y/z refinement for each cubed-cylinder group, ordered [BLeft, "
     297              :         "BRight, ALeft, ARight], or a single value used for all groups. "
     298              :         "Applies to the central cube and to the angular direction of the "
     299              :         "surrounding deformed-cube wedges."};
     300              :   };
     301              :   /*!
     302              :    * \brief Initial number of radial grid points for the deformed-cube wedges
     303              :    */
     304            1 :   struct WedgePrismInitialRadialGridPoints {
     305            0 :     using type = size_t;
     306            0 :     static constexpr Options::String help = {
     307              :         "Initial number of radial grid points for the deformed-cube wedges "
     308              :         "surrounding the central cubes."};
     309              :   };
     310              :   /*!
     311              :    * \brief Initial radial refinement for the deformed-cube wedges
     312              :    */
     313            1 :   struct WedgePrismInitialRadialRefinement {
     314            0 :     using type = size_t;
     315            0 :     static constexpr Options::String help = {
     316              :         "Initial radial refinement for the deformed-cube wedges surrounding "
     317              :         "the central cubes."};
     318              :   };
     319              :   /*!
     320              :    * \brief Initial number of grid points for the filled and hollow cylinders
     321              :    * in the direction from the cubed cylinders out to `CylinderOuterRadius`
     322              :    *
     323              :    * For the hollow cylinders this is the radial direction. For the filled
     324              :    * cylinders this is the axial direction, from the flat face at
     325              :    * \f$x_{\rm left}\f$/\f$x_{\rm right}\f$ (see `XAxisPoints`) to the outer
     326              :    * sphere.
     327              :    */
     328            1 :   struct CylinderInitialRadialGridPoints {
     329            0 :     using type = size_t;
     330            0 :     static constexpr Options::String help = {
     331              :         "Initial number of grid points for the cylinders in the direction from "
     332              :         "the cubed cylinders out to CylinderOuterRadius (radial for the hollow "
     333              :         "cylinders, axial for the filled cylinders)."};
     334              :   };
     335              :   /*!
     336              :    * \brief Initial refinement for the filled and hollow cylinders in the
     337              :    * direction from the cubed cylinders out to `CylinderOuterRadius`
     338              :    *
     339              :    * See `CylinderInitialRadialGridPoints` for which logical direction this is.
     340              :    */
     341            1 :   struct CylinderInitialRadialRefinement {
     342            0 :     using type = size_t;
     343            0 :     static constexpr Options::String help = {
     344              :         "Initial refinement for the cylinders in the direction from the cubed "
     345              :         "cylinders out to CylinderOuterRadius (radial for the hollow "
     346              :         "cylinders, axial for the filled cylinders)."};
     347              :   };
     348              :   /*!
     349              :    * \brief Initial number of angular grid points for the ZernikeB2
     350              :    * cross-section of the filled cylinders
     351              :    *
     352              :    * Must be odd. The number of radial grid points in the cross-section is
     353              :    * derived from this so that the radial and angular modal spaces match. The
     354              :    * cross-section cannot be h-refined.
     355              :    */
     356            1 :   struct B2InitialAngularGridPoints {
     357            0 :     using type = size_t;
     358            0 :     static constexpr Options::String help = {
     359              :         "Initial number of angular grid points for the ZernikeB2 cross-section "
     360              :         "of the filled cylinders. Must be odd. The radial grid points of the "
     361              :         "cross-section are derived from this."};
     362              :   };
     363              :   /*!
     364              :    * \brief Initial number of grid points for the hollow cylinders in the
     365              :    * angular and axial directions
     366              :    *
     367              :    * Passed as logical [eta, zeta], where eta is the angle about the
     368              :    * \f$x\f$-axis (must be odd) and zeta is the axial direction. Neither
     369              :    * direction is h-refined.
     370              :    */
     371            1 :   struct HollowCylinderInitialAngularGridPoints {
     372            0 :     using type = std::array<size_t, 2>;
     373            0 :     static constexpr Options::String help = {
     374              :         "Initial number of grid points for the hollow cylinders, passed as "
     375              :         "logical [eta, zeta]: eta is the angle about the x-axis (must be odd) "
     376              :         "and zeta is the axial direction."};
     377              :   };
     378              :   /*!
     379              :    * \brief Initial radial refinement of spherical shells
     380              :    */
     381            1 :   struct SphericalShellsInitialRadialRefinement {
     382            0 :     using type = std::variant<size_t, std::vector<size_t>>;
     383            0 :     static constexpr Options::String help = {
     384              :         "Initial radial refinement for spherical shells. There must be N+1 "
     385              :         "refinement levels specified for N radial partitions. You can also "
     386              :         "specify just a single refinement level (not in a vector) which will "
     387              :         "be used for all shells."};
     388              :   };
     389              :   /*!
     390              :    * \brief Initial number of radial grid points for spherical shells
     391              :    */
     392            1 :   struct SphericalShellsInitialRadialGridPoints {
     393            0 :     using type = size_t;
     394            0 :     static constexpr Options::String help = {
     395              :         "Initial number of radial grid points for spherical shells."};
     396              :   };
     397              :   /*!
     398              :    * \brief Initial spherical harmonic resolution for spherical shells
     399              :    */
     400            1 :   struct InitialSphericalHarmonicL {
     401            0 :     using type = size_t;
     402            0 :     static size_t lower_bound() { return 6; }
     403            0 :     static constexpr Options::String help = {
     404              :         "Initial spherical harmonic resolution specified as the highest "
     405              :         "spherical harmonic represented on the grid.  Minimum value is 6."};
     406              :   };
     407              :   /*!
     408              :    * \brief Radial partitioning of the spherical shell region
     409              :    */
     410            1 :   struct SphericalShellsRadialPartitioning {
     411            0 :     using type = std::vector<double>;
     412            0 :     static constexpr Options::String help = {
     413              :         "Radial coordinates of the boundaries splitting the spherical-shell "
     414              :         "region between CylinderOuterRadius and OuterRadius into multiple "
     415              :         "shells. Must be given in ascending order, strictly between "
     416              :         "CylinderOuterRadius and OuterRadius."};
     417              :   };
     418              :   /*!
     419              :    * \brief Radial distribution for spherical shells
     420              :    */
     421            1 :   struct SphericalShellsRadialDistribution {
     422            0 :     using type =
     423              :         std::variant<domain::CoordinateMaps::Distribution,
     424              :                      std::vector<domain::CoordinateMaps::Distribution>>;
     425            0 :     static constexpr Options::String help = {
     426              :         "Select the radial distribution of grid points in each spherical "
     427              :         "shell. There must be N+1 radial distributions specified for N "
     428              :         "radial partitions. You can also specify just a single radial "
     429              :         "distribution (not in a vector) which will use the same "
     430              :         "distribution for all shells."};
     431              :   };
     432              : 
     433              :   /*!
     434              :    * \brief Whether to use bulging coordinate maps for the deformed-cube wedges
     435              :    * and the hollow cylinders
     436              :    *
     437              :    * When `true`, uses `FlatOffsetWedge` for the deformed-cube wedges, whose
     438              :    * outer faces lie on spheres centered on each object, and
     439              :    * `UniformCylindricalSide` for the hollow cylinders. When `false`, uses
     440              :    * extruded 2D `Wedge`s, whose outer faces lie on a cylinder about the
     441              :    * \f$x\f$-axis, and `CylindricalSphericalShell` for the hollow cylinders.
     442              :    */
     443            1 :   struct Bulge {
     444            0 :     using type = bool;
     445            0 :     static constexpr Options::String help = {
     446              :         "If true, the outer faces of the deformed-cube wedges lie on spheres "
     447              :         "centered on each object (FlatOffsetWedge). If false, they lie on a "
     448              :         "cylinder about the x-axis (extruded 2D Wedge)."};
     449              :   };
     450              : 
     451              :   /*!
     452              :    * \brief Outer boundary condition
     453              :    */
     454              :   template <typename BoundaryConditionsBase>
     455            1 :   struct OuterBoundaryCondition {
     456            0 :     static std::string name() { return "OuterBoundary"; }
     457            0 :     static constexpr Options::String help =
     458              :         "Options for the outer boundary conditions.";
     459            0 :     using type = std::unique_ptr<BoundaryConditionsBase>;
     460              :   };
     461              : 
     462              :   /*!
     463              :    * \brief Time dependent maps
     464              :    */
     465            1 :   struct TimeDependentMaps {
     466            0 :     using type = Options::Auto<bco::TimeDependentMapOptions<true>,
     467              :                                Options::AutoLabel::None>;
     468            0 :     static constexpr Options::String help =
     469              :         bco::TimeDependentMapOptions<true>::help;
     470              :   };
     471              : 
     472              :   template <typename Metavariables>
     473            0 :   using options = tmpl::append<
     474              :       tmpl::list<
     475              :           XAxisPoints, WedgeInnerRadius, WedgeOuterRadius, CylinderOuterRadius,
     476              :           OuterRadius, CubeInitialGridPoints, CubeInitialXRefinement,
     477              :           CubeInitialYZRefinement, WedgePrismInitialRadialGridPoints,
     478              :           WedgePrismInitialRadialRefinement, CylinderInitialRadialGridPoints,
     479              :           CylinderInitialRadialRefinement, B2InitialAngularGridPoints,
     480              :           HollowCylinderInitialAngularGridPoints,
     481              :           SphericalShellsInitialRadialRefinement,
     482              :           SphericalShellsInitialRadialGridPoints, InitialSphericalHarmonicL,
     483              :           SphericalShellsRadialPartitioning, SphericalShellsRadialDistribution,
     484              :           Bulge, TimeDependentMaps>,
     485              :       tmpl::conditional_t<
     486              :           domain::BoundaryConditions::has_boundary_conditions_base_v<
     487              :               typename Metavariables::system>,
     488              :           tmpl::list<OuterBoundaryCondition<
     489              :               domain::BoundaryConditions::get_boundary_conditions_base<
     490              :                   typename Metavariables::system>>>,
     491              :           tmpl::list<>>>;
     492              : 
     493            0 :   static constexpr Options::String help{
     494              :       "A domain for a binary of two filled (non-excised) objects, such as two "
     495              :       "neutron stars, centered on the x-axis. Four cubed cylinders (a central "
     496              :       "cube surrounded by four deformed-cube wedges) span the x-axis between "
     497              :       "the points in XAxisPoints. These are surrounded by four hollow "
     498              :       "cylinders and capped at each end by a filled cylinder, whose outer "
     499              :       "faces together form a sphere of radius CylinderOuterRadius. Spherical "
     500              :       "shells extend from there to OuterRadius. The Bulge option makes the "
     501              :       "outer faces of the deformed-cube wedges spherical instead of "
     502              :       "cylindrical."};
     503              : 
     504            0 :   BinaryNeutronStars(
     505              :       const std::array<double, 4>& x_axis_points, double wedge_inner_radius,
     506              :       double wedge_outer_radius, double cylinder_outer_radius,
     507              :       double outer_radius, const CubeInitialGridPoints::type& cube_grid_points,
     508              :       const CubeInitialXRefinement::type& cube_x_refinement,
     509              :       const CubeInitialYZRefinement::type& cube_yz_refinement,
     510              :       size_t wedge_prism_radial_grid_points,
     511              :       size_t wedge_prism_radial_refinement, size_t cylinder_radial_grid_points,
     512              :       size_t cylinder_radial_refinement, size_t b2_angular_grid_points,
     513              :       std::array<size_t, 2> hollow_cylinder_angular_grid_points,
     514              :       const SphericalShellsInitialRadialRefinement::type&
     515              :           spherical_shells_radial_refinement,
     516              :       size_t spherical_shells_radial_grid_points, size_t spherical_harmonic_l,
     517              :       std::vector<double> spherical_shells_radial_partitioning,
     518              :       const SphericalShellsRadialDistribution::type&
     519              :           spherical_shells_radial_distribution,
     520              :       bool bulge = false,
     521              :       std::optional<bco::TimeDependentMapOptions<true>> time_dependent_options =
     522              :           std::nullopt,
     523              :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     524              :           outer_boundary_condition = nullptr,
     525              :       const Options::Context& context = {});
     526              : 
     527            0 :   BinaryNeutronStars() = default;
     528            0 :   BinaryNeutronStars(const BinaryNeutronStars&) = delete;
     529            0 :   BinaryNeutronStars(BinaryNeutronStars&&) = default;
     530            0 :   BinaryNeutronStars& operator=(const BinaryNeutronStars&) = delete;
     531            0 :   BinaryNeutronStars& operator=(BinaryNeutronStars&&) = default;
     532            0 :   ~BinaryNeutronStars() override = default;
     533              : 
     534            0 :   Domain<3> create_domain() const override;
     535              : 
     536              :   std::unordered_map<std::string, tnsr::I<double, 3, Frame::Grid>>
     537            1 :   grid_anchors() const override {
     538              :     return grid_anchors_;
     539              :   }
     540              : 
     541              :   std::vector<DirectionMap<
     542              :       3, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
     543            1 :   external_boundary_conditions() const override;
     544              : 
     545            1 :   std::vector<std::array<size_t, 3>> initial_extents() const override;
     546              : 
     547            1 :   std::vector<std::array<size_t, 3>> initial_refinement_levels() const override;
     548              : 
     549            1 :   auto functions_of_time(const std::unordered_map<std::string, double>&
     550              :                              initial_expiration_times = {}) const
     551              :       -> std::unordered_map<
     552              :           std::string,
     553              :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
     554              : 
     555              :   /// \brief The block names, which use left/right directionality as from a
     556              :   /// viewer looking down the \f$y\f$-axis.
     557              :   ///
     558              :   /// \details The block names start with the central cubes:
     559              :   ///  - `BLeftCubedCylinderCenter`, `BLeftCubedCylinderFront`,
     560              :   /// `BLeftCubedCylinderTop`, `BLeftCubedCylinderBack`,
     561              :   /// `BLeftCubedCylinderBottom`
     562              :   ///  - `BRightCubedCylinderCenter`, `BRightCubedCylinderFront`, ...
     563              :   ///  - `ALeftCubedCylinderCenter`, ...
     564              :   ///  - `ARightCubedCylinderCenter`, ...
     565              :   ///
     566              :   /// Then there are the cylinders:
     567              :   ///  - `BFilledCylinder`
     568              :   ///  - `BLeftHollowCylinder`
     569              :   ///  - `BRightHollowCylinder`
     570              :   ///  - `ALeftHollowCylinder`
     571              :   ///  - `ARightHollowCylinder`
     572              :   ///  - `AFilledCylinder`
     573              :   ///
     574              :   /// Finally, there are the spherical shells: `SphericalShell0`,
     575              :   /// `SphericalShell1`, etc., one for each radial partition of the region
     576              :   /// between `CylinderOuterRadius` and `OuterRadius`.
     577            1 :   std::vector<std::string> block_names() const override { return block_names_; }
     578              : 
     579              :   /// \brief The block groups, which are `CubedCylinders`, `Wedges`,
     580              :   /// `Cylinders`, and `SphericalShells`. The `Wedges` group is the subset of
     581              :   /// `CubedCylinders` consisting of the deformed cube wedges surrounding the
     582              :   /// central cubes.
     583              :   std::unordered_map<std::string, std::unordered_set<std::string>>
     584            1 :   block_groups() const override {
     585              :     return block_groups_;
     586              :   }
     587              : 
     588              :  private:
     589              :   // Block indices. The 20 cubed-cylinder blocks come first, then the
     590              :   // cylinders, then the spherical shells.
     591            0 :   static constexpr size_t b_filled_cylinder_block = 20;
     592            0 :   static constexpr size_t first_hollow_cylinder_block = 21;
     593            0 :   static constexpr size_t a_filled_cylinder_block = 25;
     594            0 :   static constexpr size_t first_spherical_shell_block = 26;
     595              : 
     596            0 :   double leftmost_x_{};
     597            0 :   double center_B_{};
     598            0 :   double center_A_{};
     599            0 :   double rightmost_x_{};
     600            0 :   double wedge_inner_radius_{};
     601            0 :   double wedge_outer_radius_{};
     602            0 :   double cylinder_outer_radius_{};
     603            0 :   double outer_radius_{};
     604            0 :   std::array<size_t, 4> cube_grid_points_{};
     605            0 :   std::array<size_t, 4> cube_x_refinement_{};
     606            0 :   std::array<size_t, 4> cube_yz_refinement_{};
     607            0 :   size_t wedge_prism_radial_grid_points_{};
     608            0 :   size_t wedge_prism_radial_refinement_{};
     609            0 :   size_t cylinder_radial_grid_points_{};
     610            0 :   size_t cylinder_radial_refinement_{};
     611            0 :   size_t b2_angular_grid_points_{};
     612            0 :   std::array<size_t, 2> hollow_cylinder_angular_grid_points_{};
     613            0 :   std::vector<size_t> spherical_shells_radial_refinement_{};
     614            0 :   size_t spherical_shells_radial_grid_points_{};
     615            0 :   size_t spherical_harmonic_l_{};
     616            0 :   std::vector<double> spherical_shells_radial_partitioning_{};
     617              :   std::vector<domain::CoordinateMaps::Distribution>
     618            0 :       spherical_shells_radial_distribution_{};
     619            0 :   size_t number_of_spherical_shells_{1};
     620            0 :   bool bulge_{};
     621              :   // Radii of the spheres around objects A and B on which the outer faces of
     622              :   // the deformed-cube wedges lie with Bulge=true (both are WedgeOuterRadius
     623              :   // with Bulge=false)
     624            0 :   double bulge_radius_A_{};
     625            0 :   double bulge_radius_B_{};
     626            0 :   size_t number_of_blocks_{};
     627              :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     628            0 :       outer_boundary_condition_;
     629            0 :   std::optional<bco::TimeDependentMapOptions<true>> time_dependent_options_{};
     630            0 :   std::vector<std::string> block_names_{};
     631              :   std::unordered_map<std::string, std::unordered_set<std::string>>
     632            0 :       block_groups_{};
     633              :   std::unordered_map<std::string, tnsr::I<double, 3, Frame::Grid>>
     634            0 :       grid_anchors_{};
     635            0 :   std::vector<std::array<size_t, 3>> initial_refinement_{};
     636            0 :   std::vector<std::array<size_t, 3>> initial_grid_points_{};
     637              : };
     638              : }  // namespace domain::creators
        

Generated by: LCOV version 2.0-1