SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/AnalyticSolutions/GeneralRelativity - GaugePlaneWave.hpp Hit Total Coverage
Commit: 923cd4a8ea30f5a5589baa60b0a93e358ca9f8e8 Lines: 2 51 3.9 %
Date: 2025-11-07 19:37:56
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/Tensor/TypeAliases.hpp"
      11             : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
      12             : #include "Options/String.hpp"
      13             : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
      14             : #include "PointwiseFunctions/AnalyticSolutions/GeneralRelativity/Solutions.hpp"
      15             : #include "PointwiseFunctions/GeneralRelativity/TagsDeclarations.hpp"
      16             : #include "PointwiseFunctions/MathFunctions/MathFunction.hpp"
      17             : #include "Utilities/TMPL.hpp"
      18             : #include "Utilities/TaggedTuple.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 1.14