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 : #include <functional>
8 : #include <memory>
9 : #include <optional>
10 : #include <pup.h>
11 :
12 : #include "DataStructures/CachedTempBuffer.hpp"
13 : #include "DataStructures/DataBox/Prefixes.hpp"
14 : #include "DataStructures/DataVector.hpp"
15 : #include "DataStructures/TaggedTuple.hpp"
16 : #include "DataStructures/Tensor/Tensor.hpp"
17 : #include "Elliptic/Systems/Xcts/Tags.hpp"
18 : #include "NumericalAlgorithms/LinearOperators/Divergence.hpp"
19 : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
20 : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
21 : #include "Options/String.hpp"
22 : #include "PointwiseFunctions/AnalyticData/Xcts/CommonVariables.hpp"
23 : #include "PointwiseFunctions/AnalyticSolutions/GeneralRelativity/KerrSchild.hpp"
24 : #include "PointwiseFunctions/AnalyticSolutions/GeneralRelativity/TeukolskyWave.hpp"
25 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
26 : #include "PointwiseFunctions/GeneralRelativity/Tags/Conformal.hpp"
27 : #include "PointwiseFunctions/InitialDataUtilities/Background.hpp"
28 : #include "PointwiseFunctions/InitialDataUtilities/InitialGuess.hpp"
29 : #include "Utilities/Gsl.hpp"
30 : #include "Utilities/Requires.hpp"
31 : #include "Utilities/Serialization/CharmPupable.hpp"
32 : #include "Utilities/TMPL.hpp"
33 :
34 : /// \cond
35 : namespace PUP {
36 : class er;
37 : } // namespace PUP
38 : /// \endcond
39 :
40 : namespace Xcts::AnalyticData {
41 : namespace detail {
42 :
43 : template <typename DataType>
44 : using KerrSchildTeukolskyVariablesCache =
45 : cached_temp_buffer_from_typelist<tmpl::append<
46 : common_tags<DataType>,
47 : tmpl::list<
48 : gr::Tags::Conformal<gr::Tags::EnergyDensity<DataType>, 0>,
49 : gr::Tags::Conformal<gr::Tags::StressTrace<DataType>, 0>,
50 : gr::Tags::Conformal<gr::Tags::MomentumDensity<DataType, 3>, 0>,
51 : Tags::ConformalFactorMinusOne<DataType>,
52 : Tags::LapseTimesConformalFactorMinusOne<DataType>,
53 : Tags::ShiftExcess<DataType, 3, Frame::Inertial>>>>;
54 :
55 : template <typename DataType>
56 : struct KerrSchildTeukolskyVariables
57 : : CommonVariables<DataType, KerrSchildTeukolskyVariablesCache<DataType>> {
58 : static constexpr size_t Dim = 3;
59 : using Cache = KerrSchildTeukolskyVariablesCache<DataType>;
60 : using Base = CommonVariables<DataType, Cache>;
61 : using Base::operator();
62 :
63 : using kerr_schild_tags =
64 : tmpl::list<gr::Tags::SpatialMetric<DataType, Dim>,
65 : gr::Tags::InverseSpatialMetric<DataType, Dim>,
66 : gr::Tags::Lapse<DataType>, gr::Tags::Shift<DataType, Dim>,
67 : gr::Tags::ExtrinsicCurvature<DataType, Dim>>;
68 :
69 : using teukolsky_tags = tmpl::list<
70 : gr::Tags::SpatialMetric<DataType, Dim, Frame::Inertial>,
71 : ::Tags::dt<gr::Tags::SpatialMetric<DataType, Dim, Frame::Inertial>>>;
72 :
73 : KerrSchildTeukolskyVariables(
74 : std::optional<std::reference_wrapper<const Mesh<Dim>>> local_mesh,
75 : std::optional<std::reference_wrapper<const InverseJacobian<
76 : DataType, Dim, Frame::ElementLogical, Frame::Inertial>>>
77 : local_inv_jacobian,
78 : const tnsr::I<DataType, Dim>& local_x,
79 : const tuples::tagged_tuple_from_typelist<kerr_schild_tags>&
80 : local_kerr_schild_vars,
81 : const tuples::tagged_tuple_from_typelist<teukolsky_tags>&
82 : local_teukolsky_vars)
83 : : Base(std::move(local_mesh), std::move(local_inv_jacobian)),
84 : x(local_x),
85 : kerr_schild_vars(local_kerr_schild_vars),
86 : teukolsky_vars(local_teukolsky_vars) {}
87 :
88 : std::reference_wrapper<const tnsr::I<DataType, Dim>> x;
89 : std::reference_wrapper<
90 : const tuples::tagged_tuple_from_typelist<kerr_schild_tags>>
91 : kerr_schild_vars;
92 : std::reference_wrapper<
93 : const tuples::tagged_tuple_from_typelist<teukolsky_tags>>
94 : teukolsky_vars;
95 :
96 : void operator()(
97 : gsl::not_null<tnsr::ii<DataType, Dim>*> conformal_metric,
98 : gsl::not_null<Cache*> cache,
99 : Xcts::Tags::ConformalMetric<DataType, Dim, Frame::Inertial> /*meta*/)
100 : const override;
101 : void operator()(
102 : gsl::not_null<tnsr::ijj<DataType, Dim>*> deriv_conformal_metric,
103 : gsl::not_null<Cache*> cache,
104 : ::Tags::deriv<Xcts::Tags::ConformalMetric<DataType, Dim, Frame::Inertial>,
105 : tmpl::size_t<Dim>, Frame::Inertial> /*meta*/)
106 : const override;
107 : void operator()(
108 : gsl::not_null<Scalar<DataType>*> trace_extrinsic_curvature,
109 : gsl::not_null<Cache*> cache,
110 : gr::Tags::TraceExtrinsicCurvature<DataType> /*meta*/) const override;
111 : void operator()(
112 : gsl::not_null<Scalar<DataType>*> dt_trace_extrinsic_curvature,
113 : gsl::not_null<Cache*> cache,
114 : ::Tags::dt<gr::Tags::TraceExtrinsicCurvature<DataType>> /*meta*/)
115 : const override;
116 : void operator()(gsl::not_null<Scalar<DataType>*> conformal_factor_minus_one,
117 : gsl::not_null<Cache*> cache,
118 : Xcts::Tags::ConformalFactorMinusOne<DataType> /*meta*/) const;
119 : void operator()(
120 : gsl::not_null<Scalar<DataType>*> lapse_times_conformal_factor_minus_one,
121 : gsl::not_null<Cache*> cache,
122 : Xcts::Tags::LapseTimesConformalFactorMinusOne<DataType> /*meta*/) const;
123 : void operator()(
124 : gsl::not_null<tnsr::I<DataType, Dim>*> shift_background,
125 : gsl::not_null<Cache*> cache,
126 : Xcts::Tags::ShiftBackground<DataType, Dim, Frame::Inertial> /*meta*/)
127 : const override;
128 : void operator()(
129 : gsl::not_null<tnsr::iJ<DataType, Dim>*> deriv_shift_background,
130 : gsl::not_null<Cache*> cache,
131 : ::Tags::deriv<Xcts::Tags::ShiftBackground<DataType, Dim, Frame::Inertial>,
132 : tmpl::size_t<Dim>, Frame::Inertial> /*meta*/)
133 : const override;
134 : void operator()(gsl::not_null<tnsr::II<DataType, Dim, Frame::Inertial>*>
135 : longitudinal_shift_background_minus_dt_conformal_metric,
136 : gsl::not_null<Cache*> cache,
137 : Xcts::Tags::LongitudinalShiftBackgroundMinusDtConformalMetric<
138 : DataType, Dim, Frame::Inertial> /*meta*/) const override;
139 : void operator()(
140 : gsl::not_null<tnsr::I<DataType, Dim>*> shift_excess,
141 : gsl::not_null<Cache*> cache,
142 : Xcts::Tags::ShiftExcess<DataType, Dim, Frame::Inertial> /*meta*/) const;
143 : void operator()(
144 : gsl::not_null<Scalar<DataType>*> energy_density,
145 : gsl::not_null<Cache*> cache,
146 : gr::Tags::Conformal<gr::Tags::EnergyDensity<DataType>, 0> /*meta*/) const;
147 : void operator()(
148 : gsl::not_null<Scalar<DataType>*> stress_trace,
149 : gsl::not_null<Cache*> cache,
150 : gr::Tags::Conformal<gr::Tags::StressTrace<DataType>, 0> /*meta*/) const;
151 : void operator()(gsl::not_null<tnsr::I<DataType, Dim>*> momentum_density,
152 : gsl::not_null<Cache*> cache,
153 : gr::Tags::Conformal<gr::Tags::MomentumDensity<DataType, Dim>,
154 : 0> /*meta*/) const;
155 : };
156 :
157 : } // namespace detail
158 :
159 : /*!
160 : * \brief Kerr-Schild plus a Teukolsky perturbation in the conformal
161 : * metric.
162 : *
163 : * This solution does not satisfy the constraint equations itself; it is
164 : * intended for supplying the free data and Dirichlet boundary conditions
165 : * needed to solve the XCTS equations for initial data containing a
166 : * Kerr-Schild black hole plus a gravitational-wave pulse.
167 : * In this solution, the Kerr-Schild solution supplies the lapse, shift, and
168 : * trace of the extrinsic curvature, while the Teukolsky wave at \f$t=0\f$ is
169 : * added only to the conformal spatial metric and its time derivative. The
170 : * spatial derivative of the conformal spatial metric is computed using
171 : * numerical partial derivatives.
172 : */
173 1 : class KerrSchildTeukolsky : public elliptic::analytic_data::Background,
174 : public elliptic::analytic_data::InitialGuess {
175 : public:
176 0 : static constexpr size_t Dim = 3;
177 :
178 : template <typename DataType>
179 0 : using tags =
180 : typename detail::KerrSchildTeukolskyVariablesCache<DataType>::tags_list;
181 :
182 0 : struct KerrSchild {
183 0 : using type = gr::Solutions::KerrSchild;
184 0 : static constexpr Options::String help{
185 : "Regular Cartesian Kerr-Schild black hole"};
186 : };
187 0 : struct TeukolskyWave {
188 0 : using type = gr::Solutions::TeukolskyWave;
189 0 : static constexpr Options::String help{
190 : "Teukolsky perturbation added to the conformal metric"};
191 : };
192 :
193 0 : using options = tmpl::list<KerrSchild, TeukolskyWave>;
194 0 : static constexpr Options::String help{
195 : "Kerr-Schild black hole with a Teukolsky perturbation in the XCTS "
196 : "conformal metric."};
197 :
198 0 : KerrSchildTeukolsky() = default;
199 0 : KerrSchildTeukolsky(const KerrSchildTeukolsky&) = default;
200 0 : KerrSchildTeukolsky& operator=(const KerrSchildTeukolsky&) = default;
201 0 : KerrSchildTeukolsky(KerrSchildTeukolsky&&) = default;
202 0 : KerrSchildTeukolsky& operator=(KerrSchildTeukolsky&&) = default;
203 0 : ~KerrSchildTeukolsky() override = default;
204 :
205 0 : KerrSchildTeukolsky(gr::Solutions::KerrSchild kerr_schild,
206 : const gr::Solutions::TeukolskyWave& teukolsky_wave);
207 :
208 0 : const gr::Solutions::KerrSchild& kerr_schild() const { return kerr_schild_; }
209 0 : const gr::Solutions::TeukolskyWave& teukolsky_wave() const {
210 : return teukolsky_wave_;
211 : }
212 :
213 : /// \cond
214 : explicit KerrSchildTeukolsky(CkMigrateMessage* m)
215 : : elliptic::analytic_data::Background(m),
216 : elliptic::analytic_data::InitialGuess(m) {}
217 : using PUP::able::register_constructor;
218 : WRAPPED_PUPable_decl_template(KerrSchildTeukolsky);
219 : /// \endcond
220 :
221 : template <typename DataType, typename... RequestedTags,
222 : Requires<tmpl2::flat_all_v<tmpl::list_contains_v<
223 : tags<DataType>, RequestedTags>...>> = nullptr>
224 0 : tuples::TaggedTuple<RequestedTags...> variables(
225 : const tnsr::I<DataType, Dim, Frame::Inertial>& x,
226 : tmpl::list<RequestedTags...> /*meta*/) const {
227 : return variables_impl<DataType>(x, std::nullopt, std::nullopt,
228 : tmpl::list<RequestedTags...>{});
229 : }
230 :
231 : template <typename... RequestedTags,
232 : Requires<tmpl2::flat_all_v<tmpl::list_contains_v<
233 : tags<DataVector>, RequestedTags>...>> = nullptr>
234 0 : tuples::TaggedTuple<RequestedTags...> variables(
235 : const tnsr::I<DataVector, Dim, Frame::Inertial>& x, const Mesh<Dim>& mesh,
236 : const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
237 : Frame::Inertial>& inv_jacobian,
238 : tmpl::list<RequestedTags...> /*meta*/) const {
239 : return variables_impl<DataVector>(x, mesh, inv_jacobian,
240 : tmpl::list<RequestedTags...>{});
241 : }
242 :
243 0 : void pup(PUP::er& p) override;
244 :
245 : private:
246 : template <typename DataType, typename... RequestedTags>
247 0 : tuples::TaggedTuple<RequestedTags...> variables_impl(
248 : const tnsr::I<DataType, Dim, Frame::Inertial>& x,
249 : std::optional<std::reference_wrapper<const Mesh<Dim>>> mesh,
250 : std::optional<std::reference_wrapper<const InverseJacobian<
251 : DataType, Dim, Frame::ElementLogical, Frame::Inertial>>>
252 : inv_jacobian,
253 : tmpl::list<RequestedTags...> /*meta*/) const {
254 : using VarsComputer = detail::KerrSchildTeukolskyVariables<DataType>;
255 : const auto kerr_schild_vars = kerr_schild_.variables(
256 : x, 0., typename VarsComputer::kerr_schild_tags{});
257 : const auto teukolsky_vars = teukolsky_wave_.variables(
258 : x, 0., typename VarsComputer::teukolsky_tags{});
259 : const size_t num_points = get_size(*x.begin());
260 : typename VarsComputer::Cache cache{num_points};
261 : VarsComputer computer{mesh, inv_jacobian, x, kerr_schild_vars,
262 : teukolsky_vars};
263 : const auto get_var = [&cache, &computer](auto tag_v) {
264 : using tag = std::decay_t<decltype(tag_v)>;
265 : return cache.get_var(computer, tag{});
266 : };
267 : return {get_var(RequestedTags{})...};
268 : }
269 :
270 0 : friend bool operator==(const KerrSchildTeukolsky& lhs,
271 : const KerrSchildTeukolsky& rhs);
272 :
273 0 : gr::Solutions::KerrSchild kerr_schild_{};
274 0 : gr::Solutions::TeukolskyWave teukolsky_wave_{};
275 : };
276 :
277 0 : bool operator==(const KerrSchildTeukolsky& lhs, const KerrSchildTeukolsky& rhs);
278 0 : bool operator!=(const KerrSchildTeukolsky& lhs, const KerrSchildTeukolsky& rhs);
279 :
280 : } // namespace Xcts::AnalyticData
|