SpECTRE Documentation Coverage Report
Current view: top level - Domain/CoordinateMaps/TimeDependent/ShapeMapTransitionFunctions - ShapeMapTransitionFunction.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 46.2 % 13 6
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 <optional>
       8              : #include <pup.h>
       9              : 
      10              : #include "DataStructures/DataVector.hpp"
      11              : #include "Utilities/Serialization/CharmPupable.hpp"
      12              : 
      13              : namespace domain::CoordinateMaps::ShapeMapTransitionFunctions {
      14              : 
      15              : /*!
      16              :  * \brief Abstract base class for the transition function $G(r,\theta,\phi)$
      17              :  * used by the domain::CoordinateMaps::TimeDependent::Shape map.
      18              :  *
      19              :  * \details This base class defines the required methods of a transition
      20              :  * function that is defined as
      21              :  *
      22              :  * \begin{equation}
      23              :  * G(r,\theta,\phi) = \frac{f(r,\theta,\phi)}{r}
      24              :  * \end{equation}
      25              :  *
      26              :  * where $0 <= f(r,\theta,\phi) <= 1$. Different domains may require the shape
      27              :  * map to fall off towards the boundary in different ways. This behavior is
      28              :  * controlled by the transition function. It is also needed to find the inverse
      29              :  * of the shape map. Since the shape map preserves angles, the problem of
      30              :  * finding its inverse reduces to the 1-dimensional problem of finding the
      31              :  * original radius from the mapped radius. The mapped radius $\tilde{r}$ is
      32              :  * related to the original $r$ radius by:
      33              :  * \begin{equation}
      34              :  * \label{eq:shape_map_radius}
      35              :  * \tilde{r} = r \left(1 - G(r,\theta,\phi)\sum_{lm}
      36              :  *     \lambda_{lm}(t)Y_{lm}(\theta,\phi)\right),
      37              :  * \end{equation}
      38              :  * Depending on the format of the transition function, it should be possible to
      39              :  * analytically derive this map's inverse because it preserves angles and shifts
      40              :  * only the radius of each point. Otherwise the inverse has to be computed
      41              :  * numerically.
      42              :  *
      43              :  * The transition function must also be able to compute the gradient and the
      44              :  * value of the function divided by the radius. Care must be taken that this
      45              :  * does not divide by zero.
      46              :  *
      47              :  * All member functions with the exception of `original_radius_over_radius`
      48              :  * exist as overloads for types `double` and `DataVector` so that they work with
      49              :  * the templated shape map methods calling them. To avoid code duplication these
      50              :  * can be forwarded to templated implementation methods held by the derived
      51              :  * classes only.
      52              :  *
      53              :  * For an example, see SphereTransition.
      54              :  *
      55              :  * #### Design Decisions:
      56              :  *
      57              :  * It was decided to make the ShapeMapTransitionFunction an abstract base class
      58              :  * with overloads for types `double` and `DataVector` corresponding to the
      59              :  * template parameter `T` of the shape map's methods. The shape map holds a
      60              :  * `unique_ptr` to this abstract class using a common dynamic dispatch design
      61              :  * pattern. This approach avoids templating the shape map all together.
      62              :  *
      63              :  * An alternative approach would be to directly template the transition
      64              :  * functions onto the shape map so that no abstract base class is necessary.
      65              :  * These approaches can also be combined by making the transition function an
      66              :  * abstract base class but also templating it onto the shape map. In this way
      67              :  * the shape map does not need to hold a `unique_ptr` but can hold the
      68              :  * transition function directly as a member.
      69              :  */
      70            1 : class ShapeMapTransitionFunction : public PUP::able {
      71              :  public:
      72            0 :   ShapeMapTransitionFunction() = default;
      73              : 
      74              :   /// @{
      75              :   /*!
      76              :    * Evaluate the transition function $G(r,\theta,\phi)$ at the
      77              :    * Cartesian coordinates `source_coords` and possibly divide by the radius
      78              :    * $r$.
      79              :    *
      80              :    * \details If \p one_over_radius_power has a value, then divide $G$ by $r$ to
      81              :    * that power. This is done here because the transition function knows how to
      82              :    * handle points in various regions of the map.
      83              :    */
      84            1 :   virtual double operator()(
      85              :       const std::array<double, 3>& source_coords,
      86              :       const std::optional<size_t>& one_over_radius_power) const = 0;
      87            1 :   virtual DataVector operator()(
      88              :       const std::array<DataVector, 3>& source_coords,
      89              :       const std::optional<size_t>& one_over_radius_power) const = 0;
      90              :   /// @}
      91              : 
      92              :   /*!
      93              :    * \brief The inverse of the transition function
      94              :    *
      95              :    * This method returns $r/\tilde{r}$ given the mapped coordinates
      96              :    * $\tilde{x}^i$ (`target_coords`) and the spherical harmonic expansion
      97              :    * $\Sigma(t, \theta, \phi) = \sum_{lm} \lambda_{lm}(t)Y_{lm}(\theta, \phi)$
      98              :    * (`radial_distortion`). See domain::CoordinateMaps::TimeDependent::Shape for
      99              :    * details on how this quantity is used to compute the inverse of the Shape
     100              :    * map.
     101              :    *
     102              :    * To derive the expression for this inverse, solve Eq.
     103              :    * ($\ref{eq:shape_map_radius}$) for $r$ after substituting
     104              :    * $G(r,\theta,\phi)$.
     105              :    *
     106              :    * \param target_coords The mapped Cartesian coordinates $\tilde{x}^i$.
     107              :    * \param radial_distortion The spherical harmonic expansion
     108              :    * $\Sigma(t, \theta, \phi)$.
     109              :    * \return The quantity $r/\tilde{r}$.
     110              :    */
     111            1 :   virtual std::optional<double> original_radius_over_radius(
     112              :       const std::array<double, 3>& target_coords,
     113              :       double radial_distortion) const = 0;
     114              : 
     115              :   /*!
     116              :    * Evaluate the gradient of the transition function with respect to the
     117              :    * Cartesian coordinates x, y and z at the Cartesian coordinates
     118              :    * `source_coords`.
     119              :    */
     120              :   /// @{
     121            1 :   virtual std::array<double, 3> gradient(
     122              :       const std::array<double, 3>& source_coords) const = 0;
     123            1 :   virtual std::array<DataVector, 3> gradient(
     124              :       const std::array<DataVector, 3>& source_coords) const = 0;
     125              :   /// @}
     126              : 
     127            0 :   virtual std::unique_ptr<ShapeMapTransitionFunction> get_clone() const = 0;
     128              : 
     129            0 :   virtual bool operator==(const ShapeMapTransitionFunction& other) const = 0;
     130            0 :   virtual bool operator!=(const ShapeMapTransitionFunction& other) const = 0;
     131              : 
     132            0 :   WRAPPED_PUPable_abstract(ShapeMapTransitionFunction);
     133            0 :   explicit ShapeMapTransitionFunction(CkMigrateMessage* m) : PUP::able(m) {}
     134              : };
     135              : }  // namespace domain::CoordinateMaps::ShapeMapTransitionFunctions
        

Generated by: LCOV version 2.0-1