SpECTRE Documentation Coverage Report
Current view: top level - Domain/CoordinateMaps - EquatorialCompression.hpp Hit Total Coverage
Commit: 5b6dac11263b5fb9107cb6ea064c64c61b65a417 Lines: 2 24 8.3 %
Date: 2024-04-19 22:56:45
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 on the sphere.
      27             :  * \image html EquatorialCompression.png "A sphere with an `aspect_ratio` of 3."
      28             :  *
      29             :  * \details A mapping from the sphere to itself which redistributes points
      30             :  * towards (or away from) a user-specifed axis, indicated by `index_pole_axis_`.
      31             :  * Once the axis is selected, the map is determined by a single parameter,
      32             :  * the `aspect_ratio` \f$\alpha\f$, which is the ratio of the distance
      33             :  * perpendicular to the polar axis to the distance along the polar axis for
      34             :  * a given point. This parameter name was chosen because points with
      35             :  * \f$\tan \theta = 1\f$ get mapped to points with \f$\tan \theta' = \alpha\f$.
      36             :  * In general, gridpoints located at an angle \f$\theta\f$ from the pole are
      37             :  * mapped to a new angle
      38             :  * \f$\theta'\f$ satisfying \f$\tan \theta' = \alpha \tan \theta\f$.
      39             :  *
      40             :  * For an `aspect_ratio` greater than one, the gridpoints are mapped towards
      41             :  * the equator, leading to an equatorially compressed grid. For an
      42             :  * `aspect_ratio` less than one, the gridpoints are mapped towards the poles.
      43             :  * Note that the aspect ratio must be positive.
      44             :  *
      45             :  * Suppose the polar axis were the z-axis, given by `index_pole_axis_ == 2`.
      46             :  * We can then define the auxiliary variables \f$ r := \sqrt{x^2 + y^2 +z^2}\f$
      47             :  * and \f$ \rho := \sqrt{x^2 + y^2 + \alpha^{-2} z^2}\f$.
      48             :  *
      49             :  * The map corresponding to this transformation in cartesian coordinates
      50             :  * is then given by:
      51             :  *
      52             :  * \f[\vec{x}'(x,y,z) =
      53             :  * \frac{r}{\rho}\begin{bmatrix}
      54             :  * x\\
      55             :  * y\\
      56             :  * \alpha^{-1} z\\
      57             :  * \end{bmatrix}.\f]
      58             :  *
      59             :  * The mappings for polar axes along the x and y axes are similarly obtained.
      60             :  */
      61           1 : class EquatorialCompression {
      62             :  public:
      63           0 :   static constexpr size_t dim = 3;
      64           0 :   explicit EquatorialCompression(double aspect_ratio,
      65             :                                  size_t index_pole_axis = 2);
      66           0 :   EquatorialCompression() = default;
      67           0 :   ~EquatorialCompression() = default;
      68           0 :   EquatorialCompression(EquatorialCompression&&) = default;
      69           0 :   EquatorialCompression(const EquatorialCompression&) = default;
      70           0 :   EquatorialCompression& operator=(const EquatorialCompression&) = default;
      71           0 :   EquatorialCompression& operator=(EquatorialCompression&&) = default;
      72             : 
      73             :   template <typename T>
      74           0 :   std::array<tt::remove_cvref_wrap_t<T>, 3> operator()(
      75             :       const std::array<T, 3>& source_coords) const;
      76             : 
      77             :   /// The inverse function is only callable with doubles because the inverse
      78             :   /// might fail if called for a point out of range, and it is unclear
      79             :   /// what should happen if the inverse were to succeed for some points in a
      80             :   /// DataVector but fail for other points.
      81           1 :   std::optional<std::array<double, 3>> inverse(
      82             :       const std::array<double, 3>& target_coords) const;
      83             : 
      84             :   template <typename T>
      85           0 :   tnsr::Ij<tt::remove_cvref_wrap_t<T>, 3, Frame::NoFrame> jacobian(
      86             :       const std::array<T, 3>& source_coords) const;
      87             : 
      88             :   template <typename T>
      89           0 :   tnsr::Ij<tt::remove_cvref_wrap_t<T>, 3, Frame::NoFrame> inv_jacobian(
      90             :       const std::array<T, 3>& source_coords) const;
      91             : 
      92             :   // NOLINTNEXTLINE(google-runtime-references)
      93           0 :   void pup(PUP::er& p);
      94             : 
      95           0 :   bool is_identity() const { return is_identity_; }
      96             : 
      97             :  private:
      98             :   template <typename T>
      99           0 :   std::array<tt::remove_cvref_wrap_t<T>, 3> angular_distortion(
     100             :       const std::array<T, 3>& coords, double inverse_alpha) const;
     101             :   template <typename T>
     102             :   tnsr::Ij<tt::remove_cvref_wrap_t<T>, 3, Frame::NoFrame>
     103           0 :   angular_distortion_jacobian(const std::array<T, 3>& coords,
     104             :                               double inverse_alpha) const;
     105           0 :   friend bool operator==(const EquatorialCompression& lhs,
     106             :                          const EquatorialCompression& rhs);
     107             : 
     108           0 :   double aspect_ratio_{std::numeric_limits<double>::signaling_NaN()};
     109           0 :   double inverse_aspect_ratio_{std::numeric_limits<double>::signaling_NaN()};
     110           0 :   bool is_identity_{false};
     111           0 :   size_t index_pole_axis_{};
     112             : };
     113           0 : bool operator!=(const EquatorialCompression& lhs,
     114             :                 const EquatorialCompression& rhs);
     115             : }  // namespace CoordinateMaps
     116             : }  // namespace domain

Generated by: LCOV version 1.14