SpECTRE Documentation Coverage Report
Current view: top level - Domain/CoordinateMaps/TimeDependent - CubicScale.hpp Hit Total Coverage
Commit: ecb8a275e1aebab77dcce48a5e098ed4e486ab4b Lines: 2 21 9.5 %
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 <memory>
      10             : #include <optional>
      11             : #include <string>
      12             : #include <unordered_map>
      13             : #include <unordered_set>
      14             : 
      15             : #include "DataStructures/Tensor/TypeAliases.hpp"
      16             : 
      17             : /// \cond
      18             : namespace domain {
      19             : namespace FunctionsOfTime {
      20             : class FunctionOfTime;
      21             : }  // namespace FunctionsOfTime
      22             : }  // namespace domain
      23             : namespace PUP {
      24             : class er;
      25             : }  // namespace PUP
      26             : /// \endcond
      27             : 
      28             : namespace domain {
      29             : namespace CoordinateMaps {
      30             : namespace TimeDependent {
      31             : /*!
      32             :  * \ingroup CoordMapsTimeDependentGroup
      33             :  * \brief Maps the radius as \f$r(t) = a(t)\rho + \left(b(t) - a(t)\right)
      34             :  * \frac{\rho^3} {R^2}\f$ where \f$\rho\f$ is the radius of the source
      35             :  * coordinates.
      36             :  *
      37             :  * The map scales the radius \f$\rho\f$ in the source coordinates
      38             :  * \f$\xi^{\hat{i}}\f$ by a factor \f$a(t)\f$, while the coordinates near the
      39             :  * outer boundary \f$R\f$, are scaled by a factor \f$b(t)\f$. Here \f$a(t)\f$
      40             :  * and \f$b(t)\f$ are FunctionsOfTime. The target/mapped coordinates are denoted
      41             :  * by \f$x^i\f$.
      42             :  *
      43             :  * The mapped coordinates are given by:
      44             :  *
      45             :  * \f{align}{
      46             :  * x^i = \left[a + (b-a) \frac{\rho^2}{R^2}\right] \xi^{\hat{i}}
      47             :  *       \delta^i_{\hat{i}},
      48             :  * \f}
      49             :  *
      50             :  * where \f$\xi^{\hat{i}}\f$ are the source coordinates, \f$a\f$ and \f$b\f$ are
      51             :  * functions of time, \f$\rho\f$ is the radius in the source coordinates, and
      52             :  * \f$R\f$ is the outer boundary.
      53             :  *
      54             :  * The inverse map is computed by solving the cubic equation:
      55             :  *
      56             :  * \f{align}{
      57             :  * (b-a)\frac{\rho^3}{R^2} + a \rho - r = 0,
      58             :  * \f}
      59             :  *
      60             :  * which is done by defining \f$q=\rho/R\f$, and solving
      61             :  *
      62             :  * \f{align}{
      63             :  * q \left[(b-a) q^2 + a\right] - \frac{r}{R} = 0.
      64             :  * \f}
      65             :  *
      66             :  * The source coordinates are obtained using:
      67             :  *
      68             :  * \f{align}{
      69             :  * \xi^{\hat{i}} = \frac{qR}{r} x^i(t) \delta^{\hat{i}}_i
      70             :  * \f}
      71             :  *
      72             :  * The Jacobian is given by:
      73             :  *
      74             :  * \f{align}{
      75             :  * \frac{\partial x^i}{\partial \xi^{\hat{i}}}=
      76             :  *    \left[a + (b-a) \frac{\rho^2}{R^2}\right] \delta^i_{\hat{i}}
      77             :  *    + \frac{2 (b-a)}{R^2} \xi^{\hat{j}} \delta^i_{\hat{j}} \xi^{\hat{k}}
      78             :  *      \delta_{\hat{k}\hat{i}}
      79             :  * \f}
      80             :  *
      81             :  * The inverse Jacobian is given by:
      82             :  *
      83             :  * \f{align}{
      84             :  * \frac{\partial \xi^{\hat{i}}}{\partial x^i}=
      85             :  * \frac{1}{\left[a + (b-a)\rho^2/R^2\right]}
      86             :  *  \left[\delta^{\hat{i}}_i -
      87             :  *        \frac{2 (b-a)}{\left[a R^2 + 3(b-a)\rho^2\right]}
      88             :  *        \xi^{\hat{i}}\xi^{\hat{j}}\delta_{\hat{j}i}\right]
      89             :  * \f}
      90             :  *
      91             :  * The mesh velocity \f$v_g^i\f$ is given by:
      92             :  *
      93             :  * \f{align}{
      94             :  * v_g^i = \left[\frac{da}{dt} + \left(\frac{db}{dt}-\frac{da}{dt}\right)
      95             :  *         \frac{\rho^2}{R^2}\right] \xi^{\hat{i}} \delta^i_{\hat{i}}.
      96             :  * \f}
      97             :  */
      98             : template <size_t Dim>
      99           1 : class CubicScale {
     100             :  public:
     101           0 :   static constexpr size_t dim = Dim;
     102             : 
     103           0 :   explicit CubicScale(double outer_boundary,
     104             :                       std::string function_of_time_name_a,
     105             :                       std::string function_of_time_name_b);
     106           0 :   CubicScale() = default;
     107             : 
     108             :   template <typename T>
     109           0 :   std::array<T, Dim> operator()(
     110             :       const std::array<T, Dim>& source_coords, double time,
     111             :       const std::unordered_map<
     112             :           std::string,
     113             :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     114             :           functions_of_time) const;
     115             : 
     116             :   /// Returns std::nullopt if the point is outside the range of the map.
     117             :   /// The inverse function is only callable with doubles because the inverse
     118             :   /// might fail if called for a point out of range, and it is unclear
     119             :   /// what should happen if the inverse were to succeed for some points in a
     120             :   /// DataVector but fail for other points.
     121           1 :   std::optional<std::array<double, Dim>> inverse(
     122             :       const std::array<double, Dim>& target_coords, double time,
     123             :       const std::unordered_map<
     124             :           std::string,
     125             :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     126             :           functions_of_time) const;
     127             : 
     128             :   template <typename T>
     129           0 :   std::array<T, Dim> frame_velocity(
     130             :       const std::array<T, Dim>& source_coords, double time,
     131             :       const std::unordered_map<
     132             :           std::string,
     133             :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     134             :           functions_of_time) const;
     135             : 
     136             :   template <typename T>
     137           0 :   tnsr::Ij<T, Dim, Frame::NoFrame> inv_jacobian(
     138             :       const std::array<T, Dim>& source_coords, double time,
     139             :       const std::unordered_map<
     140             :           std::string,
     141             :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     142             :           functions_of_time) const;
     143             : 
     144             :   template <typename T>
     145           0 :   tnsr::Ij<T, Dim, Frame::NoFrame> jacobian(
     146             :       const std::array<T, Dim>& source_coords, double time,
     147             :       const std::unordered_map<
     148             :           std::string,
     149             :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     150             :           functions_of_time) const;
     151             : 
     152             :   // NOLINTNEXTLINE(google-runtime-references)
     153           0 :   void pup(PUP::er& p);
     154             : 
     155           0 :   static bool is_identity() { return false; }
     156             : 
     157           0 :   static constexpr bool supports_hessian{false};
     158             : 
     159           0 :   const std::unordered_set<std::string>& function_of_time_names() const {
     160             :     return f_of_t_names_;
     161             :   }
     162             : 
     163             :  private:
     164             :   template <size_t LocalDim>
     165             :   // NOLINTNEXTLINE(readability-redundant-declaration)
     166           0 :   friend bool operator==(const CubicScale<LocalDim>& lhs,
     167             :                          const CubicScale<LocalDim>& rhs);
     168             : 
     169           0 :   std::string f_of_t_a_{};
     170           0 :   std::string f_of_t_b_{};
     171           0 :   std::unordered_set<std::string> f_of_t_names_;
     172           0 :   double one_over_outer_boundary_{std::numeric_limits<double>::signaling_NaN()};
     173           0 :   bool functions_of_time_equal_{false};
     174             : };
     175             : 
     176             : template <size_t Dim>
     177           0 : bool operator!=(const CubicScale<Dim>& lhs, const CubicScale<Dim>& rhs) {
     178             :   return not(lhs == rhs);
     179             : }
     180             : 
     181             : }  // namespace TimeDependent
     182             : }  // namespace CoordinateMaps
     183             : }  // namespace domain

Generated by: LCOV version 1.14