SpECTRE Documentation Coverage Report
Current view: top level - Domain/Creators/TimeDependence - Shape.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 21.5 % 65 14
Test Date: 2026-10-22 17:29:42
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 <unordered_map>
      13              : #include <vector>
      14              : 
      15              : #include "Domain/CoordinateMaps/CoordinateMap.hpp"
      16              : #include "Domain/CoordinateMaps/Identity.hpp"
      17              : #include "Domain/CoordinateMaps/TimeDependent/Shape.hpp"
      18              : #include "Domain/Creators/TimeDependence/GenerateCoordinateMap.hpp"
      19              : #include "Domain/Creators/TimeDependence/TimeDependence.hpp"
      20              : #include "Domain/Structure/ObjectLabel.hpp"
      21              : #include "Options/Auto.hpp"
      22              : #include "Options/Context.hpp"
      23              : #include "Options/String.hpp"
      24              : #include "Utilities/ErrorHandling/Assert.hpp"
      25              : #include "Utilities/GetOutput.hpp"
      26              : #include "Utilities/TMPL.hpp"
      27              : 
      28              : /// \cond
      29              : namespace domain::FunctionsOfTime {
      30              : class FunctionOfTime;
      31              : }  // namespace domain::FunctionsOfTime
      32              : namespace domain::CoordinateMaps::TimeDependent {
      33              : class Shape;
      34              : }  // namespace domain::CoordinateMaps::TimeDependent
      35              : namespace domain {
      36              : template <typename SourceFrame, typename TargetFrame, typename... Maps>
      37              : class CoordinateMap;
      38              : }  // namespace domain
      39              : 
      40              : namespace Frame {
      41              : struct Distorted;
      42              : struct Grid;
      43              : struct Inertial;
      44              : }  // namespace Frame
      45              : /// \endcond
      46              : 
      47              : namespace domain::creators::time_dependence {
      48              : /*!
      49              :  * \brief A Shape whose inner surface conforms to a surface of constant
      50              :  * Boyer-Lindquist radius, in Kerr-Schild coordinates as given by
      51              :  * domain::CoordinateMaps::TimeDependent::Shape.
      52              :  *
      53              :  * \details This TimeDependence is suitable for use on a spherical shell,
      54              :  * where LMax is the number of l and m spherical harmonics to use in
      55              :  * approximating the Kerr horizon, of mass `Mass` and spin `Spin`. The value
      56              :  * of the Boyer-Lindquist radius to which the inner surface conforms is given
      57              :  * by the value of `inner_radius`. If the user wants the inner surface of the
      58              :  * Shape to conform to a Kerr horizon for a given mass and spin, `inner_radius`
      59              :  * should be the Boyer-Lindquist radius of the outer horizon.
      60              :  *
      61              :  * The actual shape map that is applied will go from the Grid to the Distorted
      62              :  * frame, and then an identity map will go from the Distorted to Inertial frame.
      63              :  * The reasoning behind this is because in basically all use cases (BBH), the
      64              :  * shape map will go to the Distorted frame only and other maps will go from the
      65              :  * Distorted frame to the Inertial frame.
      66              :  *
      67              :  * \note The quantities stored in the FunctionOfTime are not the
      68              :  * complex spherical-harmonic coefficients \f$\lambda_{lm}(t)\f$, but
      69              :  * instead are the real-valued SPHEREPACK coefficients
      70              :  * \f$a_{lm}(t)\f$ and \f$b_{lm}(t)\f$ used by Spherepack.  The
      71              :  * relationship between these two sets of coefficients is
      72              :  * \f{align}
      73              :  * a_{l0} & = \sqrt{\frac{2}{\pi}}\lambda_{l0}&\qquad l\geq 0,\\
      74              :  * a_{lm} & = (-1)^m\sqrt{\frac{2}{\pi}} \mathrm{Re}(\lambda_{lm})
      75              :  * &\qquad l\geq 1, m\geq 1, \\
      76              :  * b_{lm} & = (-1)^m\sqrt{\frac{2}{\pi}} \mathrm{Im}(\lambda_{lm})
      77              :  * &\qquad l\geq 1, m\geq 1.
      78              :  * \f}
      79              :  * See domain::CoordinateMaps::TimeDependent::Shape for more details.
      80              :  *
      81              :  * \note To use this time dependence with the `control_system::system::Shape`
      82              :  * control system, you must choose the same \tparam Label that the control
      83              :  * system is using.
      84              :  */
      85              : template <domain::ObjectLabel Label>
      86            1 : class Shape final : public TimeDependence<3> {
      87              :  private:
      88            0 :   using ShapeMap = domain::CoordinateMaps::TimeDependent::Shape;
      89            0 :   using Identity = domain::CoordinateMaps::Identity<3>;
      90            0 :   using GridToInertialMap =
      91              :       detail::generate_coordinate_map_t<Frame::Grid, Frame::Inertial,
      92              :                                         tmpl::list<ShapeMap>>;
      93            0 :   using GridToDistortedMap =
      94              :       detail::generate_coordinate_map_t<Frame::Grid, Frame::Distorted,
      95              :                                         tmpl::list<ShapeMap>>;
      96            0 :   using DistortedToInertialMap =
      97              :       detail::generate_coordinate_map_t<Frame::Distorted, Frame::Inertial,
      98              :                                         tmpl::list<Identity>>;
      99              : 
     100              :  public:
     101            0 :   using maps_list = tmpl::list<
     102              :       domain::CoordinateMap<Frame::Grid, Frame::Inertial, ShapeMap>,
     103              :       domain::CoordinateMap<Frame::Grid, Frame::Distorted, ShapeMap>,
     104              :       domain::CoordinateMap<Frame::Distorted, Frame::Inertial, Identity>>;
     105              : 
     106            0 :   static constexpr size_t mesh_dim = 3;
     107              : 
     108            0 :   static std::string name() { return "Shape"s + get_output(Label); }
     109              : 
     110              :   /// \brief The initial time of the function of time.
     111            1 :   struct InitialTime {
     112            0 :     using type = double;
     113            0 :     static constexpr Options::String help = {
     114              :         "The initial time of the function of time"};
     115              :   };
     116              :   /// \brief The max angular resolution `l` of the Shape.
     117            1 :   struct LMax {
     118            0 :     using type = size_t;
     119            0 :     static constexpr Options::String help = {
     120              :         "The max l value of the Ylms used by the Shape map."};
     121              :   };
     122              :   /// \brief The mass of the Kerr black hole.
     123            1 :   struct Mass {
     124            0 :     using type = double;
     125            0 :     static constexpr Options::String help = {"The mass of the Kerr BH."};
     126              :   };
     127              :   /// \brief The dimensionless spin of the Kerr black hole.
     128            1 :   struct Spin {
     129            0 :     using type = std::array<double, 3>;
     130            0 :     static constexpr Options::String help = {
     131              :         "The dim'less spin of the Kerr BH."};
     132              :   };
     133              :   /// \brief Center for the Shape map
     134            1 :   struct Center {
     135            0 :     using type = std::array<double, 3>;
     136            0 :     static constexpr Options::String help = {"Center for the Shape map."};
     137              :   };
     138              :   /// \brief Coefficients below this absolute value will be truncated from the
     139              :   /// Shape map.
     140            1 :   struct CoefficientTruncationLimit {
     141            0 :     using type = double;
     142            0 :     static constexpr Options::String help = {
     143              :         "Coefficients below this absolute value will be truncated from the "
     144              :         "Shape map. Set to 0.0 to disable truncation."};
     145            0 :     static constexpr type default_value = 0.0;
     146              :   };
     147              :   /// \brief The inner radius of the Shape map, the radius at which
     148              :   /// to begin applying the map.
     149            1 :   struct InnerRadius {
     150            0 :     using type = double;
     151            0 :     static constexpr Options::String help = {
     152              :         "The inner radius of the Shape map."};
     153              :   };
     154              :   /// \brief The outer radius of the Shape map, beyond which
     155              :   /// it is no longer applied.
     156            1 :   struct OuterRadius {
     157            0 :     using type = double;
     158            0 :     static constexpr Options::String help = {
     159              :         "The outer radius of the Shape map."};
     160              :   };
     161              : 
     162            0 :   using options =
     163              :       tmpl::list<InitialTime, LMax, Mass, Spin, Center,
     164              :                  CoefficientTruncationLimit, InnerRadius, OuterRadius>;
     165              : 
     166            0 :   static constexpr Options::String help = {
     167              :       "Creates a Shape that conforms to a Kerr horizon of given mass and "
     168              :       "spin."};
     169              : 
     170            0 :   Shape() = default;
     171            0 :   ~Shape() override = default;
     172            0 :   Shape(const Shape&) = delete;
     173            0 :   Shape(Shape&&) = default;
     174            0 :   Shape& operator=(const Shape&) = delete;
     175            0 :   Shape& operator=(Shape&&) = default;
     176              : 
     177            0 :   Shape(double initial_time, size_t l_max, double mass,
     178              :         std::array<double, 3> spin, std::array<double, 3> center,
     179              :         double coefficient_truncation_limit, double inner_radius,
     180              :         double outer_radius, const Options::Context& context = {});
     181              : 
     182            1 :   auto get_clone() const -> std::unique_ptr<TimeDependence<mesh_dim>> override;
     183              : 
     184            1 :   auto block_maps_grid_to_inertial(size_t number_of_blocks) const
     185              :       -> std::vector<std::unique_ptr<domain::CoordinateMapBase<
     186              :           Frame::Grid, Frame::Inertial, mesh_dim>>> override;
     187              : 
     188            1 :   auto block_maps_grid_to_distorted(size_t number_of_blocks) const
     189              :       -> std::vector<std::unique_ptr<domain::CoordinateMapBase<
     190              :           Frame::Grid, Frame::Distorted, mesh_dim>>> override;
     191              : 
     192            1 :   auto block_maps_distorted_to_inertial(size_t number_of_blocks) const
     193              :       -> std::vector<std::unique_ptr<domain::CoordinateMapBase<
     194              :           Frame::Distorted, Frame::Inertial, mesh_dim>>> override;
     195              : 
     196            1 :   auto functions_of_time(const std::unordered_map<std::string, double>&
     197              :                              initial_expiration_times = {}) const
     198              :       -> std::unordered_map<
     199              :           std::string,
     200              :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
     201              : 
     202              :  private:
     203              :   template <domain::ObjectLabel OtherLabel>
     204              :   // NOLINTNEXTLINE(readability-redundant-declaration)
     205            0 :   friend bool operator==(const Shape<OtherLabel>& lhs,
     206              :                          const Shape<OtherLabel>& rhs);
     207              : 
     208            0 :   using TransitionFunction = domain::CoordinateMaps::
     209              :       ShapeMapTransitionFunctions::ShapeMapTransitionFunction;
     210              : 
     211            0 :   GridToInertialMap grid_to_inertial_map() const;
     212            0 :   GridToDistortedMap grid_to_distorted_map() const;
     213            0 :   static DistortedToInertialMap distorted_to_inertial_map();
     214              : 
     215            0 :   double initial_time_{std::numeric_limits<double>::signaling_NaN()};
     216            0 :   size_t l_max_{2};
     217            0 :   double mass_{std::numeric_limits<double>::signaling_NaN()};
     218            0 :   std::array<double, 3> spin_{
     219              :       make_array<3>(std::numeric_limits<double>::signaling_NaN())};
     220            0 :   std::array<double, 3> center_{
     221              :       make_array<3>(std::numeric_limits<double>::signaling_NaN())};
     222            0 :   inline static const std::string function_of_time_name_{"Shape" +
     223              :                                                          get_output(Label)};
     224            0 :   double coefficient_truncation_limit_{0.0};
     225            0 :   double inner_radius_{std::numeric_limits<double>::signaling_NaN()};
     226            0 :   double outer_radius_{std::numeric_limits<double>::signaling_NaN()};
     227            0 :   std::unique_ptr<TransitionFunction> transition_func_;
     228              : };
     229              : 
     230              : template <domain::ObjectLabel Label>
     231            0 : bool operator!=(const Shape<Label>& lhs, const Shape<Label>& rhs);
     232              : }  // namespace domain::creators::time_dependence
        

Generated by: LCOV version 2.0-1