Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 :
8 : #include "DataStructures/Tensor/TypeAliases.hpp"
9 : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
10 : #include "Options/Options.hpp"
11 : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
12 : #include "PointwiseFunctions/GeneralRelativity/TagsDeclarations.hpp"
13 : #include "Utilities/ForceInline.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 1 : namespace gr {
28 1 : 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 1 : class GaugeWave : public MarkAsAnalyticSolution {
96 : template <typename DataType>
97 0 : struct IntermediateVars;
98 :
99 : public:
100 0 : static constexpr size_t volume_dim = Dim;
101 0 : struct Amplitude {
102 0 : using type = double;
103 0 : static constexpr Options::String help = {"Amplitude of the gauge wave"};
104 0 : static type upper_bound() noexcept { return 1.; }
105 0 : static type lower_bound() noexcept { return -1.; }
106 : };
107 0 : struct Wavelength {
108 0 : using type = double;
109 0 : static constexpr Options::String help = {"Wavelength of the gauge wave"};
110 0 : static type lower_bound() noexcept { return 0.; }
111 : };
112 :
113 0 : using options = tmpl::list<Amplitude, Wavelength>;
114 0 : static constexpr Options::String help{"Gauge wave in flat spacetime"};
115 :
116 0 : GaugeWave(double amplitude, double wavelength,
117 : const Options::Context& context = {});
118 :
119 0 : GaugeWave() = default;
120 0 : GaugeWave(const GaugeWave& /*rhs*/) = default;
121 0 : GaugeWave& operator=(const GaugeWave& /*rhs*/) = default;
122 0 : GaugeWave(GaugeWave&& /*rhs*/) noexcept = default;
123 0 : GaugeWave& operator=(GaugeWave&& /*rhs*/) noexcept = default;
124 0 : ~GaugeWave() = default;
125 :
126 : template <typename DataType>
127 0 : using DerivLapse = ::Tags::deriv<gr::Tags::Lapse<DataType>,
128 : tmpl::size_t<volume_dim>, Frame::Inertial>;
129 : template <typename DataType>
130 0 : 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 0 : 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 0 : 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 0 : 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 0 : using tags = tmpl::list<
160 : gr::Tags::Lapse<DataType>, ::Tags::dt<gr::Tags::Lapse<DataType>>,
161 : DerivLapse<DataType>,
162 : gr::Tags::Shift<volume_dim, Frame::Inertial, DataType>,
163 : ::Tags::dt<gr::Tags::Shift<volume_dim, Frame::Inertial, DataType>>,
164 : DerivShift<DataType>,
165 : gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataType>,
166 : ::Tags::dt<
167 : gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataType>>,
168 : DerivSpatialMetric<DataType>, gr::Tags::SqrtDetSpatialMetric<DataType>,
169 : gr::Tags::ExtrinsicCurvature<volume_dim, Frame::Inertial, DataType>,
170 : gr::Tags::InverseSpatialMetric<volume_dim, Frame::Inertial, DataType>>;
171 :
172 : // clang-tidy: no runtime references
173 0 : void pup(PUP::er& p) noexcept; // NOLINT
174 :
175 0 : SPECTRE_ALWAYS_INLINE double amplitude() const noexcept { return amplitude_; }
176 0 : SPECTRE_ALWAYS_INLINE double wavelength() const noexcept {
177 : return wavelength_;
178 : }
179 :
180 : private:
181 : template <typename DataType>
182 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : IntermediateVars(double amplitude, double wavelength,
270 : const tnsr::I<DataType, volume_dim, Frame::Inertial>& x,
271 : double t) noexcept;
272 0 : DataType h{};
273 0 : DataType dx_h{};
274 0 : DataType sqrt_h{};
275 0 : DataType dx_h_over_2_sqrt_h{};
276 : };
277 :
278 0 : double amplitude_{1.0};
279 0 : double wavelength_{1.0};
280 : };
281 :
282 : template <size_t Dim>
283 0 : bool operator==(const GaugeWave<Dim>& lhs, const GaugeWave<Dim>& rhs) noexcept;
284 : template <size_t Dim>
285 0 : bool operator!=(const GaugeWave<Dim>& lhs, const GaugeWave<Dim>& rhs) noexcept;
286 : } // namespace Solutions
287 : } // namespace gr
|