SpECTRE Documentation Coverage Report
Current view: top level - Domain/CoordinateMaps - SpecialMobius.hpp Hit Total Coverage
Commit: ecb8a275e1aebab77dcce48a5e098ed4e486ab4b Lines: 2 23 8.7 %
Date: 2026-08-22 01:05:40
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 <optional>
      10             : 
      11             : #include "DataStructures/Tensor/TypeAliases.hpp"
      12             : 
      13             : /// \cond
      14             : namespace PUP {
      15             : class er;
      16             : }  // namespace PUP
      17             : /// \endcond
      18             : 
      19             : namespace domain {
      20             : namespace CoordinateMaps {
      21             : 
      22             : /*!
      23             :  * \ingroup CoordinateMapsGroup
      24             :  *
      25             :  * \brief Redistributes gridpoints within the unit sphere.
      26             :  * \image html SpecialMobius.png "A sphere with a `mu` of 0.25."
      27             :  *
      28             :  * \details A special case of the conformal Mobius transformation that
      29             :  * maps the unit ball to itself. This map depends on a single
      30             :  * parameter, `mu` \f$ = \mu\f$, which is the x-coordinate of the preimage
      31             :  * of the origin under this map. This map has the fixed points \f$x=1\f$ and
      32             :  * \f$x=-1\f$. The map is singular for \f$\mu=1\f$ but we have found that this
      33             :  * map is accurate up to 12 decimal places for values of \f$\mu\f$ up to 0.96.
      34             :  *
      35             :  * We define the auxiliary variables
      36             :  * \f[ r := \sqrt{x^2 + y^2 +z^2}\f]
      37             :  * and
      38             :  * \f[ \lambda := \frac{1}{1 - 2 x \mu + \mu^2 r^2}\f]
      39             :  *
      40             :  * The map corresponding to this transformation in cartesian coordinates
      41             :  * is then given by:
      42             :  *
      43             :  * \f[\vec{x}'(x,y,z) =
      44             :  * \lambda\begin{bmatrix}
      45             :  * x(1+\mu^2) - \mu(1+r^2)\\
      46             :  * y(1-\mu^2)\\
      47             :  * z(1-\mu^2)\\
      48             :  * \end{bmatrix}\f]
      49             :  *
      50             :  * The inverse map is the same as the forward map with \f$\mu\f$
      51             :  * replaced by \f$-\mu\f$.
      52             :  *
      53             :  * This map is intended to be used only inside the unit sphere.  A
      54             :  * point inside the unit sphere maps to another point inside the unit
      55             :  * sphere. The map can have undesirable behavior at certain points
      56             :  * outside the unit sphere: The map is singular at
      57             :  * \f$(x,y,z) = (1/\mu, 0, 0)\f$ (which is outside the unit sphere
      58             :  * since \f$|\mu| < 1\f$). Moreover, a point on the \f$x\f$-axis
      59             :  * arbitrarily close to the singularity maps to an arbitrarily large
      60             :  * value on the \f$\pm x\f$-axis, where the sign depends on which side
      61             :  * of the singularity the point is on.
      62             :  *
      63             :  * A general Mobius transformation is a function on the complex plane, and
      64             :  * takes the form \f$ f(z) = \frac{az+b}{cz+d}\f$, where
      65             :  * \f$z, a, b, c, d \in \mathbb{C}\f$, and \f$ad-bc\neq 0\f$.
      66             :  *
      67             :  * The special case used in this map is the function
      68             :  * \f$ f(z) = \frac{z - \mu}{1 - z\mu}\f$. This has the desired properties:
      69             :  * - The unit disk in the complex plane is mapped to itself.
      70             :  *
      71             :  * - The x-axis is mapped to itself.
      72             :  *
      73             :  * - \f$f(\mu) = 0\f$.
      74             :  *
      75             :  * The three-dimensional version of this map is obtained by rotating the disk
      76             :  * in the plane about the x-axis.
      77             :  *
      78             :  * This map is useful for performing transformations along the x-axis
      79             :  * that preserve the unit disk. A concrete example of this is in the BBH
      80             :  * domain, where two BBHs with a center-of-mass at x=\f$\mu\f$ can be shifted
      81             :  * such that the new center of mass is now located at x=0. Additionally,
      82             :  * the spherical shape of the outer wave-zone is preserved and, as a mobius
      83             :  * map, the spherical coordinate shapes of the black holes is also preserved.
      84             :  */
      85           1 : class SpecialMobius {
      86             :  public:
      87           0 :   static constexpr size_t dim = 3;
      88           0 :   explicit SpecialMobius(double mu);
      89           0 :   SpecialMobius() = default;
      90           0 :   ~SpecialMobius() = default;
      91           0 :   SpecialMobius(SpecialMobius&&) = default;
      92           0 :   SpecialMobius(const SpecialMobius&) = default;
      93           0 :   SpecialMobius& operator=(const SpecialMobius&) = default;
      94           0 :   SpecialMobius& operator=(SpecialMobius&&) = default;
      95             : 
      96             :   template <typename T>
      97           0 :   std::array<T, 3> operator()(const std::array<T, 3>& source_coords) const;
      98             : 
      99             :   /// Returns std::nullopt for target_coords outside the unit sphere.
     100             :   /// The inverse function is only callable with doubles because the inverse
     101             :   /// might fail if called for a point out of range, and it is unclear
     102             :   /// what should happen if the inverse were to succeed for some points in a
     103             :   /// DataVector but fail for other points.
     104           1 :   std::optional<std::array<double, 3>> inverse(
     105             :       const std::array<double, 3>& target_coords) const;
     106             : 
     107             :   template <typename T>
     108           0 :   tnsr::Ij<T, 3, Frame::NoFrame> jacobian(
     109             :       const std::array<T, 3>& source_coords) const;
     110             : 
     111             :   template <typename T>
     112           0 :   tnsr::Ij<T, 3, Frame::NoFrame> inv_jacobian(
     113             :       const std::array<T, 3>& source_coords) const;
     114             : 
     115             :   // NOLINTNEXTLINE(google-runtime-references)
     116           0 :   void pup(PUP::er& p);
     117             : 
     118           0 :   bool is_identity() const { return is_identity_; }
     119             : 
     120           0 :   static constexpr bool supports_hessian{true};
     121             : 
     122             :  private:
     123             :   template <typename T>
     124           0 :   std::array<T, 3> mobius_distortion(const std::array<T, 3>& coords,
     125             :                                      double mu) const;
     126             :   template <typename T>
     127           0 :   tnsr::Ij<T, 3, Frame::NoFrame> mobius_distortion_jacobian(
     128             :       const std::array<T, 3>& coords, double mu) const;
     129           0 :   friend bool operator==(const SpecialMobius& lhs, const SpecialMobius& rhs);
     130             : 
     131           0 :   double mu_{std::numeric_limits<double>::signaling_NaN()};
     132           0 :   bool is_identity_{false};
     133             : };
     134           0 : bool operator!=(const SpecialMobius& lhs, const SpecialMobius& rhs);
     135             : }  // namespace CoordinateMaps
     136             : }  // namespace domain

Generated by: LCOV version 1.14