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/CachedTempBuffer.hpp"
9 : #include "DataStructures/DataBox/Prefixes.hpp"
10 : #include "DataStructures/DataBox/Tag.hpp"
11 : #include "DataStructures/DataVector.hpp"
12 : #include "DataStructures/Tensor/Tensor.hpp"
13 : #include "DataStructures/VariablesTag.hpp"
14 : #include "Domain/Tags.hpp"
15 : #include "Elliptic/Systems/Xcts/Tags.hpp"
16 : #include "NumericalAlgorithms/LinearOperators/Divergence.hpp"
17 : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
18 : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
19 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
20 : #include "Utilities/Gsl.hpp"
21 : #include "Utilities/TMPL.hpp"
22 :
23 : namespace Xcts {
24 :
25 : namespace detail {
26 : template <typename DataType>
27 : struct ConformalLaplacianOfConformalFactor : db::SimpleTag {
28 : using type = Scalar<DataType>;
29 : };
30 : template <typename DataType>
31 : struct LongitudinalShiftMinusDtConformalMetric : db::SimpleTag {
32 : using type = tnsr::II<DataType, 3>;
33 : };
34 : } // namespace detail
35 :
36 : /// General-relativistic 3+1 quantities computed from XCTS variables.
37 1 : using SpacetimeQuantities = CachedTempBuffer<
38 : Tags::ConformalFactor<DataVector>,
39 : Tags::LapseTimesConformalFactor<DataVector>,
40 : // Derivatives of XCTS variables
41 : ::Tags::deriv<Tags::ConformalFactor<DataVector>, tmpl::size_t<3>,
42 : Frame::Inertial>,
43 : // Note: this is the _covariant_ second derivative of the conformal factor
44 : // (includes Christoffel symbols)
45 : ::Tags::deriv<::Tags::deriv<Tags::ConformalFactor<DataVector>,
46 : tmpl::size_t<3>, Frame::Inertial>,
47 : tmpl::size_t<3>, Frame::Inertial>,
48 : detail::ConformalLaplacianOfConformalFactor<DataVector>,
49 : ::Tags::deriv<Tags::LapseTimesConformalFactor<DataVector>, tmpl::size_t<3>,
50 : Frame::Inertial>,
51 : ::Tags::deriv<Tags::ShiftExcess<DataVector, 3, Frame::Inertial>,
52 : tmpl::size_t<3>, Frame::Inertial>,
53 : Xcts::Tags::ShiftStrain<DataVector, 3, Frame::Inertial>,
54 : Xcts::Tags::LongitudinalShiftExcess<DataVector, 3, Frame::Inertial>,
55 : ::Tags::div<Tags::LongitudinalShiftExcess<DataVector, 3, Frame::Inertial>>,
56 : detail::LongitudinalShiftMinusDtConformalMetric<DataVector>,
57 : // ADM quantities
58 : gr::Tags::SpatialMetric<DataVector, 3>,
59 : gr::Tags::InverseSpatialMetric<DataVector, 3>,
60 : ::Tags::deriv<gr::Tags::InverseSpatialMetric<DataVector, 3>,
61 : tmpl::size_t<3>, Frame::Inertial>,
62 : gr::Tags::Lapse<DataVector>,
63 : ::Tags::deriv<gr::Tags::Lapse<DataVector>, tmpl::size_t<3>,
64 : Frame::Inertial>,
65 : gr::Tags::Shift<DataVector, 3>,
66 : ::Tags::deriv<gr::Tags::Shift<DataVector, 3>, tmpl::size_t<3>,
67 : Frame::Inertial>,
68 : gr::Tags::ExtrinsicCurvature<DataVector, 3>,
69 : gr::Tags::SpatialChristoffelSecondKind<DataVector, 3>,
70 : gr::Tags::SpatialRicci<DataVector, 3>,
71 : // Constraints
72 : gr::Tags::HamiltonianConstraint<DataVector>,
73 : gr::Tags::MomentumConstraint<DataVector, 3>>;
74 :
75 : /// `CachedTempBuffer` computer class for 3+1 quantities from XCTS variables.
76 : /// See `Xcts::SpacetimeQuantities`.
77 1 : struct SpacetimeQuantitiesComputer {
78 0 : using Cache = SpacetimeQuantities;
79 :
80 0 : void operator()(gsl::not_null<Scalar<DataVector>*> conformal_factor,
81 : gsl::not_null<Cache*> cache,
82 : Tags::ConformalFactor<DataVector> /*meta*/) const;
83 0 : void operator()(
84 : gsl::not_null<Scalar<DataVector>*> lapse_times_conformal_factor,
85 : gsl::not_null<Cache*> cache,
86 : Tags::LapseTimesConformalFactor<DataVector> /*meta*/) const;
87 0 : void operator()(gsl::not_null<tnsr::ii<DataVector, 3>*> spatial_metric,
88 : gsl::not_null<Cache*> cache,
89 : gr::Tags::SpatialMetric<DataVector, 3> /*meta*/) const;
90 0 : void operator()(gsl::not_null<tnsr::II<DataVector, 3>*> inv_spatial_metric,
91 : gsl::not_null<Cache*> cache,
92 : gr::Tags::InverseSpatialMetric<DataVector, 3> /*meta*/) const;
93 0 : void operator()(
94 : gsl::not_null<tnsr::iJJ<DataVector, 3>*> deriv_inv_spatial_metric,
95 : gsl::not_null<Cache*> cache,
96 : ::Tags::deriv<gr::Tags::InverseSpatialMetric<DataVector, 3>,
97 : tmpl::size_t<3>, Frame::Inertial> /*meta*/) const;
98 0 : void operator()(
99 : gsl::not_null<tnsr::i<DataVector, 3>*> deriv_conformal_factor,
100 : gsl::not_null<Cache*> cache,
101 : ::Tags::deriv<Tags::ConformalFactor<DataVector>, tmpl::size_t<3>,
102 : Frame::Inertial> /*meta*/) const;
103 0 : void operator()(
104 : gsl::not_null<tnsr::Ijj<DataVector, 3>*> spatial_christoffel_second_kind,
105 : gsl::not_null<Cache*> cache,
106 : gr::Tags::SpatialChristoffelSecondKind<DataVector, 3> /*meta*/) const;
107 0 : void operator()(
108 : gsl::not_null<tnsr::ij<DataVector, 3>*> deriv2_conformal_factor,
109 : gsl::not_null<Cache*> cache,
110 : ::Tags::deriv<::Tags::deriv<Tags::ConformalFactor<DataVector>,
111 : tmpl::size_t<3>, Frame::Inertial>,
112 : tmpl::size_t<3>, Frame::Inertial> /*meta*/) const;
113 0 : void operator()(
114 : gsl::not_null<Scalar<DataVector>*>
115 : conformal_laplacian_of_conformal_factor,
116 : gsl::not_null<Cache*> cache,
117 : detail::ConformalLaplacianOfConformalFactor<DataVector> /*meta*/) const;
118 0 : void operator()(gsl::not_null<tnsr::ii<DataVector, 3>*> spatial_ricci,
119 : gsl::not_null<Cache*> cache,
120 : gr::Tags::SpatialRicci<DataVector, 3> /*meta*/) const;
121 0 : void operator()(
122 : gsl::not_null<tnsr::i<DataVector, 3>*> deriv_lapse_times_conformal_factor,
123 : gsl::not_null<Cache*> cache,
124 : ::Tags::deriv<Tags::LapseTimesConformalFactor<DataVector>,
125 : tmpl::size_t<3>, Frame::Inertial> /*meta*/) const;
126 0 : void operator()(gsl::not_null<Scalar<DataVector>*> lapse,
127 : gsl::not_null<Cache*> cache,
128 : gr::Tags::Lapse<DataVector> /*meta*/) const;
129 0 : void operator()(gsl::not_null<tnsr::i<DataVector, 3>*> deriv_lapse,
130 : gsl::not_null<Cache*> cache,
131 : ::Tags::deriv<gr::Tags::Lapse<DataVector>, tmpl::size_t<3>,
132 : Frame::Inertial> /*meta*/) const;
133 0 : void operator()(gsl::not_null<tnsr::I<DataVector, 3>*> shift,
134 : gsl::not_null<Cache*> cache,
135 : gr::Tags::Shift<DataVector, 3> /*meta*/) const;
136 0 : void operator()(
137 : gsl::not_null<tnsr::iJ<DataVector, 3>*> deriv_shift_excess,
138 : gsl::not_null<Cache*> cache,
139 : ::Tags::deriv<Tags::ShiftExcess<DataVector, 3, Frame::Inertial>,
140 : tmpl::size_t<3>, Frame::Inertial> /*meta*/) const;
141 0 : void operator()(gsl::not_null<tnsr::iJ<DataVector, 3>*> deriv_shift,
142 : gsl::not_null<Cache*> cache,
143 : ::Tags::deriv<gr::Tags::Shift<DataVector, 3>, tmpl::size_t<3>,
144 : Frame::Inertial> /*meta*/) const;
145 0 : void operator()(
146 : gsl::not_null<tnsr::ii<DataVector, 3>*> shift_strain,
147 : gsl::not_null<Cache*> cache,
148 : Tags::ShiftStrain<DataVector, 3, Frame::Inertial> /*meta*/) const;
149 0 : void operator()(
150 : gsl::not_null<tnsr::II<DataVector, 3>*> longitudinal_shift_excess,
151 : gsl::not_null<Cache*> cache,
152 : Tags::LongitudinalShiftExcess<DataVector, 3, Frame::Inertial> /*meta*/)
153 : const;
154 0 : void operator()(
155 : gsl::not_null<tnsr::I<DataVector, 3>*> div_longitudinal_shift_excess,
156 : gsl::not_null<Cache*> cache,
157 : ::Tags::div<Tags::LongitudinalShiftExcess<
158 : DataVector, 3, Frame::Inertial>> /*meta*/) const;
159 0 : void operator()(
160 : gsl::not_null<tnsr::II<DataVector, 3>*>
161 : longitudinal_shift_minus_dt_conformal_metric,
162 : gsl::not_null<Cache*> cache,
163 : detail::LongitudinalShiftMinusDtConformalMetric<DataVector> /*meta*/)
164 : const;
165 0 : void operator()(gsl::not_null<tnsr::ii<DataVector, 3>*> extrinsic_curvature,
166 : gsl::not_null<Cache*> cache,
167 : gr::Tags::ExtrinsicCurvature<DataVector, 3> /*meta*/) const;
168 0 : void operator()(gsl::not_null<Scalar<DataVector>*> hamiltonian_constraint,
169 : gsl::not_null<Cache*> cache,
170 : gr::Tags::HamiltonianConstraint<DataVector> /*meta*/) const;
171 0 : void operator()(gsl::not_null<tnsr::I<DataVector, 3>*> momentum_constraint,
172 : gsl::not_null<Cache*> cache,
173 : gr::Tags::MomentumConstraint<DataVector, 3> /*meta*/) const;
174 :
175 : // NOLINTBEGIN(cppcoreguidelines-avoid-const-or-ref-data-members)
176 : // XCTS variables
177 0 : const Scalar<DataVector>& conformal_factor_minus_one;
178 0 : const Scalar<DataVector>& lapse_times_conformal_factor_minus_one;
179 0 : const tnsr::I<DataVector, 3>& shift_excess;
180 : // Background
181 0 : const tnsr::ii<DataVector, 3>& conformal_metric;
182 0 : const tnsr::II<DataVector, 3>& inv_conformal_metric;
183 0 : const tnsr::ijj<DataVector, 3>& deriv_conformal_metric;
184 0 : const tnsr::ijj<DataVector, 3>& conformal_christoffel_first_kind;
185 0 : const tnsr::Ijj<DataVector, 3>& conformal_christoffel_second_kind;
186 0 : const tnsr::i<DataVector, 3>& conformal_christoffel_contracted;
187 0 : const tnsr::ii<DataVector, 3>& conformal_ricci;
188 0 : const Scalar<DataVector>& conformal_ricci_scalar;
189 0 : const Scalar<DataVector>& trace_extrinsic_curvature;
190 0 : const tnsr::i<DataVector, 3>& deriv_trace_extrinsic_curvature;
191 0 : const tnsr::I<DataVector, 3>& shift_background;
192 0 : const tnsr::iJ<DataVector, 3>& deriv_shift_background;
193 : const tnsr::II<DataVector, 3>&
194 0 : longitudinal_shift_background_minus_dt_conformal_metric;
195 : const tnsr::I<DataVector, 3>&
196 0 : div_longitudinal_shift_background_minus_dt_conformal_metric;
197 0 : const Scalar<DataVector>& energy_density;
198 0 : const tnsr::I<DataVector, 3>& momentum_density;
199 : // Grid
200 0 : const Mesh<3>& mesh;
201 : const InverseJacobian<DataVector, 3, Frame::ElementLogical, Frame::Inertial>&
202 0 : inv_jacobian;
203 : // NOLINTEND(cppcoreguidelines-avoid-const-or-ref-data-members)
204 : };
205 :
206 : namespace Tags {
207 : /// Compute tag for the 3+1 quantities `Tags` from XCTS variables. The `Tags`
208 : /// can be any subset of the tags supported by `Xcts::SpacetimeQuantities`.
209 : template <typename Tags>
210 1 : struct SpacetimeQuantitiesCompute : ::Tags::Variables<Tags>, db::ComputeTag {
211 0 : using base = ::Tags::Variables<Tags>;
212 0 : using argument_tags = tmpl::list<
213 : domain::Tags::Mesh<3>, ConformalFactorMinusOne<DataVector>,
214 : LapseTimesConformalFactorMinusOne<DataVector>,
215 : ShiftExcess<DataVector, 3, Frame::Inertial>,
216 : ConformalMetric<DataVector, 3, Frame::Inertial>,
217 : InverseConformalMetric<DataVector, 3, Frame::Inertial>,
218 : ::Tags::deriv<ConformalMetric<DataVector, 3, Frame::Inertial>,
219 : tmpl::size_t<3>, Frame::Inertial>,
220 : ConformalChristoffelFirstKind<DataVector, 3, Frame::Inertial>,
221 : ConformalChristoffelSecondKind<DataVector, 3, Frame::Inertial>,
222 : ConformalChristoffelContracted<DataVector, 3, Frame::Inertial>,
223 : ConformalRicciTensor<DataVector, 3, Frame::Inertial>,
224 : ConformalRicciScalar<DataVector>,
225 : gr::Tags::TraceExtrinsicCurvature<DataVector>,
226 : ::Tags::deriv<gr::Tags::TraceExtrinsicCurvature<DataVector>,
227 : tmpl::size_t<3>, Frame::Inertial>,
228 : ShiftBackground<DataVector, 3, Frame::Inertial>,
229 : ::Tags::deriv<ShiftBackground<DataVector, 3, Frame::Inertial>,
230 : tmpl::size_t<3>, Frame::Inertial>,
231 : LongitudinalShiftBackgroundMinusDtConformalMetric<DataVector, 3,
232 : Frame::Inertial>,
233 : ::Tags::div<LongitudinalShiftBackgroundMinusDtConformalMetric<
234 : DataVector, 3, Frame::Inertial>>,
235 : gr::Tags::Conformal<gr::Tags::EnergyDensity<DataVector>, 0>,
236 : gr::Tags::Conformal<gr::Tags::MomentumDensity<DataVector, 3>, 0>,
237 : domain::Tags::Mesh<3>,
238 : domain::Tags::InverseJacobian<3, Frame::ElementLogical, Frame::Inertial>>;
239 : template <typename... Args>
240 0 : static void function(const gsl::not_null<typename base::type*> result,
241 : const Mesh<3>& mesh, const Args&... args) {
242 : const size_t num_points = mesh.number_of_grid_points();
243 : if (result->number_of_grid_points() != num_points) {
244 : result->initialize(num_points);
245 : }
246 : SpacetimeQuantities spacetime_quantities{num_points};
247 : const SpacetimeQuantitiesComputer computer{args...};
248 : tmpl::for_each<Tags>(
249 : [&spacetime_quantities, &computer, &result](const auto tag_v) {
250 : using tag = tmpl::type_from<std::decay_t<decltype(tag_v)>>;
251 : get<tag>(*result) = spacetime_quantities.get_var(computer, tag{});
252 : });
253 : }
254 : };
255 : } // namespace Tags
256 :
257 : } // namespace Xcts
|