GaugeWave.hpp
1 // 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/Options.hpp"
17 #include "Utilities/Gsl.hpp"
18 #include "Utilities/Literals.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 struct GaugeWave : public SphericalMetricData {
49  using type = double;
50  static constexpr Options::String help{
51  "The extraction radius of the spherical solution"};
52  static type lower_bound() noexcept { return 0.0; }
53  };
54  struct Mass {
55  using type = double;
56  static constexpr Options::String help{
57  "The mass of the Schwarzschild solution."};
58  static type lower_bound() noexcept { return 0.0; }
59  };
60  struct Frequency {
61  using type = double;
62  static constexpr Options::String help{
63  "The frequency of the oscillation of the gauge wave."};
64  static type lower_bound() noexcept { return 0.0; }
65  };
66  struct Amplitude {
67  using type = double;
68  static constexpr Options::String help{
69  "The amplitude of the gauge wave."};
70  static type lower_bound() noexcept { return 0.0; }
71  };
72  struct PeakTime {
73  using type = double;
74  static constexpr Options::String help{
75  "The time of the peak of the Gaussian envelope."};
76  static type lower_bound() noexcept { return 0.0; }
77  };
78  struct Duration {
79  using type = double;
80  static constexpr Options::String help{
81  "The characteristic duration of the Gaussian envelope."};
82  static type lower_bound() noexcept { return 0.0; }
83  };
84 
85  using options = tmpl::list<ExtractionRadius, Mass, Frequency, Amplitude,
87 
88  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  WRAPPED_PUPable_decl_template(GaugeWave); // NOLINT
93 
94  explicit GaugeWave(CkMigrateMessage* /*unused*/) noexcept {}
95 
96  // clang doesn't manage to use = default correctly in this case
97  // NOLINTNEXTLINE(modernize-use-equals-default)
98  GaugeWave() noexcept {}
99 
100  GaugeWave(double extraction_radius, double mass, double frequency,
101  double amplitude, double peak_time, double duration) noexcept;
102 
103  std::unique_ptr<WorldtubeData> get_clone() const noexcept override;
104 
105  void pup(PUP::er& p) noexcept override;
106 
107  private:
108  double coordinate_wave_function(double time) const noexcept;
109 
110  double du_coordinate_wave_function(double time) const noexcept;
111 
112  double du_du_coordinate_wave_function(double time) const noexcept;
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  void prepare_solution(const size_t /*output_l_max*/,
118  const double /*time*/) const noexcept 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  void spherical_metric(
160  size_t l_max, double time) const noexcept 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  void dr_spherical_metric(
206  size_t l_max, double time) const noexcept 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  void dt_spherical_metric(
257  size_t l_max, double time) const noexcept override;
258 
259  using WorldtubeData::variables_impl;
260 
262 
263  /// The News vanishes, because the wave is pure gauge.
264  void variables_impl(
266  size_t l_max, double time,
267  tmpl::type_<Tags::News> /*meta*/) const noexcept override;
268 
270  double frequency_ = std::numeric_limits<double>::signaling_NaN();
271  double amplitude_ = std::numeric_limits<double>::signaling_NaN();
272  double peak_time_ = std::numeric_limits<double>::signaling_NaN();
273  double duration_ = std::numeric_limits<double>::signaling_NaN();
274 };
275 } // namespace Solutions
276 } // namespace Cce
Cce::Solutions::GaugeWave::spherical_metric
void spherical_metric(gsl::not_null< tnsr::aa< DataVector, 3, ::Frame::Spherical<::Frame::Inertial >> * > spherical_metric, size_t l_max, double time) const noexcept override
Compute the spherical coordinate metric from the closed-form gauge wave metric.
Cce::Solutions::GaugeWave::variables_impl
void variables_impl(gsl::not_null< Scalar< SpinWeighted< ComplexDataVector, -2 >> * > News, size_t l_max, double time, tmpl::type_< Tags::News >) const noexcept override
The News vanishes, because the wave is pure gauge.
Cce::Solutions::GaugeWave::ExtractionRadius
Definition: GaugeWave.hpp:48
CharmPupable.hpp
Cce::Solutions::GaugeWave::Frequency
Definition: GaugeWave.hpp:60
Literals.hpp
Options.hpp
vector
Cce::Solutions::GaugeWave::Mass
Definition: GaugeWave.hpp:54
SpinWeighted
Make a spin-weighted type T with spin-weight Spin. Mathematical operators are restricted to addition,...
Definition: SpinWeighted.hpp:24
Cce::Solutions::GaugeWave::dt_spherical_metric
void dt_spherical_metric(gsl::not_null< tnsr::aa< DataVector, 3, ::Frame::Spherical<::Frame::Inertial >> * > dt_spherical_metric, size_t l_max, double time) const noexcept override
Compute the spherical coordinate metric from the closed-form gauge wave metric.
Cce::Solutions::SphericalMetricData
Abstract base class for analytic worldtube data most easily derived in spherical coordinate form.
Definition: SphericalMetricData.hpp:42
Cce::Solutions::GaugeWave::Amplitude
Definition: GaugeWave.hpp:66
Cce::Solutions::GaugeWave::prepare_solution
void prepare_solution(const size_t, const double) const noexcept override
A no-op as the gauge wave solution does not have substantial shared computation to prepare before the...
Definition: GaugeWave.hpp:117
Cce::Solutions::GaugeWave::dr_spherical_metric
void dr_spherical_metric(gsl::not_null< tnsr::aa< DataVector, 3, ::Frame::Spherical<::Frame::Inertial >> * > dr_spherical_metric, size_t l_max, double time) const noexcept override
Compute the radial derivative of the spherical coordinate metric from the closed-form gauge wave metr...
cstddef
Cce::Solutions::SphericalMetricData::variables_impl
void variables_impl(gsl::not_null< tnsr::aa< DataVector, 3 > * > spacetime_metric, size_t l_max, double time, tmpl::type_< gr::Tags::SpacetimeMetric< 3, ::Frame::Inertial, DataVector >>) const noexcept override
Computes the Cartesian spacetime metric from the spherical solution provided by the derived classes.
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:46
std::numeric_limits::signaling_NaN
T signaling_NaN(T... args)
memory
Frame::Spherical
Represents a spherical-coordinate frame that is associated with a Cartesian frame,...
Definition: IndexType.hpp:54
Cce::Solutions::GaugeWave::Duration
Definition: GaugeWave.hpp:78
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
Cce
The set of utilities for performing Cauchy characteristic evolution and Cauchy characteristic matchin...
Definition: CharacteristicExtractFwd.hpp:6
Gsl.hpp
Cce::Solutions::GaugeWave
Computes the analytic data for a gauge wave solution described in .
Definition: GaugeWave.hpp:47
Options::String
const char *const String
The string used in option structs.
Definition: Options.hpp:32
complex
Cce::Solutions::GaugeWave::PeakTime
Definition: GaugeWave.hpp:72
ComplexDataVector
Stores a collection of complex function values.
Definition: ComplexDataVector.hpp:53
std::unique_ptr
TMPL.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecThirdOrderPiecewisePolynomial.hpp:13