GaugeWave.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 
10 #include "Options/Options.hpp"
11 #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
12 #include "PointwiseFunctions/GeneralRelativity/TagsDeclarations.hpp"
14 #include "Utilities/TMPL.hpp"
16 
17 /// \cond
18 namespace PUP {
19 class er;
20 } // namespace PUP
21 namespace Tags {
22 template <typename Tag>
23 struct dt;
24 } // namespace Tags
25 /// \endcond
26 
27 namespace gr {
28 namespace Solutions {
29 
30 /*!
31  * \brief Gauge wave in flat spacetime
32  *
33  * \details
34  * This solution is Minkowski space in coordinates chosen to contain
35  * a gauge wave. The spacetime metric is given by Eq. (4.3) of
36  * \cite Alcubierre2003pc :
37  *
38  * \f{equation}{
39  * ds^2 = -H dt^2 + H dx^2 + dy^2 + dz^2,
40  * \f}
41  *
42  * where
43  *
44  * \f{equation}{
45  * H = H(x-t) = 1 - A \sin\left(\frac{2\pi(x-t)}{d}\right).
46  * \f}
47  *
48  * The gauge wave has amplitude \f$A\f$, wavelength \f$d\f$, and propagates
49  * along the x axis.
50  *
51  * In these coordinates, the spatial metric \f$\gamma_{ij}\f$ and
52  * inverse spatial metric \f$\gamma^{ij}\f$ are diagonal,
53  * with the diagonal elements equal to unity except for
54  *
55  * \f{align}{
56  * \gamma_{xx} & = H,\\
57  * \gamma^{xx} & = 1/H.
58  * \f}
59  *
60  * The components of the derivatives of \f$\gamma_{ij}\f$ vanish except for
61  *
62  * \f{align}{
63  * \partial_t \gamma_{xx} & = \partial_t H = - \partial_x H,\\
64  * \partial_x \gamma_{xx} & = \partial_x H.
65  * \f}
66  *
67  * The square root of the spatial metric determinant is
68  *
69  * \f{align}{
70  * \sqrt{\gamma} & = \sqrt{H}.
71  * \f}
72  *
73  * The lapse and its derivatives are
74  *
75  * \f{align}{
76  * \alpha & = \sqrt{H},\\
77  * \partial_t \alpha & = -\frac{\partial_x H}{2\sqrt{H}},\\
78  * \partial_x \alpha & = \frac{\partial_x H}{2\sqrt{H}},\\
79  * \partial_y \alpha & = \partial_z \alpha = 0.
80  * \f}
81  *
82  * The shift \f$\beta^i\f$ and its derivatives vanish.
83  *
84  * The extrinsic curvature's components vanish, except for
85  *
86  * \f{align}{
87  * K_{xx} & = \frac{\partial_x H}{2 \sqrt{H}}.
88  * \f}
89  *
90  * The following are input file options that can be specified:
91  * - Amplitude (default: 1.)
92  * - Wavelength (default: 1.)
93  */
94 class GaugeWave : public MarkAsAnalyticSolution {
95  template <typename DataType>
96  struct IntermediateVars;
97 
98  public:
99  static constexpr size_t volume_dim = 3;
100  struct Amplitude {
101  using type = double;
102  static constexpr OptionString help = {"Amplitude of the gauge wave"};
103  static type default_value() noexcept { return 1.; }
104  static type lower_bound() noexcept { return 0.; }
105  };
106  struct Wavelength {
107  using type = double;
108  static constexpr OptionString help = {"Wavelength of the gauge wave"};
109  static type default_value() noexcept { return 1.; }
110  static type lower_bound() noexcept { return 0.; }
111  };
112 
113  using options = tmpl::list<Amplitude, Wavelength>;
114  static constexpr OptionString help{"Gauge wave in flat spacetime"};
115 
116  GaugeWave(double amplitude, double wavelength) noexcept;
117 
118  GaugeWave() = default;
119  GaugeWave(const GaugeWave& /*rhs*/) = default;
120  GaugeWave& operator=(const GaugeWave& /*rhs*/) = default;
121  GaugeWave(GaugeWave&& /*rhs*/) noexcept = default;
122  GaugeWave& operator=(GaugeWave&& /*rhs*/) noexcept = default;
123  ~GaugeWave() = default;
124 
125  template <typename DataType>
126  using DerivLapse = ::Tags::deriv<gr::Tags::Lapse<DataType>,
127  tmpl::size_t<volume_dim>, Frame::Inertial>;
128  template <typename DataType>
129  using DerivShift =
130  ::Tags::deriv<gr::Tags::Shift<volume_dim, Frame::Inertial, DataType>,
131  tmpl::size_t<volume_dim>, Frame::Inertial>;
132  template <typename DataType>
133  using DerivSpatialMetric = ::Tags::deriv<
135  tmpl::size_t<volume_dim>, Frame::Inertial>;
136 
137  template <typename DataType, typename... Tags>
138  tuples::TaggedTuple<Tags...> variables(
139  const tnsr::I<DataType, volume_dim, Frame::Inertial>& x, double t,
140  tmpl::list<Tags...> /*meta*/) const noexcept {
141  const auto& vars =
142  IntermediateVars<DataType>{amplitude_, wavelength_, x, t};
143  return {get<Tags>(variables(x, t, vars, tmpl::list<Tags>{}))...};
144  }
145 
146  template <typename DataType, typename... Tags>
147  tuples::TaggedTuple<Tags...> variables(
148  const tnsr::I<DataType, volume_dim, Frame::Inertial>& x, double t,
149  const IntermediateVars<DataType>& vars,
150  tmpl::list<Tags...> /*meta*/) const noexcept {
151  static_assert(sizeof...(Tags) > 1,
152  "Unrecognized tag requested. See the function parameters "
153  "for the tag.");
154  return {get<Tags>(variables(x, t, vars, tmpl::list<Tags>{}))...};
155  }
156 
157  template <typename DataType>
158  using tags = tmpl::list<
160  DerivLapse<DataType>,
163  DerivShift<DataType>,
164  gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataType>,
165  ::Tags::dt<
166  gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataType>>,
167  DerivSpatialMetric<DataType>, gr::Tags::SqrtDetSpatialMetric<DataType>,
170 
171  // clang-tidy: no runtime references
172  void pup(PUP::er& p) noexcept; // NOLINT
173 
174  SPECTRE_ALWAYS_INLINE double amplitude() const noexcept { return amplitude_; }
175  SPECTRE_ALWAYS_INLINE double wavelength() const noexcept {
176  return wavelength_;
177  }
178 
179  private:
180  template <typename DataType>
181  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
182  double t, const IntermediateVars<DataType>& vars,
183  tmpl::list<gr::Tags::Lapse<DataType>> /*meta*/) const noexcept
185 
186  template <typename DataType>
187  auto variables(
188  const tnsr::I<DataType, volume_dim, Frame::Inertial>& x, double t,
189  const IntermediateVars<DataType>& vars,
190  tmpl::list<::Tags::dt<gr::Tags::Lapse<DataType>>> /*meta*/) const noexcept
192 
193  template <typename DataType>
194  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
195  double t, const IntermediateVars<DataType>& vars,
196  tmpl::list<DerivLapse<DataType>> /*meta*/) const noexcept
198 
199  template <typename DataType>
200  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
201  double t, const IntermediateVars<DataType>& vars,
202  tmpl::list<gr::Tags::Shift<volume_dim, Frame::Inertial,
203  DataType>> /*meta*/) const noexcept
205  gr::Tags::Shift<volume_dim, Frame::Inertial, DataType>>;
206 
207  template <typename DataType>
208  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
209  double t, const IntermediateVars<DataType>& vars,
210  tmpl::list<::Tags::dt<gr::Tags::Shift<
211  volume_dim, Frame::Inertial, DataType>>> /*meta*/) const
212  noexcept -> tuples::TaggedTuple<
213  ::Tags::dt<gr::Tags::Shift<volume_dim, Frame::Inertial, DataType>>>;
214 
215  template <typename DataType>
216  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
217  double t, const IntermediateVars<DataType>& vars,
218  tmpl::list<DerivShift<DataType>> /*meta*/) const noexcept
220 
221  template <typename DataType>
222  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
223  double t, const IntermediateVars<DataType>& vars,
224  tmpl::list<gr::Tags::SpatialMetric<volume_dim, Frame::Inertial,
225  DataType>> /*meta*/) const
226  noexcept -> tuples::TaggedTuple<
227  gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataType>>;
228 
229  template <typename DataType>
230  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
231  double t, const IntermediateVars<DataType>& vars,
232  tmpl::list<::Tags::dt<gr::Tags::SpatialMetric<
233  volume_dim, Frame::Inertial, DataType>>> /*meta*/) const
234  noexcept -> tuples::TaggedTuple<::Tags::dt<
235  gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataType>>>;
236 
237  template <typename DataType>
238  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& /*x*/,
239  double /*t*/, const IntermediateVars<DataType>& vars,
240  tmpl::list<DerivSpatialMetric<DataType>> /*meta*/) const
242 
243  template <typename DataType>
244  auto variables(
245  const tnsr::I<DataType, volume_dim, Frame::Inertial>& /*x*/, double /*t*/,
246  const IntermediateVars<DataType>& vars,
247  tmpl::list<gr::Tags::SqrtDetSpatialMetric<DataType>> /*meta*/) const
249 
250  template <typename DataType>
251  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
252  double t, const IntermediateVars<DataType>& vars,
253  tmpl::list<gr::Tags::ExtrinsicCurvature<
254  volume_dim, Frame::Inertial, DataType>> /*meta*/) const
255  noexcept -> tuples::TaggedTuple<
256  gr::Tags::ExtrinsicCurvature<volume_dim, Frame::Inertial, DataType>>;
257 
258  template <typename DataType>
259  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
260  double t, const IntermediateVars<DataType>& vars,
262  volume_dim, Frame::Inertial, DataType>> /*meta*/) const
264  volume_dim, Frame::Inertial, DataType>>;
265 
266  template <typename DataType>
267  struct IntermediateVars {
268  IntermediateVars(double amplitude, double wavelength,
269  const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
270  double t) noexcept;
271  DataType h{};
272  DataType dx_h{};
273  DataType sqrt_h{};
274  DataType dx_h_over_2_sqrt_h{};
275  };
276 
277  double amplitude_{1.0};
278  double wavelength_{1.0};
279 };
280 
281 bool operator==(const GaugeWave& lhs, const GaugeWave& rhs) noexcept;
282 bool operator!=(const GaugeWave& lhs, const GaugeWave& rhs) noexcept;
283 } // namespace Solutions
284 } // namespace gr
Definition: Strahlkorper.hpp:14
Gauge wave in flat spacetime.
Definition: GaugeWave.hpp:94
Defines class tuples::TaggedTuple.
Definition: GaugeWave.hpp:106
Definition: Tags.hpp:49
Defines classes and functions for making classes creatable from input files.
Definition: Tags.hpp:59
Inverse of the spatial metric.
Definition: Tags.hpp:36
Prefix indicating a time derivative.
Definition: Prefixes.hpp:30
Definition: GaugeWave.hpp:100
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:29
Holds functions related to general relativity.
Definition: GaugeWave.hpp:27
#define SPECTRE_ALWAYS_INLINE
Always inline a function. Only use this if you benchmarked the code.
Definition: ForceInline.hpp:16
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:273
Definition: Tags.hpp:28
Defines functions computing partial derivatives.
Definition: Tags.hpp:54
Defines macro to always inline a function.
Definition: DataBoxTag.hpp:29
Defines a list of useful type aliases for tensors.
Wraps the template metaprogramming library used (brigand)
Definition: IndexType.hpp:44
Definition: Tags.hpp:148