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"
15 #include "Utilities/TaggedTuple.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
92  * - Wavelength
93  */
94 template <size_t Dim>
95 class GaugeWave : public MarkAsAnalyticSolution {
96  template <typename DataType>
97  struct IntermediateVars;
98 
99  public:
100  static constexpr size_t volume_dim = Dim;
101  struct Amplitude {
102  using type = double;
103  static constexpr Options::String help = {"Amplitude of the gauge wave"};
104  static type upper_bound() noexcept { return 1.; }
105  static type lower_bound() noexcept { return -1.; }
106  };
107  struct Wavelength {
108  using type = double;
109  static constexpr Options::String help = {"Wavelength of the gauge wave"};
110  static type lower_bound() noexcept { return 0.; }
111  };
112 
113  using options = tmpl::list<Amplitude, Wavelength>;
114  static constexpr Options::String help{"Gauge wave in flat spacetime"};
115 
116  GaugeWave(double amplitude, double wavelength,
117  const Options::Context& context = {});
118 
119  GaugeWave() = default;
120  GaugeWave(const GaugeWave& /*rhs*/) = default;
121  GaugeWave& operator=(const GaugeWave& /*rhs*/) = default;
122  GaugeWave(GaugeWave&& /*rhs*/) noexcept = default;
123  GaugeWave& operator=(GaugeWave&& /*rhs*/) noexcept = default;
124  ~GaugeWave() = default;
125 
126  template <typename DataType>
127  using DerivLapse = ::Tags::deriv<gr::Tags::Lapse<DataType>,
128  tmpl::size_t<volume_dim>, Frame::Inertial>;
129  template <typename DataType>
130  using DerivShift =
131  ::Tags::deriv<gr::Tags::Shift<volume_dim, Frame::Inertial, DataType>,
132  tmpl::size_t<volume_dim>, Frame::Inertial>;
133  template <typename DataType>
134  using DerivSpatialMetric = ::Tags::deriv<
135  gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataType>,
136  tmpl::size_t<volume_dim>, Frame::Inertial>;
137 
138  template <typename DataType, typename... Tags>
139  tuples::TaggedTuple<Tags...> variables(
140  const tnsr::I<DataType, volume_dim, Frame::Inertial>& x, double t,
141  tmpl::list<Tags...> /*meta*/) const noexcept {
142  const auto& vars =
143  IntermediateVars<DataType>{amplitude_, wavelength_, x, t};
144  return {get<Tags>(variables(x, t, vars, tmpl::list<Tags>{}))...};
145  }
146 
147  template <typename DataType, typename... Tags>
148  tuples::TaggedTuple<Tags...> variables(
149  const tnsr::I<DataType, volume_dim, Frame::Inertial>& x, double t,
150  const IntermediateVars<DataType>& vars,
151  tmpl::list<Tags...> /*meta*/) const noexcept {
152  static_assert(sizeof...(Tags) > 1,
153  "Unrecognized tag requested. See the function parameters "
154  "for the tag.");
155  return {get<Tags>(variables(x, t, vars, tmpl::list<Tags>{}))...};
156  }
157 
158  template <typename DataType>
159  using tags = tmpl::list<
161  DerivLapse<DataType>,
164  DerivShift<DataType>,
166  ::Tags::dt<
168  DerivSpatialMetric<DataType>, gr::Tags::SqrtDetSpatialMetric<DataType>,
171 
172  // clang-tidy: no runtime references
173  void pup(PUP::er& p) noexcept; // NOLINT
174 
175  SPECTRE_ALWAYS_INLINE double amplitude() const noexcept { return amplitude_; }
176  SPECTRE_ALWAYS_INLINE double wavelength() const noexcept {
177  return wavelength_;
178  }
179 
180  private:
181  template <typename DataType>
182  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
183  double t, const IntermediateVars<DataType>& vars,
184  tmpl::list<gr::Tags::Lapse<DataType>> /*meta*/) const noexcept
185  -> tuples::TaggedTuple<gr::Tags::Lapse<DataType>>;
186 
187  template <typename DataType>
188  auto variables(
189  const tnsr::I<DataType, volume_dim, Frame::Inertial>& x, double t,
190  const IntermediateVars<DataType>& vars,
191  tmpl::list<::Tags::dt<gr::Tags::Lapse<DataType>>> /*meta*/) const noexcept
192  -> tuples::TaggedTuple<::Tags::dt<gr::Tags::Lapse<DataType>>>;
193 
194  template <typename DataType>
195  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
196  double t, const IntermediateVars<DataType>& vars,
197  tmpl::list<DerivLapse<DataType>> /*meta*/) const noexcept
198  -> tuples::TaggedTuple<DerivLapse<DataType>>;
199 
200  template <typename DataType>
201  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
202  double t, const IntermediateVars<DataType>& vars,
203  tmpl::list<gr::Tags::Shift<volume_dim, Frame::Inertial,
204  DataType>> /*meta*/) const noexcept
205  -> tuples::TaggedTuple<
206  gr::Tags::Shift<volume_dim, Frame::Inertial, DataType>>;
207 
208  template <typename DataType>
209  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
210  double t, const IntermediateVars<DataType>& vars,
211  tmpl::list<::Tags::dt<gr::Tags::Shift<
212  volume_dim, Frame::Inertial, DataType>>> /*meta*/) const
213  noexcept -> tuples::TaggedTuple<
214  ::Tags::dt<gr::Tags::Shift<volume_dim, Frame::Inertial, DataType>>>;
215 
216  template <typename DataType>
217  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
218  double t, const IntermediateVars<DataType>& vars,
219  tmpl::list<DerivShift<DataType>> /*meta*/) const noexcept
220  -> tuples::TaggedTuple<DerivShift<DataType>>;
221 
222  template <typename DataType>
223  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
224  double t, const IntermediateVars<DataType>& vars,
225  tmpl::list<gr::Tags::SpatialMetric<volume_dim, Frame::Inertial,
226  DataType>> /*meta*/) const
227  noexcept -> tuples::TaggedTuple<
228  gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataType>>;
229 
230  template <typename DataType>
231  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
232  double t, const IntermediateVars<DataType>& vars,
233  tmpl::list<::Tags::dt<gr::Tags::SpatialMetric<
234  volume_dim, Frame::Inertial, DataType>>> /*meta*/) const
235  noexcept -> tuples::TaggedTuple<::Tags::dt<
236  gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataType>>>;
237 
238  template <typename DataType>
239  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& /*x*/,
240  double /*t*/, const IntermediateVars<DataType>& vars,
241  tmpl::list<DerivSpatialMetric<DataType>> /*meta*/) const
242  noexcept -> tuples::TaggedTuple<DerivSpatialMetric<DataType>>;
243 
244  template <typename DataType>
245  auto variables(
246  const tnsr::I<DataType, volume_dim, Frame::Inertial>& /*x*/, double /*t*/,
247  const IntermediateVars<DataType>& vars,
248  tmpl::list<gr::Tags::SqrtDetSpatialMetric<DataType>> /*meta*/) const
249  noexcept -> tuples::TaggedTuple<gr::Tags::SqrtDetSpatialMetric<DataType>>;
250 
251  template <typename DataType>
252  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
253  double t, const IntermediateVars<DataType>& vars,
254  tmpl::list<gr::Tags::ExtrinsicCurvature<
255  volume_dim, Frame::Inertial, DataType>> /*meta*/) const
256  noexcept -> tuples::TaggedTuple<
257  gr::Tags::ExtrinsicCurvature<volume_dim, Frame::Inertial, DataType>>;
258 
259  template <typename DataType>
260  auto variables(const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
261  double t, const IntermediateVars<DataType>& vars,
262  tmpl::list<gr::Tags::InverseSpatialMetric<
263  volume_dim, Frame::Inertial, DataType>> /*meta*/) const
264  noexcept -> tuples::TaggedTuple<gr::Tags::InverseSpatialMetric<
265  volume_dim, Frame::Inertial, DataType>>;
266 
267  template <typename DataType>
268  struct IntermediateVars {
269  IntermediateVars(double amplitude, double wavelength,
270  const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
271  double t) noexcept;
272  DataType h{};
273  DataType dx_h{};
274  DataType sqrt_h{};
275  DataType dx_h_over_2_sqrt_h{};
276  };
277 
278  double amplitude_{1.0};
279  double wavelength_{1.0};
280 };
281 
282 template <size_t Dim>
283 bool operator==(const GaugeWave<Dim>& lhs, const GaugeWave<Dim>& rhs) noexcept;
284 template <size_t Dim>
285 bool operator!=(const GaugeWave<Dim>& lhs, const GaugeWave<Dim>& rhs) noexcept;
286 } // namespace Solutions
287 } // namespace gr
gr::Solutions::GaugeWave::Amplitude
Definition: GaugeWave.hpp:101
gr::Tags::SpatialMetric
Definition: Tags.hpp:26
std::rel_ops::operator!=
T operator!=(T... args)
Options.hpp
gr::Solutions::GaugeWave::Wavelength
Definition: GaugeWave.hpp:107
Options::Context
Definition: Options.hpp:41
SPECTRE_ALWAYS_INLINE
#define SPECTRE_ALWAYS_INLINE
Definition: ForceInline.hpp:16
cstddef
gr::Solutions::GaugeWave
Gauge wave in flat spacetime.
Definition: GaugeWave.hpp:95
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:271
gr::Tags::Shift
Definition: Tags.hpp:48
tnsr
Type aliases to construct common Tensors.
Definition: TypeAliases.hpp:31
Tags::dt
Prefix indicating a time derivative.
Definition: Prefixes.hpp:29
TypeAliases.hpp
Options::String
const char *const String
The string used in option structs.
Definition: Options.hpp:32
Frame
Definition: IndexType.hpp:36
ForceInline.hpp
gr
Definition: GaugeWave.hpp:27
gr::Tags::ExtrinsicCurvature
Definition: Tags.hpp:110
PartialDerivatives.hpp
gr::Tags::Lapse
Definition: Tags.hpp:52
TMPL.hpp
gr::Tags::InverseSpatialMetric
Inverse of the spatial metric.
Definition: Tags.hpp:33
gr::Tags::SqrtDetSpatialMetric
Definition: Tags.hpp:44