SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/AnalyticSolutions/GeneralRelativity - GaugePlaneWave.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 3.9 % 51 2
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 <cstddef>
       8              : #include <memory>
       9              : 
      10              : #include "DataStructures/TaggedTuple.hpp"
      11              : #include "DataStructures/Tensor/TypeAliases.hpp"
      12              : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
      13              : #include "Options/String.hpp"
      14              : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
      15              : #include "PointwiseFunctions/AnalyticSolutions/GeneralRelativity/Solutions.hpp"
      16              : #include "PointwiseFunctions/GeneralRelativity/TagsDeclarations.hpp"
      17              : #include "PointwiseFunctions/MathFunctions/MathFunction.hpp"
      18              : #include "Utilities/TMPL.hpp"
      19              : 
      20              : /// \cond
      21              : namespace PUP {
      22              : class er;
      23              : }  // namespace PUP
      24              : namespace Tags {
      25              : template <typename Tag>
      26              : struct dt;
      27              : }  // namespace Tags
      28              : /// \endcond
      29              : 
      30            1 : namespace gr::Solutions {
      31              : 
      32              : /*!
      33              :  * \brief Gauge plane wave in flat spacetime
      34              :  *
      35              :  * \details
      36              :  * The spacetime metric is in Kerr-Schild form:
      37              :  * \f{equation}{
      38              :  * g_{\mu\nu} = \eta_{\mu\nu} + H l_\mu l_\nu
      39              :  * \f}
      40              :  * where \f$H\f$ is a scalar function of the coordinates, \f$\eta_{\mu\nu}\f$
      41              :  * is the Minkowski metric, and \f$l^\mu\f$ is a null vector. Note that the
      42              :  * form of the metric along with the nullness of \f$l^\mu\f$ allows one to
      43              :  * raise and lower indices of \f$l^\mu\f$ using \f$\eta_{\mu\nu}\f$, and
      44              :  * that \f$l^t l^t = l_t l_t = l^i l_i\f$.
      45              :  * Note also that
      46              :  * \f{equation}{
      47              :  * g^{\mu\nu}  \equiv \eta^{\mu\nu} - H l^\mu l^\nu,
      48              :  * \f}
      49              :  * and that \f$\sqrt{-g}=1\f$.
      50              :  * Also, \f$l_\mu\f$ is a geodesic with respect to both the physical metric
      51              :  * and the Minkowski metric:
      52              :  * \f{equation}{
      53              :  * l^\mu \partial_\mu l_\nu = l^\mu\nabla_\mu l_\nu = 0.
      54              :  * \f}
      55              :  *
      56              :  * For this solution we choose the profile \f$H\f$ of the plane wave to be an
      57              :  * arbitrary one-dimensional function of \f$u = \vec{k} \cdot \vec{x} - \omega
      58              :  * t\f$ with a constant Euclidean wave vector \f$\vec{k}\f$ and frequency
      59              :  * \f$\omega = ||\vec{k}||\f$.  The null covector is chosen to be \f$l_a =
      60              :  * (-\omega, k_i)\f$. Thus, if \f$H = H[u]\f$, then \f$\partial_\mu H = H'[u]
      61              :  * l_\mu\f$. Therefore the derivatives of the spacetime metric are:
      62              :  * \f{equation}{
      63              :  * \partial_\rho g_{\mu\nu} = H' l_\rho l_\mu l_\nu,
      64              :  * \f}
      65              :  *
      66              :  * The 3+1 quantities are
      67              :  * \f{align}{
      68              :  * \alpha & = \left( 1 + H \omega^2 \right)^{-1/2},\\
      69              :  * \beta^i & = \frac{-H \omega k^i}{1 + H \omega^2},\\
      70              :  * \gamma_{ij} & = \delta_{ij} + H k_i k_j,\\
      71              :  * \gamma & = 1 + H \omega^2,\\
      72              :  * \gamma^{ij} & = \delta^{ij} - \frac{H k^i k^j}{1 + H \omega^2},\\
      73              :  * \partial_t \alpha & = \frac{\omega^3 H'}{2 \left(1 + H \omega^2
      74              :  *    \right)^{3/2}},\\
      75              :  * \partial_i \alpha & = - \frac{\omega^2 H' k_i}{2 \left(1 + H
      76              :  *    \omega^2 \right)^{3/2}},\\
      77              :  * \partial_t \beta^i & = \frac{\omega^2 H' k^i}{\left(1 + H \omega^2
      78              :  *    \right)^2},\\
      79              :  * \partial_j \beta^i & = - \frac{\omega H' k_j k^i}{\left(1 + H
      80              :  *    \omega^2 \right)^2},\\
      81              :  * \partial_t \gamma_{ij} & = - \omega H' k_i k_j,\\
      82              :  * \partial_k \gamma_{ij} & = H' k_k k_i k_j,\\
      83              :  * K_{ij} & =  - \frac{\omega H' k_i k_j}{2 \left(1 + H
      84              :  *    \omega^2 \right)^{1/2}}.
      85              :  * \f}
      86              :  *
      87              :  * Note that this solution is a gauge wave as \f$\Gamma^a{}_{bc} = \frac{1}{2}
      88              :  * H' l^a l_b l_c\f$ and thus \f$R^a{}_{bcd} = 0\f$.
      89              :  *
      90              :  * \tparam Dim the spatial dimension of the solution
      91              :  */
      92              : template <size_t Dim>
      93            1 : class GaugePlaneWave : public AnalyticSolution<Dim>,
      94              :                        public MarkAsAnalyticSolution {
      95              :  public:
      96            0 :   static constexpr size_t volume_dim = Dim;
      97            0 :   struct WaveVector {
      98            0 :     using type = std::array<double, Dim>;
      99            0 :     static constexpr Options::String help = {
     100              :         "The direction of propagation of the wave."};
     101              :   };
     102              : 
     103            0 :   struct Profile {
     104            0 :     using type = std::unique_ptr<MathFunction<1, Frame::Inertial>>;
     105            0 :     static constexpr Options::String help = {"The profile of the wave."};
     106              :   };
     107              : 
     108            0 :   using options = tmpl::list<WaveVector, Profile>;
     109            0 :   static constexpr Options::String help{"Gauge plane wave in flat spacetime"};
     110              : 
     111            0 :   GaugePlaneWave() = default;
     112            0 :   GaugePlaneWave(const std::array<double, Dim>& wave_vector,
     113              :                  std::unique_ptr<MathFunction<1, Frame::Inertial>> profile);
     114            0 :   GaugePlaneWave(const GaugePlaneWave&);
     115            0 :   GaugePlaneWave& operator=(const GaugePlaneWave&);
     116            0 :   GaugePlaneWave(GaugePlaneWave&&) = default;
     117            0 :   GaugePlaneWave& operator=(GaugePlaneWave&&) = default;
     118            0 :   ~GaugePlaneWave() = default;
     119              : 
     120            0 :   explicit GaugePlaneWave(CkMigrateMessage* /*msg*/);
     121              : 
     122              :   template <typename DataType>
     123            0 :   using DerivLapse = ::Tags::deriv<gr::Tags::Lapse<DataType>,
     124              :                                    tmpl::size_t<volume_dim>, Frame::Inertial>;
     125              :   template <typename DataType>
     126            0 :   using DerivShift = ::Tags::deriv<gr::Tags::Shift<DataType, volume_dim>,
     127              :                                    tmpl::size_t<volume_dim>, Frame::Inertial>;
     128              :   template <typename DataType>
     129            0 :   using DerivSpatialMetric =
     130              :       ::Tags::deriv<gr::Tags::SpatialMetric<DataType, volume_dim>,
     131              :                     tmpl::size_t<volume_dim>, Frame::Inertial>;
     132              : 
     133              :   template <typename DataType>
     134            0 :   struct IntermediateVars {
     135            0 :     IntermediateVars(
     136              :         const std::array<double, Dim>& wave_vector,
     137              :         const std::unique_ptr<MathFunction<1, Frame::Inertial>>& profile,
     138              :         double omega, const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
     139              :         double t);
     140            0 :     DataType h{};
     141            0 :     DataType du_h{};
     142            0 :     DataType du_du_h{};
     143            0 :     DataType det_gamma{};
     144            0 :     DataType lapse{};
     145              :   };
     146              : 
     147              :   template <typename DataType, typename... Tags>
     148            0 :   tuples::TaggedTuple<Tags...> variables(
     149              :       const tnsr::I<DataType, volume_dim, Frame::Inertial>& x, double t,
     150              :       tmpl::list<Tags...> /*meta*/) const {
     151              :     const auto& vars =
     152              :         IntermediateVars<DataType>{wave_vector_, profile_, omega_, x, t};
     153              :     return {get<Tags>(variables(x, t, vars, tmpl::list<Tags>{}))...};
     154              :   }
     155              : 
     156              :   template <typename DataType, typename... Tags>
     157            0 :   tuples::TaggedTuple<Tags...> variables(
     158              :       const tnsr::I<DataType, volume_dim, Frame::Inertial>& x, double t,
     159              :       const IntermediateVars<DataType>& vars,
     160              :       tmpl::list<Tags...> /*meta*/) const {
     161              :     static_assert(sizeof...(Tags) > 1,
     162              :                   "Unrecognized tag requested. See the function parameters "
     163              :                   "for the tag.");
     164              :     return {get<Tags>(variables(x, t, vars, tmpl::list<Tags>{}))...};
     165              :   }
     166              : 
     167            0 :   std::array<double, Dim> get_wave_vector() const { return wave_vector_; }
     168              : 
     169              :   // NOLINTNEXTLINE(google-runtime-references)
     170            0 :   void pup(PUP::er& p);
     171              : 
     172              :  private:
     173              :   template <typename DataType>
     174            0 :   auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
     175              :                  double t, const IntermediateVars<DataType>& vars,
     176              :                  tmpl::list<gr::Tags::Lapse<DataType>> /*meta*/) const
     177              :       -> tuples::TaggedTuple<gr::Tags::Lapse<DataType>>;
     178              : 
     179              :   template <typename DataType>
     180            0 :   auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
     181              :                  double t, const IntermediateVars<DataType>& vars,
     182              :                  tmpl::list<::Tags::dt<gr::Tags::Lapse<DataType>>> /*meta*/)
     183              :       const -> tuples::TaggedTuple<::Tags::dt<gr::Tags::Lapse<DataType>>>;
     184              : 
     185              :   template <typename DataType>
     186            0 :   auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
     187              :                  double t, const IntermediateVars<DataType>& vars,
     188              :                  tmpl::list<DerivLapse<DataType>> /*meta*/) const
     189              :       -> tuples::TaggedTuple<DerivLapse<DataType>>;
     190              : 
     191              :   template <typename DataType>
     192            0 :   auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
     193              :                  double t, const IntermediateVars<DataType>& vars,
     194              :                  tmpl::list<gr::Tags::Shift<DataType, volume_dim>> /*meta*/)
     195              :       const -> tuples::TaggedTuple<gr::Tags::Shift<DataType, volume_dim>>;
     196              : 
     197              :   template <typename DataType>
     198            0 :   auto variables(
     199              :       const tnsr::I<DataType, volume_dim, Frame::Inertial>& x, double t,
     200              :       const IntermediateVars<DataType>& vars,
     201              :       tmpl::list<::Tags::dt<gr::Tags::Shift<DataType, volume_dim>>> /*meta*/)
     202              :       const
     203              :       -> tuples::TaggedTuple<::Tags::dt<gr::Tags::Shift<DataType, volume_dim>>>;
     204              : 
     205              :   template <typename DataType>
     206            0 :   auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
     207              :                  double t, const IntermediateVars<DataType>& vars,
     208              :                  tmpl::list<DerivShift<DataType>> /*meta*/) const
     209              :       -> tuples::TaggedTuple<DerivShift<DataType>>;
     210              : 
     211              :   template <typename DataType>
     212            0 :   auto variables(
     213              :       const tnsr::I<DataType, volume_dim, Frame::Inertial>& x, double t,
     214              :       const IntermediateVars<DataType>& vars,
     215              :       tmpl::list<gr::Tags::SpatialMetric<DataType, volume_dim>> /*meta*/) const
     216              :       -> tuples::TaggedTuple<gr::Tags::SpatialMetric<DataType, volume_dim>>;
     217              : 
     218              :   template <typename DataType>
     219            0 :   auto variables(
     220              :       const tnsr::I<DataType, volume_dim, Frame::Inertial>& x, double t,
     221              :       const IntermediateVars<DataType>& vars,
     222              :       tmpl::list<
     223              :           ::Tags::dt<gr::Tags::SpatialMetric<DataType, volume_dim>>> /*meta*/)
     224              :       const -> tuples::TaggedTuple<
     225              :           ::Tags::dt<gr::Tags::SpatialMetric<DataType, volume_dim>>>;
     226              : 
     227              :   template <typename DataType>
     228            0 :   auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& /*x*/,
     229              :                  double /*t*/, const IntermediateVars<DataType>& vars,
     230              :                  tmpl::list<DerivSpatialMetric<DataType>> /*meta*/) const
     231              :       -> tuples::TaggedTuple<DerivSpatialMetric<DataType>>;
     232              : 
     233              :   template <typename DataType>
     234            0 :   auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& /*x*/,
     235              :                  double /*t*/, const IntermediateVars<DataType>& vars,
     236              :                  tmpl::list<gr::Tags::SqrtDetSpatialMetric<DataType>> /*meta*/)
     237              :       const -> tuples::TaggedTuple<gr::Tags::SqrtDetSpatialMetric<DataType>>;
     238              : 
     239              :   template <typename DataType>
     240            0 :   auto variables(
     241              :       const tnsr::I<DataType, volume_dim, Frame::Inertial>& x, double t,
     242              :       const IntermediateVars<DataType>& vars,
     243              :       tmpl::list<gr::Tags::ExtrinsicCurvature<DataType, volume_dim>> /*meta*/)
     244              :       const -> tuples::TaggedTuple<
     245              :           gr::Tags::ExtrinsicCurvature<DataType, volume_dim>>;
     246              : 
     247              :   template <typename DataType>
     248            0 :   auto variables(
     249              :       const tnsr::I<DataType, volume_dim, Frame::Inertial>& x, double t,
     250              :       const IntermediateVars<DataType>& vars,
     251              :       tmpl::list<gr::Tags::InverseSpatialMetric<DataType, volume_dim>> /*meta*/)
     252              :       const -> tuples::TaggedTuple<
     253              :           gr::Tags::InverseSpatialMetric<DataType, volume_dim>>;
     254              : 
     255              :   template <size_t LocalDim>
     256              :   // NOLINTNEXTLINE(readability-redundant-declaration)
     257            0 :   friend bool operator==(const GaugePlaneWave<LocalDim>& lhs,
     258              :                          const GaugePlaneWave<LocalDim>& rhs);
     259              :   template <size_t LocalDim>
     260              :   // NOLINTNEXTLINE(readability-redundant-declaration)
     261            0 :   friend bool operator!=(const GaugePlaneWave<LocalDim>& lhs,
     262              :                          const GaugePlaneWave<LocalDim>& rhs);
     263              : 
     264            0 :   std::array<double, Dim> wave_vector_{};
     265            0 :   std::unique_ptr<MathFunction<1, Frame::Inertial>> profile_;
     266            0 :   double omega_{};
     267              : };
     268              : }  // namespace gr::Solutions
        

Generated by: LCOV version 2.0-1