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