TimeDerivativeTerms.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <utility>
8 
9 #include "DataStructures/DataVector.hpp"
11 #include "Evolution/Systems/GeneralizedHarmonic/System.hpp"
12 #include "Evolution/Systems/GeneralizedHarmonic/TimeDerivative.hpp"
13 #include "Evolution/Systems/GrMhd/GhValenciaDivClean/StressEnergy.hpp"
14 #include "Evolution/Systems/GrMhd/GhValenciaDivClean/Tags.hpp"
15 #include "Evolution/Systems/GrMhd/ValenciaDivClean/System.hpp"
16 #include "Evolution/Systems/GrMhd/ValenciaDivClean/TimeDerivativeTerms.hpp"
17 #include "Utilities/Gsl.hpp"
18 #include "Utilities/Literals.hpp"
19 #include "Utilities/TMPL.hpp"
20 #include "Utilities/TaggedTuple.hpp"
21 
22 namespace grmhd::GhValenciaDivClean {
23 namespace detail {
24 // Some temporary tags appear both in the GRMHD temporary list and the
25 // GeneralizedHarmonic temporary list, so we wrap the GRMHD temporaries in this
26 // prefix tag to avoid collisions in data structures used to store the
27 // temporaries.
28 template <typename Tag>
29 struct ValenciaTempTag : db::SimpleTag, db::PrefixTag {
30  using tag = Tag;
31  using type = typename Tag::type;
32 };
33 
34 template <typename GhDtTagList, typename ValenciaDtTagList,
35  typename ValenciaFluxTagList, typename GhTempTagList,
36  typename ValenciaTempTagList, typename GhGradientTagList,
37  typename GhArgTagList, typename ValenciaArgTagList,
38  typename ValenciaTimeDerivativeArgTagList>
39 struct TimeDerivativeTermsImpl;
40 
41 template <typename... GhDtTags, typename... ValenciaDtTags,
42  typename... ValenciaFluxTags, typename... GhTempTags,
43  typename... ValenciaTempTags, typename... GhGradientTags,
44  typename... GhArgTags, typename... ValenciaArgTags,
45  typename... ValenciaTimeDerivativeArgTags>
46 struct TimeDerivativeTermsImpl<
47  tmpl::list<GhDtTags...>, tmpl::list<ValenciaDtTags...>,
48  tmpl::list<ValenciaFluxTags...>, tmpl::list<GhTempTags...>,
49  tmpl::list<ValenciaTempTags...>, tmpl::list<GhGradientTags...>,
50  tmpl::list<GhArgTags...>, tmpl::list<ValenciaArgTags...>,
51  tmpl::list<ValenciaTimeDerivativeArgTags...>> {
52  static void apply(
55  const gsl::not_null<typename ValenciaFluxTags::type*>... valencia_fluxes,
56  const gsl::not_null<typename GhTempTags::type*>... gh_temporaries,
57  const gsl::not_null<
58  typename ValenciaTempTags::type*>... valencia_temporaries,
59  gsl::not_null<tnsr::aa<DataVector, 3_st>*> stress_energy,
60  gsl::not_null<tnsr::a<DataVector, 3_st>*> four_velocity_one_form,
61  gsl::not_null<tnsr::a<DataVector, 3_st>*>
62  comoving_magnetic_field_one_form,
63  const typename ::Tags::deriv<GhGradientTags, tmpl::size_t<3_st>,
64  Frame::Inertial>::type&... gh_gradients,
65  const typename GhArgTags::type&... gh_args,
66  const typename ValenciaArgTags::type&... valencia_args) noexcept {
68  gh_dts..., gh_temporaries..., gh_gradients..., gh_args...);
69 
70  // This is needed to be able to reuse temporary tags that the GH system
71  // computed already and pass them in as argument tags to the GRMHD system.
72  // Because the tag lists have order alterations from filtering the argument
73  // tags, we use a tagged tuple to reorder the references to the order
74  // expected by the GRMHD time derivative calculation.
76  Tags::detail::TemporaryReference<ValenciaTempTags>...,
77  Tags::detail::TemporaryReference<GhTempTags>...>
78  shuffle_refs(valencia_args..., *valencia_temporaries...,
79  *gh_temporaries...);
80 
81  grmhd::ValenciaDivClean::TimeDerivativeTerms::apply(
82  valencia_dts..., valencia_fluxes..., valencia_temporaries...,
84  Tags::detail::TemporaryReference<ValenciaTimeDerivativeArgTags>>(
85  shuffle_refs)...);
86  dispatch_to_stress_energy_calculation(stress_energy, four_velocity_one_form,
87  comoving_magnetic_field_one_form,
88  gh_args..., shuffle_refs);
89  dispatch_to_add_stress_energy_term_to_dt_pi(gh_dts..., shuffle_refs,
90  *stress_energy);
91  }
92 
93  private:
94  template <typename TupleType>
95  static void dispatch_to_add_stress_energy_term_to_dt_pi(
96  gsl::not_null<tnsr::aa<DataVector, 3_st>*> /*dt_spacetime_metric*/,
97  gsl::not_null<tnsr::aa<DataVector, 3_st>*> dt_pi,
98  gsl::not_null<tnsr::iaa<DataVector, 3_st>*> /*dt_phi*/,
99  const TupleType& args,
100  const tnsr::aa<DataVector, 3_st>& stress_energy) noexcept {
102  dt_pi, stress_energy,
103  tuples::get<
104  Tags::detail::TemporaryReference<gr::Tags::Lapse<DataVector>>>(
105  args));
106  }
107 
108  template <typename TupleType>
109  static void dispatch_to_stress_energy_calculation(
110  gsl::not_null<tnsr::aa<DataVector, 3_st>*> local_stress_energy,
111  gsl::not_null<tnsr::a<DataVector, 3_st>*> four_velocity_buffer_one_form,
112  gsl::not_null<tnsr::a<DataVector, 3_st>*>
113  comoving_magnetic_field_one_form,
114  const tnsr::aa<DataVector, 3_st>& spacetime_metric,
115  const tnsr::aa<DataVector, 3_st>& /*pi*/,
116  const tnsr::iaa<DataVector, 3_st>& /*phi*/,
117  const Scalar<DataVector>& /*gamma0*/,
118  const Scalar<DataVector>& /*gamma1*/,
119  const Scalar<DataVector>& /*gamma2*/,
120  const tnsr::a<DataVector, 3_st>& /*gauge_function*/,
121  const tnsr::ab<DataVector, 3_st>& /*spacetime_deriv_gauge_function*/,
122  const TupleType& args) noexcept {
124  local_stress_energy, four_velocity_buffer_one_form,
125  comoving_magnetic_field_one_form,
126  tuples::get<Tags::detail::TemporaryReference<
128  tuples::get<Tags::detail::TemporaryReference<
130  tuples::get<Tags::detail::TemporaryReference<
131  ValenciaTempTag<hydro::Tags::SpatialVelocityOneForm<
132  DataVector, 3_st, Frame::Inertial>>>>(args),
133  tuples::get<Tags::detail::TemporaryReference<
134  ValenciaTempTag<hydro::Tags::MagneticFieldOneForm<
135  DataVector, 3_st, Frame::Inertial>>>>(args),
136  tuples::get<Tags::detail::TemporaryReference<
138  args),
139  tuples::get<Tags::detail::TemporaryReference<ValenciaTempTag<
141  tuples::get<Tags::detail::TemporaryReference<
143  tuples::get<Tags::detail::TemporaryReference<
145  OneOverLorentzFactorSquared>>>(args),
146  tuples::get<Tags::detail::TemporaryReference<
149  tuples::get<Tags::detail::TemporaryReference<
151  tuples::get<
152  Tags::detail::TemporaryReference<gr::Tags::Lapse<DataVector>>>(
153  args));
154  }
155 };
156 } // namespace detail
157 
158 /*!
159  * \brief Compute the RHS terms and flux values for both the Generalized
160  * Harmonic formulation of Einstein's equations and the Valencia formulation of
161  * the GRMHD equations with divergence cleaning.
162  *
163  * \details The bulk of the computations in this class dispatch to
164  * `GeneralizedHarmonic::TimeDerivative` and
165  * `grmhd::ValenciaDivClean::TimeDerivativeTerms` as a 'product system' -- each
166  * independently operating on its own subset of the supplied variable
167  * collections.
168  * The additional step is taken to compute the trace-reversed stress energy
169  * tensor associated with the GRMHD part of the system and add its contribution
170  * to the \f$\partial_t \Pi_{a b}\f$ variable in the Generalized Harmonic
171  * system, which is the only explicit coupling required to back-react the effect
172  * of matter on the spacetime solution.
173  *
174  * \note The MHD calculation reuses any spacetime quantities in its
175  * argument_tags that are computed by the GH time derivative. However, other
176  * quantities that aren't computed by the GH time derivative like the extrinsic
177  * curvature are currently still retrieved from the DataBox. Those calculations
178  * can be explicitly inlined here to reduce memory pressure and the number of
179  * compute tags.
180  */
182  using valencia_dt_tags = db::wrap_tags_in<
183  ::Tags::dt,
184  typename grmhd::ValenciaDivClean::System::variables_tag::tags_list>;
185  using valencia_flux_tags = tmpl::transform<
186  typename grmhd::ValenciaDivClean::System::flux_variables,
187  tmpl::bind<::Tags::Flux, tmpl::_1, tmpl::pin<tmpl::size_t<3_st>>,
188  tmpl::pin<Frame::Inertial>>>;
189 
190  using gh_dt_tags = db::wrap_tags_in<
191  ::Tags::dt,
192  typename GeneralizedHarmonic::System<3_st>::variables_tag::tags_list>;
193  using gh_temp_tags =
194  typename GeneralizedHarmonic::TimeDerivative<3_st>::temporary_tags;
195  using gh_gradient_tags =
196  typename GeneralizedHarmonic::System<3_st>::gradients_tags;
197  using gh_arg_tags =
198  typename GeneralizedHarmonic::TimeDerivative<3_st>::argument_tags;
199 
200  using valencia_temp_tags = db::wrap_tags_in<
201  detail::ValenciaTempTag,
202  typename grmhd::ValenciaDivClean::TimeDerivativeTerms::temporary_tags>;
203  using valencia_arg_tags = tmpl::list_difference<
204  typename grmhd::ValenciaDivClean::TimeDerivativeTerms::argument_tags,
205  gh_temp_tags>;
206 
207  using temporary_tags = tmpl::flatten<tmpl::list<
208  gh_temp_tags, valencia_temp_tags, Tags::TraceReversedStressEnergy,
210  using argument_tags = tmpl::append<gh_arg_tags, valencia_arg_tags>;
211 
212  template <typename... Args>
213  static void apply(Args&&... args) noexcept {
214  detail::TimeDerivativeTermsImpl<
215  gh_dt_tags, valencia_dt_tags, valencia_flux_tags, gh_temp_tags,
216  valencia_temp_tags, gh_gradient_tags, gh_arg_tags, valencia_arg_tags,
217  typename grmhd::ValenciaDivClean::TimeDerivativeTerms::argument_tags>::
218  apply(std::forward<Args>(args)...);
219  }
220 };
221 } // namespace grmhd::GhValenciaDivClean
std::apply
T apply(T... args)
hydro::Tags::Pressure
The fluid pressure .
Definition: Tags.hpp:119
hydro::Tags::MagneticFieldDotSpatialVelocity
The magnetic field dotted into the spatial velocity, where is the spatial velocity one-form.
Definition: Tags.hpp:90
utility
Frame::Inertial
Definition: IndexType.hpp:44
db::PrefixTag
Mark a struct as a prefix tag by inheriting from this.
Definition: Tag.hpp:103
hydro::Tags::MagneticFieldSquared
The square of the magnetic field, .
Definition: Tags.hpp:107
Literals.hpp
grmhd::GhValenciaDivClean::TimeDerivativeTerms
Compute the RHS terms and flux values for both the Generalized Harmonic formulation of Einstein's equ...
Definition: TimeDerivativeTerms.hpp:181
hydro::Tags::SpatialVelocityOneForm
The spatial velocity one-form , where is raised and lowered with the spatial metric.
Definition: Tags.hpp:152
grmhd::GhValenciaDivClean::add_stress_energy_term_to_dt_pi
void add_stress_energy_term_to_dt_pi(gsl::not_null< tnsr::aa< DataVector, 3 > * > dt_pi, const tnsr::aa< DataVector, 3 > &trace_reversed_stress_energy, const Scalar< DataVector > &lapse) noexcept
Add in the trace-reversed stress-energy source term to the evolved variable of the Generalized Harmo...
db::get
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:791
db::SimpleTag
Mark a struct as a simple tag by inheriting from this.
Definition: Tag.hpp:36
grmhd::ValenciaDivClean::TimeDerivativeTerms
Compute the time derivative of the conserved variables for the Valencia formulation of the GRMHD equa...
Definition: TimeDerivativeTerms.hpp:29
hydro::Tags::LorentzFactor
The Lorentz factor , where is the spatial velocity of the fluid.
Definition: Tags.hpp:64
cstddef
hydro::Tags::MagneticFieldOneForm
The one-form of the magnetic field. Note that is raised and lowered with the spatial metric.
Definition: Tags.hpp:98
hydro::Tags::SpecificEnthalpy
The relativistic specific enthalpy .
Definition: Tags.hpp:167
GeneralizedHarmonic::TimeDerivative
Compute the RHS of the Generalized Harmonic formulation of Einstein's equations.
Definition: TimeDerivative.hpp:87
grmhd::GhValenciaDivClean::Tags::TraceReversedStressEnergy
Represents the trace reversed stress-energy tensor of the matter in the MHD sector of the GRMHD syste...
Definition: Tags.hpp:26
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:271
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:46
grmhd::GhValenciaDivClean::trace_reversed_stress_energy
void trace_reversed_stress_energy(gsl::not_null< tnsr::aa< DataVector, 3 > * > stress_energy, gsl::not_null< tnsr::a< DataVector, 3 > * > four_velocity_one_form_buffer, gsl::not_null< tnsr::a< DataVector, 3 > * > comoving_magnetic_field_one_form_buffer, const Scalar< DataVector > &rest_mass_density, const Scalar< DataVector > &specific_enthalpy, const tnsr::i< DataVector, 3, Frame::Inertial > &spatial_velocity_one_form, const tnsr::i< DataVector, 3, Frame::Inertial > &magnetic_field_one_form, const Scalar< DataVector > &magnetic_field_squared, const Scalar< DataVector > &magnetic_field_dot_spatial_velocity, const Scalar< DataVector > &lorentz_factor, const Scalar< DataVector > &one_over_w_squared, const Scalar< DataVector > &pressure, const tnsr::aa< DataVector, 3, Frame::Inertial > &spacetime_metric, const tnsr::I< DataVector, 3, Frame::Inertial > &shift, const Scalar< DataVector > &lapse) noexcept
Calculate the trace-reversed stress-energy tensor associated with the matter part of the GRMHD syste...
gr::Tags::Shift
Definition: Tags.hpp:48
grmhd::GhValenciaDivClean::Tags::FourVelocityOneForm
The down-index four-velocity .
Definition: Tags.hpp:52
Tags::dt
Prefix indicating a time derivative.
Definition: Prefixes.hpp:29
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
Gsl.hpp
gr::spacetime_metric
void spacetime_metric(gsl::not_null< tnsr::aa< DataType, Dim, Frame > * > spacetime_metric, const Scalar< DataType > &lapse, const tnsr::I< DataType, Dim, Frame > &shift, const tnsr::ii< DataType, Dim, Frame > &spatial_metric) noexcept
Computes the spacetime metric from the spatial metric, lapse, and shift.
Tensor.hpp
db::wrap_tags_in
tmpl::transform< TagList, tmpl::bind< Wrapper, tmpl::_1, tmpl::pin< Args >... > > wrap_tags_in
Create a new tmpl::list of tags by wrapping each tag in TagList in Wrapper<_, Args....
Definition: PrefixHelpers.hpp:30
grmhd::GhValenciaDivClean
Namespace associated with utilities for the combined Generalized Harmonic and Valencia formulation of...
Definition: BoundaryCondition.hpp:19
grmhd::GhValenciaDivClean::Tags::ComovingMagneticFieldOneForm
The down-index comoving magnetic field .
Definition: Tags.hpp:47
brigand::list_difference
fold< Sequence2, Sequence1, lazy::remove< _state, _element > > list_difference
Obtain the elements of Sequence1 that are not in Sequence2.
Definition: TMPL.hpp:589
gr::Tags::Lapse
Definition: Tags.hpp:52
TMPL.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecPiecewisePolynomial.hpp:13
hydro::Tags::RestMassDensity
The rest-mass density .
Definition: Tags.hpp:125