SpECTRE Documentation Coverage Report
Current view: top level - Evolution/Systems/Cce/AnalyticSolutions - GaugeWave.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 14.3 % 49 7
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 <complex>
       7              : #include <cstddef>
       8              : #include <memory>
       9              : #include <vector>
      10              : 
      11              : #include "DataStructures/SpinWeighted.hpp"
      12              : #include "Evolution/Systems/Cce/AnalyticSolutions/SphericalMetricData.hpp"
      13              : #include "Evolution/Systems/Cce/AnalyticSolutions/WorldtubeData.hpp"
      14              : #include "Evolution/Systems/Cce/Tags.hpp"
      15              : #include "Options/String.hpp"
      16              : #include "Utilities/Gsl.hpp"
      17              : #include "Utilities/Literals.hpp"
      18              : #include "Utilities/Serialization/CharmPupable.hpp"
      19              : #include "Utilities/TMPL.hpp"
      20              : 
      21              : /// \cond
      22              : class DataVector;
      23              : class ComplexDataVector;
      24              : /// \endcond
      25              : 
      26              : namespace Cce {
      27              : namespace Solutions {
      28              : 
      29              : /*!
      30              :  * \brief Computes the analytic data for a gauge wave solution described in
      31              :  * \cite Barkett2019uae.
      32              :  *
      33              :  * \details This test computes an analytic solution of a pure-gauge perturbation
      34              :  * of the Schwarzschild metric. The gauge perturbation is constructed using the
      35              :  * time-dependent coordinate transformation of the ingoing Eddington-Finklestein
      36              :  * coordinate \f$\nu \rightarrow \nu + F(t - r) / r\f$, where
      37              :  *
      38              :  * \f[
      39              :  * F(u) = A \sin(\omega u) e^{- (u - u_0)^2 / k^2}.
      40              :  * \f]
      41              :  *
      42              :  * \note In the paper \cite Barkett2019uae, a translation map was
      43              :  * applied to the solution to make the test more demanding. For simplicity, we
      44              :  * omit that extra map. The behavior of translation-independence is
      45              :  * tested by the `Cce::Solutions::BouncingBlackHole` solution.
      46              :  */
      47            1 : struct GaugeWave : public SphericalMetricData {
      48            0 :   struct ExtractionRadius {
      49            0 :     using type = double;
      50            0 :     static constexpr Options::String help{
      51              :         "The extraction radius of the spherical solution"};
      52            0 :     static type lower_bound() { return 0.0; }
      53              :   };
      54            0 :   struct Mass {
      55            0 :     using type = double;
      56            0 :     static constexpr Options::String help{
      57              :         "The mass of the Schwarzschild solution."};
      58            0 :     static type lower_bound() { return 0.0; }
      59              :   };
      60            0 :   struct Frequency {
      61            0 :     using type = double;
      62            0 :     static constexpr Options::String help{
      63              :         "The frequency of the oscillation of the gauge wave."};
      64            0 :     static type lower_bound() { return 0.0; }
      65              :   };
      66            0 :   struct Amplitude {
      67            0 :     using type = double;
      68            0 :     static constexpr Options::String help{
      69              :       "The amplitude of the gauge wave."};
      70            0 :     static type lower_bound() { return 0.0; }
      71              :   };
      72            0 :   struct PeakTime {
      73            0 :     using type = double;
      74            0 :     static constexpr Options::String help{
      75              :         "The time of the peak of the Gaussian envelope."};
      76            0 :     static type lower_bound() { return 0.0; }
      77              :   };
      78            0 :   struct Duration {
      79            0 :     using type = double;
      80            0 :     static constexpr Options::String help{
      81              :         "The characteristic duration of the Gaussian envelope."};
      82            0 :     static type lower_bound() { return 0.0; }
      83              :   };
      84              : 
      85            0 :   using options = tmpl::list<ExtractionRadius, Mass, Frequency, Amplitude,
      86              :                              PeakTime, Duration>;
      87              : 
      88            0 :   static constexpr Options::String help = {
      89              :       "Analytic solution representing worldtube data for a pure-gauge "
      90              :       "perturbation near a Schwarzschild metric in spherical coordinates"};
      91              : 
      92            0 :   WRAPPED_PUPable_decl_template(GaugeWave);  // NOLINT
      93              : 
      94            0 :   explicit GaugeWave(CkMigrateMessage* msg) : SphericalMetricData(msg) {}
      95              : 
      96              :   // clang doesn't manage to use = default correctly in this case
      97              :   // NOLINTNEXTLINE(modernize-use-equals-default)
      98            0 :   GaugeWave() {}
      99              : 
     100            0 :   GaugeWave(double extraction_radius, double mass, double frequency,
     101              :             double amplitude, double peak_time, double duration);
     102              : 
     103            0 :   std::unique_ptr<WorldtubeData> get_clone() const override;
     104              : 
     105            0 :   void pup(PUP::er& p) override;
     106              : 
     107              :  private:
     108            0 :   double coordinate_wave_function(double time) const;
     109              : 
     110            0 :   double du_coordinate_wave_function(double time) const;
     111              : 
     112            0 :   double du_du_coordinate_wave_function(double time) const;
     113              : 
     114              :  protected:
     115              :   /// A no-op as the gauge wave solution does not have substantial
     116              :   /// shared computation to prepare before the separate component calculations.
     117            1 :   void prepare_solution(const size_t /*output_l_max*/,
     118              :                         const double /*time*/) const override {}
     119              : 
     120              :   /*!
     121              :    * \brief Compute the spherical coordinate metric from the closed-form gauge
     122              :    * wave metric.
     123              :    *
     124              :    * \details The transformation of the ingoing Eddington-Finkelstein coordinate
     125              :    * produces metric components in spherical coordinates (identical up to minor
     126              :    * manipulations of the metric given in Eq. (149) of \cite Barkett2019uae):
     127              :    *
     128              :    * \f{align*}{
     129              :    * g_{tt} &= \frac{-1}{r^3}\left(r - 2 M\right)
     130              :    * \left[r + \partial_u F(u)\right]^2\\
     131              :    * g_{rt} &= \frac{1}{r^4} \left[r + \partial_u F(u)\right]
     132              :    * \left\{2 M r^2 + \left(r - 2 M\right)
     133              :    * \left[r \partial_u F(u) + F(u)\right]\right\} \\
     134              :    * g_{rr} &= \frac{1}{r^5} \left[r^2 - r \partial_u F(u) - F(u)\right]
     135              :    * \left\{r^3 + 2 M r^2 + \left(r - 2 M\right)
     136              :    * \left[r \partial_u F(u) + F(u)\right]\right\} \\
     137              :    * g_{\theta \theta} &= r^2 \\
     138              :    * g_{\phi \phi} &= r^2 \sin^2(\theta),
     139              :    * \f}
     140              :    *
     141              :    * and all other components vanish. Here, \f$F(u)\f$ is defined as
     142              :    *
     143              :    * \f{align*}{
     144              :    * F(u) &= A \sin(\omega u) e^{-(u - u_0)^2 /k^2},\\
     145              :    * \partial_u F(u) &= A \left[-2 \frac{u - u_0}{k^2} \sin(\omega u)
     146              :    * + \omega \cos(\omega u)\right] e^{-(u - u_0)^2 / k^2}.
     147              :    * \f}
     148              :    *
     149              :    * \warning The \f$\phi\f$ components are returned in a form for which the
     150              :    * \f$\sin(\theta)\f$ factors are omitted, assuming that derivatives and
     151              :    * Jacobians will be applied similarly omitting those factors (and therefore
     152              :    * improving precision of the tensor expression). If you require the
     153              :    * \f$\sin(\theta)\f$ factors, be sure to put them in by hand in the calling
     154              :    * code.
     155              :    */
     156            1 :   void spherical_metric(
     157              :       gsl::not_null<
     158              :           tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>*>
     159              :           spherical_metric,
     160              :       size_t l_max, double time) const override;
     161              : 
     162              :   /*!
     163              :    * \brief Compute the radial derivative of the spherical coordinate metric
     164              :    * from the closed-form gauge wave metric.
     165              :    *
     166              :    * \details The transformation of the ingoing Eddington-Finkelstein coordinate
     167              :    * produces the radial derivative of the metric components in spherical
     168              :    * coordinates:
     169              :    *
     170              :    * \f{align*}{
     171              :    * \partial_r g_{tt} + \partial_t g_{tt} =& \frac{2}{r^4}
     172              :    * \left[r + \partial_u F(u)\right]
     173              :    * \left[- M r + (r - 3 M)\partial_u F(u)\right] \\
     174              :    * \partial_r g_{rt} + \partial_t g_{rt} =& - \frac{1}{r^5}
     175              :    * \left\{2 M r^3 + 2 r F(u) (r - 3M) + \partial_u F(u)[r^3 + F(u)(3r - 8 M)]
     176              :    * + 2 r [\partial_u F(u)]^2 (r - 3M)\right\}\\
     177              :    * \partial_r g_{rr} + \partial_t g_{rr} =& \frac{2}{r^6}
     178              :    * \left\{- M r^4 + F(u)^2 (2r - 5M)
     179              :    * + \partial_u F(u) r^2 \left[4 M r + \partial_u F(u) (r - 3 M)\right]
     180              :    * + F(u) r \left[6 M r + \partial_u F(u) (3r - 8 M)\right]\right\} \\
     181              :    * g_{\theta \theta} =& 2 r \\
     182              :    * g_{\phi \phi} =& 2 r \sin^2(\theta),
     183              :    * \f}
     184              :    *
     185              :    * and all other components vanish (these formulae are obtained simply by
     186              :    * applying radial derivatives to those given in
     187              :    * `GaugeWave::spherical_metric()`). Here, \f$F(u)\f$ is defined as
     188              :    *
     189              :    * \f{align*}{
     190              :    * F(u) &= A \sin(\omega u) e^{-(u - u_0)^2 /k^2},\\
     191              :    * \partial_u F(u) &= A \left[-2 \frac{u - u_0}{k^2} \sin(\omega u)
     192              :    * + \omega \cos(\omega u)\right] e^{-(u - u_0)^2 / k^2}.
     193              :    * \f}
     194              :    *
     195              :    * \warning The \f$\phi\f$ components are returned in a form for which the
     196              :    * \f$\sin(\theta)\f$ factors are omitted, assuming that derivatives and
     197              :    * Jacobians will be applied similarly omitting those factors (and therefore
     198              :    * improving precision of the tensor expression). If you require the
     199              :    * \f$\sin(\theta)\f$ factors, be sure to put them in by hand in the calling
     200              :    * code.
     201              :    */
     202            1 :   void dr_spherical_metric(
     203              :       gsl::not_null<
     204              :           tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>*>
     205              :           dr_spherical_metric,
     206              :       size_t l_max, double time) const override;
     207              : 
     208              :   /*!
     209              :    * \brief Compute the spherical coordinate metric from the closed-form gauge
     210              :    * wave metric.
     211              :    *
     212              :    * \details The transformation of the ingoing Eddington-Finkelstein coordinate
     213              :    * produces metric components in spherical coordinates:
     214              :    *
     215              :    * \f{align*}{
     216              :    * \partial_t g_{tt} =& \frac{-2 \partial_u^2 F(u)}{r^3}
     217              :    * \left(r - 2 M\right) \left(r + \partial_u F(u)\right) \\
     218              :    * \partial_t g_{rt} =& \frac{1}{r^4} \Bigg\{\partial_u^2 F(u)
     219              :    * \left[2 M r^2 + \left(r - 2 M\right)
     220              :    * (r \partial_u F(u) + F(u))\right] \\
     221              :    * &+ \left[r + \partial_u F(u)\right]
     222              :    * \left(r - 2M\right) \left[r \partial_u^2 F(u) + \partial_u F(u)
     223              :    * \right]\Bigg\} \\
     224              :    * \partial_t g_{rr} =&
     225              :    * \frac{1}{r^5}\Bigg\{-\left[r \partial_u^2 F(u) + \partial_u F(u)\right]
     226              :    * \left[r^3 + 2 M r^2  + \left(r - 2 M\right)
     227              :    * \left(r \partial_u F(u) + F(u)\right)\right]\\
     228              :    * &+ \left[r^2 - r \partial_u F(u) - F(u)\right]
     229              :    * \left(r - 2 M\right)
     230              :    * \left[r \partial_u^2 F(u) + \partial_u F(u)\right]\Bigg\} \\
     231              :    * \partial_t g_{\theta \theta} =& 0 \\
     232              :    * \partial_t g_{\phi \phi} =& 0,
     233              :    * \f}
     234              :    *
     235              :    * and all other components vanish. Here, \f$F(u)\f$ is defined as
     236              :    *
     237              :    * \f{align*}{
     238              :    * F(u) &= A \sin(\omega u) e^{-(u - u_0)^2 /k^2},\\
     239              :    * \partial_u F(u) &= A \left[-2 \frac{u - u_0}{k^2} \sin(\omega u)
     240              :    * + \omega \cos(\omega u)\right] e^{-(u - u_0)^2 / k^2},\\
     241              :    * \partial^2_u F(u) &= \frac{A}{k^4} \left\{-4 k^2 \omega (u - u_0)
     242              :    * \cos(\omega u) + \left[-2 k^2 + 4 (u - u_0)^2 - k^4 \omega^2\right]
     243              :    * \sin(\omega u)\right\}  e^{-(u - u_0) / k^2}
     244              :    * \f}
     245              :    *
     246              :    * \warning The \f$\phi\f$ components are returned in a form for which the
     247              :    * \f$\sin(\theta)\f$ factors are omitted, assuming that derivatives and
     248              :    * Jacobians will be applied similarly omitting those factors (and therefore
     249              :    * improving precision of the tensor expression). If you require the
     250              :    * \f$\sin(\theta)\f$ factors, be sure to put them in by hand in the calling
     251              :    * code.
     252              :    */
     253            1 :   void dt_spherical_metric(
     254              :       gsl::not_null<
     255              :           tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>*>
     256              :           dt_spherical_metric,
     257              :       size_t l_max, double time) const override;
     258              : 
     259            0 :   using WorldtubeData::variables_impl;
     260              : 
     261            1 :   using SphericalMetricData::variables_impl;
     262              : 
     263              :   /// The News vanishes, because the wave is pure gauge.
     264            1 :   void variables_impl(
     265              :       gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -2>>*> News,
     266              :       size_t l_max, double time,
     267              :       tmpl::type_<Tags::News> /*meta*/) const override;
     268              : 
     269            0 :   double mass_ = std::numeric_limits<double>::signaling_NaN();
     270            0 :   double frequency_ = std::numeric_limits<double>::signaling_NaN();
     271            0 :   double amplitude_ = std::numeric_limits<double>::signaling_NaN();
     272            0 :   double peak_time_ = std::numeric_limits<double>::signaling_NaN();
     273            0 :   double duration_ = std::numeric_limits<double>::signaling_NaN();
     274              : };
     275              : }  // namespace Solutions
     276              : }  // namespace Cce
        

Generated by: LCOV version 2.0-1