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* msg) noexcept
95  : SphericalMetricData(msg) {}
96 
97  // clang doesn't manage to use = default correctly in this case
98  // NOLINTNEXTLINE(modernize-use-equals-default)
99  GaugeWave() noexcept {}
100 
101  GaugeWave(double extraction_radius, double mass, double frequency,
102  double amplitude, double peak_time, double duration) noexcept;
103 
104  std::unique_ptr<WorldtubeData> get_clone() const noexcept override;
105 
106  void pup(PUP::er& p) noexcept override;
107 
108  private:
109  double coordinate_wave_function(double time) const noexcept;
110 
111  double du_coordinate_wave_function(double time) const noexcept;
112 
113  double du_du_coordinate_wave_function(double time) const noexcept;
114 
115  protected:
116  /// A no-op as the gauge wave solution does not have substantial
117  /// shared computation to prepare before the separate component calculations.
118  void prepare_solution(const size_t /*output_l_max*/,
119  const double /*time*/) const noexcept override {}
120 
121  /*!
122  * \brief Compute the spherical coordinate metric from the closed-form gauge
123  * wave metric.
124  *
125  * \details The transformation of the ingoing Eddington-Finkelstein coordinate
126  * produces metric components in spherical coordinates (identical up to minor
127  * manipulations of the metric given in Eq. (149) of \cite Barkett2019uae):
128  *
129  * \f{align*}{
130  * g_{tt} &= \frac{-1}{r^3}\left(r - 2 M\right)
131  * \left[r + \partial_u F(u)\right]^2\\
132  * g_{rt} &= \frac{1}{r^4} \left[r + \partial_u F(u)\right]
133  * \left\{2 M r^2 + \left(r - 2 M\right)
134  * \left[r \partial_u F(u) + F(u)\right]\right\} \\
135  * g_{rr} &= \frac{1}{r^5} \left[r^2 - r \partial_u F(u) - F(u)\right]
136  * \left\{r^3 + 2 M r^2 + \left(r - 2 M\right)
137  * \left[r \partial_u F(u) + F(u)\right]\right\} \\
138  * g_{\theta \theta} &= r^2 \\
139  * g_{\phi \phi} &= r^2 \sin^2(\theta),
140  * \f}
141  *
142  * and all other components vanish. Here, \f$F(u)\f$ is defined as
143  *
144  * \f{align*}{
145  * F(u) &= A \sin(\omega u) e^{-(u - u_0)^2 /k^2},\\
146  * \partial_u F(u) &= A \left[-2 \frac{u - u_0}{k^2} \sin(\omega u)
147  * + \omega \cos(\omega u)\right] e^{-(u - u_0)^2 / k^2}.
148  * \f}
149  *
150  * \warning The \f$\phi\f$ components are returned in a form for which the
151  * \f$\sin(\theta)\f$ factors are omitted, assuming that derivatives and
152  * Jacobians will be applied similarly omitting those factors (and therefore
153  * improving precision of the tensor expression). If you require the
154  * \f$\sin(\theta)\f$ factors, be sure to put them in by hand in the calling
155  * code.
156  */
157  void spherical_metric(
161  size_t l_max, double time) const noexcept override;
162 
163  /*!
164  * \brief Compute the radial derivative of the spherical coordinate metric
165  * from the closed-form gauge wave metric.
166  *
167  * \details The transformation of the ingoing Eddington-Finkelstein coordinate
168  * produces the radial derivative of the metric components in spherical
169  * coordinates:
170  *
171  * \f{align*}{
172  * \partial_r g_{tt} + \partial_t g_{tt} =& \frac{2}{r^4}
173  * \left[r + \partial_u F(u)\right]
174  * \left[- M r + (r - 3 M)\partial_u F(u)\right] \\
175  * \partial_r g_{rt} + \partial_t g_{rt} =& - \frac{1}{r^5}
176  * \left\{2 M r^3 + 2 r F(u) (r - 3M) + \partial_u F(u)[r^3 + F(u)(3r - 8 M)]
177  * + 2 r [\partial_u F(u)]^2 (r - 3M)\right\}\\
178  * \partial_r g_{rr} + \partial_t g_{rr} =& \frac{2}{r^6}
179  * \left\{- M r^4 + F(u)^2 (2r - 5M)
180  * + \partial_u F(u) r^2 \left[4 M r + \partial_u F(u) (r - 3 M)\right]
181  * + F(u) r \left[6 M r + \partial_u F(u) (3r - 8 M)\right]\right\} \\
182  * g_{\theta \theta} =& 2 r \\
183  * g_{\phi \phi} =& 2 r \sin^2(\theta),
184  * \f}
185  *
186  * and all other components vanish (these formulae are obtained simply by
187  * applying radial derivatives to those given in
188  * `GaugeWave::spherical_metric()`). Here, \f$F(u)\f$ is defined as
189  *
190  * \f{align*}{
191  * F(u) &= A \sin(\omega u) e^{-(u - u_0)^2 /k^2},\\
192  * \partial_u F(u) &= A \left[-2 \frac{u - u_0}{k^2} \sin(\omega u)
193  * + \omega \cos(\omega u)\right] e^{-(u - u_0)^2 / k^2}.
194  * \f}
195  *
196  * \warning The \f$\phi\f$ components are returned in a form for which the
197  * \f$\sin(\theta)\f$ factors are omitted, assuming that derivatives and
198  * Jacobians will be applied similarly omitting those factors (and therefore
199  * improving precision of the tensor expression). If you require the
200  * \f$\sin(\theta)\f$ factors, be sure to put them in by hand in the calling
201  * code.
202  */
203  void dr_spherical_metric(
207  size_t l_max, double time) const noexcept override;
208 
209  /*!
210  * \brief Compute the spherical coordinate metric from the closed-form gauge
211  * wave metric.
212  *
213  * \details The transformation of the ingoing Eddington-Finkelstein coordinate
214  * produces metric components in spherical coordinates:
215  *
216  * \f{align*}{
217  * \partial_t g_{tt} =& \frac{-2 \partial_u^2 F(u)}{r^3}
218  * \left(r - 2 M\right) \left(r + \partial_u F(u)\right) \\
219  * \partial_t g_{rt} =& \frac{1}{r^4} \Bigg\{\partial_u^2 F(u)
220  * \left[2 M r^2 + \left(r - 2 M\right)
221  * (r \partial_u F(u) + F(u))\right] \\
222  * &+ \left[r + \partial_u F(u)\right]
223  * \left(r - 2M\right) \left[r \partial_u^2 F(u) + \partial_u F(u)
224  * \right]\Bigg\} \\
225  * \partial_t g_{rr} =&
226  * \frac{1}{r^5}\Bigg\{-\left[r \partial_u^2 F(u) + \partial_u F(u)\right]
227  * \left[r^3 + 2 M r^2 + \left(r - 2 M\right)
228  * \left(r \partial_u F(u) + F(u)\right)\right]\\
229  * &+ \left[r^2 - r \partial_u F(u) - F(u)\right]
230  * \left(r - 2 M\right)
231  * \left[r \partial_u^2 F(u) + \partial_u F(u)\right]\Bigg\} \\
232  * \partial_t g_{\theta \theta} =& 0 \\
233  * \partial_t g_{\phi \phi} =& 0,
234  * \f}
235  *
236  * and all other components vanish. Here, \f$F(u)\f$ is defined as
237  *
238  * \f{align*}{
239  * F(u) &= A \sin(\omega u) e^{-(u - u_0)^2 /k^2},\\
240  * \partial_u F(u) &= A \left[-2 \frac{u - u_0}{k^2} \sin(\omega u)
241  * + \omega \cos(\omega u)\right] e^{-(u - u_0)^2 / k^2},\\
242  * \partial^2_u F(u) &= \frac{A}{k^4} \left\{-4 k^2 \omega (u - u_0)
243  * \cos(\omega u) + \left[-2 k^2 + 4 (u - u_0)^2 - k^4 \omega^2\right]
244  * \sin(\omega u)\right\} e^{-(u - u_0) / k^2}
245  * \f}
246  *
247  * \warning The \f$\phi\f$ components are returned in a form for which the
248  * \f$\sin(\theta)\f$ factors are omitted, assuming that derivatives and
249  * Jacobians will be applied similarly omitting those factors (and therefore
250  * improving precision of the tensor expression). If you require the
251  * \f$\sin(\theta)\f$ factors, be sure to put them in by hand in the calling
252  * code.
253  */
254  void dt_spherical_metric(
258  size_t l_max, double time) const noexcept override;
259 
260  using WorldtubeData::variables_impl;
261 
263 
264  /// The News vanishes, because the wave is pure gauge.
265  void variables_impl(
267  size_t l_max, double time,
268  tmpl::type_<Tags::News> /*meta*/) const noexcept override;
269 
271  double frequency_ = std::numeric_limits<double>::signaling_NaN();
272  double amplitude_ = std::numeric_limits<double>::signaling_NaN();
273  double peak_time_ = std::numeric_limits<double>::signaling_NaN();
274  double duration_ = std::numeric_limits<double>::signaling_NaN();
275 };
276 } // namespace Solutions
277 } // 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:118
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: ReadSpecPiecewisePolynomial.hpp:13