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