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

Generated by: LCOV version 1.14