Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <limits>
7 : #include <ostream>
8 :
9 : #include "DataStructures/CachedTempBuffer.hpp"
10 : #include "DataStructures/DataBox/Prefixes.hpp"
11 : #include "DataStructures/DataVector.hpp"
12 : #include "DataStructures/Tensor/Tensor.hpp"
13 : #include "Elliptic/Systems/Xcts/Tags.hpp"
14 : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
15 : #include "Options/String.hpp"
16 : #include "PointwiseFunctions/AnalyticSolutions/RelativisticEuler/TovStar.hpp"
17 : #include "PointwiseFunctions/AnalyticSolutions/Xcts/CommonVariables.hpp"
18 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
19 : #include "PointwiseFunctions/GeneralRelativity/Tags/Conformal.hpp"
20 : #include "PointwiseFunctions/InitialDataUtilities/AnalyticSolution.hpp"
21 : #include "Utilities/Gsl.hpp"
22 : #include "Utilities/Serialization/CharmPupable.hpp"
23 : #include "Utilities/TMPL.hpp"
24 : #include "Utilities/TaggedTuple.hpp"
25 :
26 : /// \cond
27 : namespace PUP {
28 : class er;
29 : } // namespace PUP
30 : /// \endcond
31 :
32 : namespace Xcts::Solutions {
33 : namespace tov_detail {
34 :
35 : using TovCoordinates = RelativisticEuler::Solutions::TovCoordinates;
36 :
37 : template <typename DataType>
38 : using TovVariablesCache = cached_temp_buffer_from_typelist<tmpl::push_back<
39 : common_tags<DataType>,
40 : ::Tags::deriv<gr::Tags::Lapse<DataType>, tmpl::size_t<3>, Frame::Inertial>,
41 : gr::Tags::Conformal<gr::Tags::EnergyDensity<DataType>, 0>,
42 : gr::Tags::Conformal<gr::Tags::StressTrace<DataType>, 0>,
43 : gr::Tags::Conformal<gr::Tags::MomentumDensity<DataType, 3>, 0>>>;
44 :
45 : template <typename DataType>
46 : struct TovVariables : CommonVariables<DataType, TovVariablesCache<DataType>> {
47 : static constexpr size_t Dim = 3;
48 : static constexpr int ConformalMatterScale = 0;
49 : using Cache = TovVariablesCache<DataType>;
50 : using Base = CommonVariables<DataType, TovVariablesCache<DataType>>;
51 : using Base::operator();
52 :
53 : const tnsr::I<DataType, 3>& x;
54 : const DataType& radius;
55 : const RelativisticEuler::Solutions::TovStar& tov_star;
56 :
57 : TovVariables(
58 : std::optional<std::reference_wrapper<const Mesh<Dim>>> local_mesh,
59 : std::optional<std::reference_wrapper<const InverseJacobian<
60 : DataType, Dim, Frame::ElementLogical, Frame::Inertial>>>
61 : local_inv_jacobian,
62 : const tnsr::I<DataType, 3>& local_x, const DataType& local_radius,
63 : const RelativisticEuler::Solutions::TovStar& local_tov_star)
64 : : Base(std::move(local_mesh), std::move(local_inv_jacobian)),
65 : x(local_x),
66 : radius(local_radius),
67 : tov_star(local_tov_star) {}
68 :
69 : void operator()(gsl::not_null<tnsr::ii<DataType, 3>*> conformal_metric,
70 : gsl::not_null<Cache*> cache,
71 : Tags::ConformalMetric<DataType, 3, Frame::Inertial> /*meta*/)
72 : const override;
73 : void operator()(
74 : gsl::not_null<tnsr::II<DataType, 3>*> inv_conformal_metric,
75 : gsl::not_null<Cache*> cache,
76 : Tags::InverseConformalMetric<DataType, 3, Frame::Inertial> /*meta*/)
77 : const override;
78 : void operator()(
79 : gsl::not_null<tnsr::ijj<DataType, 3>*> deriv_conformal_metric,
80 : gsl::not_null<Cache*> cache,
81 : ::Tags::deriv<Tags::ConformalMetric<DataType, 3, Frame::Inertial>,
82 : tmpl::size_t<3>, Frame::Inertial> /*meta*/) const override;
83 : void operator()(
84 : gsl::not_null<tnsr::ii<DataType, 3>*> extrinsic_curvature,
85 : gsl::not_null<Cache*> cache,
86 : gr::Tags::ExtrinsicCurvature<DataType, 3> /*meta*/) const override;
87 : void operator()(
88 : gsl::not_null<Scalar<DataType>*> trace_extrinsic_curvature,
89 : gsl::not_null<Cache*> cache,
90 : gr::Tags::TraceExtrinsicCurvature<DataType> /*meta*/) const override;
91 : void operator()(
92 : gsl::not_null<tnsr::i<DataType, 3>*> deriv_trace_extrinsic_curvature,
93 : gsl::not_null<Cache*> cache,
94 : ::Tags::deriv<gr::Tags::TraceExtrinsicCurvature<DataType>,
95 : tmpl::size_t<3>, Frame::Inertial> /*meta*/) const override;
96 : void operator()(
97 : gsl::not_null<Scalar<DataType>*> dt_trace_extrinsic_curvature,
98 : gsl::not_null<Cache*> cache,
99 : ::Tags::dt<gr::Tags::TraceExtrinsicCurvature<DataType>> /*meta*/)
100 : const override;
101 : void operator()(gsl::not_null<Scalar<DataType>*> conformal_factor,
102 : gsl::not_null<Cache*> cache,
103 : Tags::ConformalFactor<DataType> /*meta*/) const override;
104 : void operator()(
105 : gsl::not_null<Scalar<DataType>*> conformal_factor_minus_one,
106 : gsl::not_null<Cache*> cache,
107 : Tags::ConformalFactorMinusOne<DataType> /*meta*/) const override;
108 : void operator()(
109 : gsl::not_null<tnsr::i<DataType, 3>*> deriv_conformal_factor,
110 : gsl::not_null<Cache*> cache,
111 : ::Tags::deriv<Xcts::Tags::ConformalFactorMinusOne<DataType>,
112 : tmpl::size_t<3>, Frame::Inertial> /*meta*/) const override;
113 : void operator()(gsl::not_null<Scalar<DataType>*> lapse,
114 : gsl::not_null<Cache*> cache,
115 : gr::Tags::Lapse<DataType> /*meta*/) const override;
116 : void operator()(gsl::not_null<tnsr::i<DataType, 3>*> deriv_lapse,
117 : gsl::not_null<Cache*> cache,
118 : ::Tags::deriv<gr::Tags::Lapse<DataType>, tmpl::size_t<3>,
119 : Frame::Inertial> /*meta*/) const;
120 : void operator()(
121 : gsl::not_null<Scalar<DataType>*> lapse_times_conformal_factor,
122 : gsl::not_null<Cache*> cache,
123 : Tags::LapseTimesConformalFactor<DataType> /*meta*/) const override;
124 : void operator()(
125 : gsl::not_null<Scalar<DataType>*> lapse_times_conformal_factor_minus_one,
126 : gsl::not_null<Cache*> cache,
127 : Tags::LapseTimesConformalFactorMinusOne<DataType> /*meta*/)
128 : const override;
129 : void operator()(
130 : gsl::not_null<tnsr::i<DataType, 3>*> deriv_lapse_times_conformal_factor,
131 : gsl::not_null<Cache*> cache,
132 : ::Tags::deriv<Tags::LapseTimesConformalFactorMinusOne<DataType>,
133 : tmpl::size_t<3>, Frame::Inertial> /*meta*/) const override;
134 : void operator()(gsl::not_null<tnsr::I<DataType, 3>*> shift_background,
135 : gsl::not_null<Cache*> cache,
136 : Tags::ShiftBackground<DataType, 3, Frame::Inertial> /*meta*/)
137 : const override;
138 : void operator()(gsl::not_null<tnsr::II<DataType, 3, Frame::Inertial>*>
139 : longitudinal_shift_background_minus_dt_conformal_metric,
140 : gsl::not_null<Cache*> cache,
141 : Tags::LongitudinalShiftBackgroundMinusDtConformalMetric<
142 : DataType, 3, Frame::Inertial> /*meta*/) const override;
143 : void operator()(
144 : gsl::not_null<tnsr::I<DataType, 3>*> shift_excess,
145 : gsl::not_null<Cache*> cache,
146 : Tags::ShiftExcess<DataType, 3, Frame::Inertial> /*meta*/) const override;
147 : void operator()(
148 : gsl::not_null<tnsr::iJ<DataType, 3>*> deriv_shift_excess,
149 : gsl::not_null<Cache*> cache,
150 : ::Tags::deriv<Tags::ShiftExcess<DataType, 3, Frame::Inertial>,
151 : tmpl::size_t<3>, Frame::Inertial> /*meta*/) const override;
152 : void operator()(gsl::not_null<Scalar<DataType>*> energy_density,
153 : gsl::not_null<Cache*> cache,
154 : gr::Tags::Conformal<gr::Tags::EnergyDensity<DataType>,
155 : ConformalMatterScale> /*meta*/) const;
156 : void operator()(gsl::not_null<Scalar<DataType>*> stress_trace,
157 : gsl::not_null<Cache*> cache,
158 : gr::Tags::Conformal<gr::Tags::StressTrace<DataType>,
159 : ConformalMatterScale> /*meta*/) const;
160 : void operator()(gsl::not_null<tnsr::I<DataType, 3>*> momentum_density,
161 : gsl::not_null<Cache*> cache,
162 : gr::Tags::Conformal<gr::Tags::MomentumDensity<DataType, 3>,
163 : ConformalMatterScale> /*meta*/) const;
164 :
165 : private:
166 : template <typename Tag>
167 : typename Tag::type get_tov_var(Tag /*meta*/) const {
168 : // Possible optimization: Access the cache of the RelEuler::TovStar solution
169 : // so its intermediate quantities don't have to be re-computed repeatedly
170 : return get<Tag>(tov_star.variables(
171 : x, std::numeric_limits<double>::signaling_NaN(), tmpl::list<Tag>{}));
172 : }
173 : };
174 :
175 : } // namespace tov_detail
176 :
177 : /*!
178 : * \brief TOV solution to the XCTS equations
179 : *
180 : * \see RelativisticEuler::Solutions::TovStar
181 : * \see gr::Solutions::TovSolution
182 : */
183 1 : class TovStar : public elliptic::analytic_data::AnalyticSolution {
184 : private:
185 0 : using RelEulerTovStar = RelativisticEuler::Solutions::TovStar;
186 :
187 : public:
188 0 : using options = RelEulerTovStar::options;
189 0 : static constexpr Options::String help = RelEulerTovStar::help;
190 :
191 0 : TovStar() = default;
192 0 : TovStar(const TovStar&) = default;
193 0 : TovStar& operator=(const TovStar&) = default;
194 0 : TovStar(TovStar&&) = default;
195 0 : TovStar& operator=(TovStar&&) = default;
196 0 : ~TovStar() = default;
197 :
198 0 : TovStar(double central_rest_mass_density,
199 : std::unique_ptr<EquationsOfState::EquationOfState<true, 1>>
200 : equation_of_state,
201 : const RelativisticEuler::Solutions::TovCoordinates coordinate_system)
202 : : tov_star(central_rest_mass_density, std::move(equation_of_state),
203 : coordinate_system) {}
204 :
205 0 : const EquationsOfState::EquationOfState<true, 1>& equation_of_state() const {
206 : return tov_star.equation_of_state();
207 : }
208 :
209 0 : const RelativisticEuler::Solutions::TovSolution& radial_solution() const {
210 : return tov_star.radial_solution();
211 : }
212 :
213 : /// \cond
214 : explicit TovStar(CkMigrateMessage* m)
215 : : elliptic::analytic_data::AnalyticSolution(m) {}
216 : using PUP::able::register_constructor;
217 : WRAPPED_PUPable_decl_template(TovStar);
218 : std::unique_ptr<elliptic::analytic_data::AnalyticSolution> get_clone()
219 : const override {
220 : return std::make_unique<TovStar>(*this);
221 : }
222 : /// \endcond
223 :
224 : template <typename DataType>
225 0 : using tags = typename tov_detail::TovVariablesCache<DataType>::tags_list;
226 :
227 : template <typename DataType, typename... RequestedTags>
228 0 : tuples::TaggedTuple<RequestedTags...> variables(
229 : const tnsr::I<DataType, 3, Frame::Inertial>& x,
230 : tmpl::list<RequestedTags...> /*meta*/) const {
231 : return variables_impl<DataType>(x, std::nullopt, std::nullopt,
232 : tmpl::list<RequestedTags...>{});
233 : }
234 :
235 : template <typename... RequestedTags>
236 0 : tuples::TaggedTuple<RequestedTags...> variables(
237 : const tnsr::I<DataVector, 3, Frame::Inertial>& x, const Mesh<3>& mesh,
238 : const InverseJacobian<DataVector, 3, Frame::ElementLogical,
239 : Frame::Inertial>& inv_jacobian,
240 : tmpl::list<RequestedTags...> /*meta*/) const {
241 : return variables_impl<DataVector>(x, mesh, inv_jacobian,
242 : tmpl::list<RequestedTags...>{});
243 : }
244 :
245 : // NOLINTNEXTLINE(google-runtime-references)
246 0 : void pup(PUP::er& p) override {
247 : elliptic::analytic_data::AnalyticSolution::pup(p);
248 : p | tov_star;
249 : }
250 :
251 : private:
252 : template <typename DataType, typename... RequestedTags>
253 0 : tuples::TaggedTuple<RequestedTags...> variables_impl(
254 : const tnsr::I<DataType, 3, Frame::Inertial>& x,
255 : std::optional<std::reference_wrapper<const Mesh<3>>> mesh,
256 : std::optional<std::reference_wrapper<const InverseJacobian<
257 : DataType, 3, Frame::ElementLogical, Frame::Inertial>>>
258 : inv_jacobian,
259 : tmpl::list<RequestedTags...> /*meta*/) const {
260 : using VarsComputer = tov_detail::TovVariables<DataType>;
261 : typename VarsComputer::Cache cache{get_size(*x.begin())};
262 : const DataType radius = get(magnitude(x));
263 : const VarsComputer computer{std::move(mesh), std::move(inv_jacobian), x,
264 : radius, tov_star};
265 : using unrequested_hydro_tags =
266 : tmpl::list_difference<hydro_tags<DataType>,
267 : tmpl::list<RequestedTags...>>;
268 : using requested_hydro_tags =
269 : tmpl::list_difference<hydro_tags<DataType>, unrequested_hydro_tags>;
270 : tuples::tagged_tuple_from_typelist<requested_hydro_tags> hydro_vars;
271 : if constexpr (not std::is_same_v<requested_hydro_tags, tmpl::list<>>) {
272 : hydro_vars =
273 : tov_star.variables(x, std::numeric_limits<double>::signaling_NaN(),
274 : requested_hydro_tags{});
275 : }
276 : const auto get_var = [&cache, &computer, &hydro_vars](auto tag_v) {
277 : using tag = std::decay_t<decltype(tag_v)>;
278 : if constexpr (tmpl::list_contains_v<hydro_tags<DataType>, tag>) {
279 : (void)cache;
280 : (void)computer;
281 : return get<tag>(hydro_vars);
282 : } else {
283 : (void)hydro_vars;
284 : return cache.get_var(computer, tag{});
285 : }
286 : };
287 : return {get_var(RequestedTags{})...};
288 : }
289 :
290 0 : friend bool operator==(const TovStar& lhs, const TovStar& rhs) {
291 : return lhs.tov_star == rhs.tov_star;
292 : }
293 :
294 : // Instead of inheriting from the RelEuler::TovStar we use an aggregate
295 : // pattern to avoid multiple-inheritance issues.
296 0 : RelativisticEuler::Solutions::TovStar tov_star{};
297 : };
298 :
299 0 : inline bool operator!=(const TovStar& lhs, const TovStar& rhs) {
300 : return not(lhs == rhs);
301 : }
302 :
303 : } // namespace Xcts::Solutions
|