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