SpECTRE Documentation Coverage Report
Current view: top level - Domain/CoordinateMaps - Interval.hpp Hit Total Coverage
Commit: 37c384043430860f87787999aa7399d01bb3d213 Lines: 1 20 5.0 %
Date: 2024-04-20 02:24:02
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 <optional>
       9             : 
      10             : #include "DataStructures/Tensor/TypeAliases.hpp"
      11             : #include "Domain/CoordinateMaps/Distribution.hpp"
      12             : #include "Utilities/Serialization/PupStlCpp17.hpp"
      13             : #include "Utilities/TypeTraits/RemoveReferenceWrapper.hpp"
      14             : 
      15             : /// \cond
      16             : namespace PUP {
      17             : class er;
      18             : }  // namespace PUP
      19             : /// \endcond
      20             : 
      21             : namespace domain::CoordinateMaps {
      22             : 
      23             : /*!
      24             :  * \ingroup CoordinateMapsGroup
      25             :  * \brief Maps \f$\xi\f$ in the 1D interval \f$[A, B]\f$ to \f$x\f$ in the
      26             :  * interval \f$[a, b]\f$ according to a `domain::CoordinateMaps::Distribution`.
      27             :  *
      28             :  * \details The mapping takes a `domain::CoordinateMaps::Distribution` and
      29             :  * distributes the grid points accordingly.
      30             :  *
      31             :  * The formula for the mapping is, in case of a `Linear` distribution
      32             :  * \f{align}
      33             :  * x &= \frac{b}{B-A} (\xi-A) + \frac{a}{B-A} (B-\xi)\\
      34             :  * \xi &=\frac{B}{b-a} (x-a) + \frac{A}{b-a} (b-x)
      35             :  * \f}
      36             :  *
      37             :  * For every other distribution we use this linear mapping to map onto an
      38             :  * interval \f$[-1, 1]\f$, so we define:
      39             :  * \f{align}
      40             :  * f(\xi) &:= \frac{A+B-2\xi}{A-B} \in [-1, 1]\\
      41             :  * g(x) &:= \frac{a+b-2x}{a-b} \in [-1, 1]
      42             :  * \f}
      43             :  *
      44             :  * With this an `Equiangular` distribution is described by
      45             :  *
      46             :  * \f{align}
      47             :  * x &= \frac{a}{2} \left(1-\mathrm{tan}\left(\frac{\pi}{4}f(\xi)\right)\right)
      48             :  * + \frac{b}{2} \left(1+\mathrm{tan}\left(\frac{\pi}{4}f(\xi)\right)\right)\\
      49             :  * \xi &=
      50             :  * \frac{A}{2} \left(1-\frac{4}{\pi}\mathrm{arctan}\left(g(x)\right)\right) +
      51             :  * \frac{B}{2} \left(1+\frac{4}{\pi}\mathrm{arctan}\left(g(x)\right)\right)
      52             :  * \f}
      53             :  *
      54             :  * \note The equiangular distribution is intended to be used with the `Wedge`
      55             :  * map when equiangular coordinates are chosen for those maps. For more
      56             :  * information on this choice of coordinates, see the documentation for `Wedge`.
      57             :  *
      58             :  *
      59             :  * For both the `Logarithmic` and `Inverse` distribution, we first specify a
      60             :  * position for the singularity \f$c:=\f$`singularity_pos` outside the target
      61             :  * interval \f$[a, b]\f$.
      62             :  *
      63             :  * The `Logarithmic` distribution further requires the introduction of a
      64             :  * variable \f$\sigma\f$ dependent on whether \f$c\f$ is left (\f$ \sigma =
      65             :  * 1\f$) or right (\f$ \sigma = -1\f$) of the target interval. With this, the
      66             :  * `Logarithmic` distribution is described by
      67             :  *
      68             :  * \f{align}
      69             :  * x &= \sigma\, {\rm exp}\left(\frac{\ln(b-c)+\ln(a-c)}{2} + f(\xi)
      70             :  * \frac{\ln(b-c)-\ln(a-c)}{2}\right) + c\\
      71             :  * \xi &= \frac{B-A}{2}\frac{2\ln(\sigma [x-c]) - \ln(b-c) - \ln(a-c)}{\ln(b-c)
      72             :  * - \ln(a-c)} + \frac{B+A}{2} \f}
      73             :  *
      74             :  * and the `Inverse` distribution by
      75             :  *
      76             :  * \f{align}
      77             :  * x &= \frac{2(a-c)(b-c)}{a+b-2c+(a-b)f(\xi)} + c\\
      78             :  * \xi &= -\frac{A-B}{2(a-b)} \left(\frac{2(a-c)(b-c)}{x-c} - (a-c) -
      79             :  * (b-c)\right) + \frac{A+B}{2}
      80             :  * \f}
      81             :  */
      82           1 : class Interval {
      83             :  public:
      84           0 :   static constexpr size_t dim = 1;
      85             : 
      86           0 :   Interval(double A, double B, double a, double b, Distribution distribution,
      87             :            std::optional<double> singularity_pos = std::nullopt);
      88             : 
      89           0 :   Interval() = default;
      90             : 
      91             :   template <typename T>
      92           0 :   std::array<tt::remove_cvref_wrap_t<T>, 1> operator()(
      93             :       const std::array<T, 1>& source_coords) const;
      94             : 
      95           0 :   std::optional<std::array<double, 1>> inverse(
      96             :       const std::array<double, 1>& target_coords) const;
      97             : 
      98             :   template <typename T>
      99           0 :   tnsr::Ij<tt::remove_cvref_wrap_t<T>, 1, Frame::NoFrame> jacobian(
     100             :       const std::array<T, 1>& source_coords) const;
     101             : 
     102             :   template <typename T>
     103           0 :   tnsr::Ij<tt::remove_cvref_wrap_t<T>, 1, Frame::NoFrame> inv_jacobian(
     104             :       const std::array<T, 1>& source_coords) const;
     105             : 
     106             :   // NOLINTNEXTLINE(google-runtime-references)
     107           0 :   void pup(PUP::er& p);
     108             : 
     109           0 :   bool is_identity() const { return is_identity_; }
     110             : 
     111             :  private:
     112           0 :   friend bool operator==(const Interval& lhs, const Interval& rhs);
     113             : 
     114           0 :   double A_{std::numeric_limits<double>::signaling_NaN()};
     115           0 :   double B_{std::numeric_limits<double>::signaling_NaN()};
     116           0 :   double a_{std::numeric_limits<double>::signaling_NaN()};
     117           0 :   double b_{std::numeric_limits<double>::signaling_NaN()};
     118           0 :   Distribution distribution_{Distribution::Linear};
     119           0 :   std::optional<double> singularity_pos_{std::nullopt};
     120           0 :   bool is_identity_{false};
     121             : };
     122             : 
     123           0 : inline bool operator!=(const CoordinateMaps::Interval& lhs,
     124             :                        const CoordinateMaps::Interval& rhs) {
     125             :   return not(lhs == rhs);
     126             : }
     127             : 
     128             : }  // namespace domain::CoordinateMaps

Generated by: LCOV version 1.14