Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <array>
7 : #include <cstddef>
8 :
9 : #include "DataStructures/DataBox/Tag.hpp"
10 : #include "DataStructures/Tensor/EagerMath/Magnitude.hpp"
11 : #include "DataStructures/Tensor/TypeAliases.hpp"
12 : #include "Domain/FaceNormal.hpp"
13 : #include "Evolution/Systems/GrMhd/ValenciaDivClean/Tags.hpp"
14 : #include "PointwiseFunctions/GeneralRelativity/TagsDeclarations.hpp" // IWYU pragma: keep
15 : #include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp" // IWYU pragma: keep
16 : #include "PointwiseFunctions/Hydro/TagsDeclarations.hpp" // IWYU pragma: keep
17 : #include "Utilities/Gsl.hpp"
18 : #include "Utilities/TMPL.hpp"
19 :
20 : // IWYU pragma: no_include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
21 : // IWYU pragma: no_include "PointwiseFunctions/Hydro/Tags.hpp"
22 :
23 : /// \cond
24 : class DataVector;
25 : namespace Tags {
26 : template <typename Tag>
27 : struct Normalized;
28 : } // namespace Tags
29 : /// \endcond
30 :
31 : // IWYU pragma: no_forward_declare EquationsOfState::EquationOfState
32 : // IWYU pragma: no_forward_declare EquationsOfSTate::IdealFluid
33 : // IWYU pragma: no_forward_declare Tensor
34 :
35 : namespace grmhd {
36 : namespace ValenciaDivClean {
37 :
38 : /// @{
39 : /*!
40 : * \brief Compute the characteristic speeds for the Valencia formulation of
41 : * GRMHD with divergence cleaning.
42 : *
43 : * Obtaining the exact form of the characteristic speeds involves the solution
44 : * of a nontrivial quartic equation for the fast and slow modes. Here we make
45 : * use of a common approximation in the literature (e.g. \cite Gammie2003)
46 : * where the resulting characteristic speeds are analogous to those of the
47 : * Valencia formulation of the 3-D relativistic Euler system
48 : * (see RelativisticEuler::Valencia::characteristic_speeds),
49 : *
50 : * \f{align*}
51 : * \lambda_2 &= \alpha \Lambda^- - \beta_n,\\
52 : * \lambda_{3, 4, 5, 6, 7} &= \alpha v_n - \beta_n,\\
53 : * \lambda_{8} &= \alpha \Lambda^+ - \beta_n,
54 : * \f}
55 : *
56 : * with the substitution
57 : *
58 : * \f{align*}
59 : * c_s^2 \longrightarrow c_s^2 + v_A^2(1 - c_s^2)
60 : * \f}
61 : *
62 : * in the definition of \f$\Lambda^\pm\f$. Here \f$v_A\f$ is the Alfvén
63 : * speed. In addition, two more speeds corresponding to the divergence cleaning
64 : * mode and the longitudinal magnetic field are added,
65 : *
66 : * \f{align*}
67 : * \lambda_1 = -\alpha - \beta_n,\\
68 : * \lambda_9 = \alpha - \beta_n.
69 : * \f}
70 : *
71 : * \note The ordering assumed here is such that, in the Newtonian limit,
72 : * the exact expressions for \f$\lambda_{2, 8}\f$, \f$\lambda_{3, 7}\f$,
73 : * and \f$\lambda_{4, 6}\f$ should reduce to the
74 : * corresponding fast modes, Alfvén modes, and slow modes, respectively.
75 : * See \cite Dedner2002 for a detailed description of the hyperbolic
76 : * characterization of Newtonian MHD. In terms of the primitive variables:
77 : *
78 : * \f{align*}
79 : * v^2 &= \gamma_{mn} v^m v^n \\
80 : * c_s^2 &= \frac{1}{h} \left[ \left( \frac{\partial p}{\partial \rho}
81 : * \right)_\epsilon +
82 : * \frac{p}{\rho^2} \left(\frac{\partial p}{\partial \epsilon}
83 : * \right)_\rho \right] \\
84 : * v_A^2 &= \frac{b^2}{b^2 + \rho h} \\
85 : * b^2 &= \frac{1}{W^2} \gamma_{mn} B^m B^n + \left( \gamma_{mn} B^m v^n
86 : * \right)^2
87 : * \f}
88 : *
89 : * where \f$\gamma_{mn}\f$ is the spatial metric, \f$\rho\f$ is the rest
90 : * mass density, \f$W = 1/\sqrt{1-v_i v^i}\f$ is the Lorentz factor, \f$h = 1 +
91 : * \epsilon + \frac{p}{\rho}\f$ is the specific enthalpy, \f$v^i\f$ is the
92 : * spatial velocity, \f$\epsilon\f$ is the specific internal energy, \f$p\f$ is
93 : * the pressure, and \f$B^i\f$ is the spatial magnetic field measured by an
94 : * Eulerian observer.
95 : */
96 : template <size_t ThermodynamicDim>
97 1 : std::array<DataVector, 9> characteristic_speeds(
98 : const Scalar<DataVector>& rest_mass_density,
99 : const Scalar<DataVector>& electron_fraction,
100 : const Scalar<DataVector>& specific_internal_energy,
101 : const Scalar<DataVector>& specific_enthalpy,
102 : const tnsr::I<DataVector, 3, Frame::Inertial>& spatial_velocity,
103 : const Scalar<DataVector>& lorentz_factor,
104 : const tnsr::I<DataVector, 3, Frame::Inertial>& magnetic_field,
105 : const Scalar<DataVector>& lapse, const tnsr::I<DataVector, 3>& shift,
106 : const tnsr::ii<DataVector, 3, Frame::Inertial>& spatial_metric,
107 : const tnsr::i<DataVector, 3>& unit_normal,
108 : const EquationsOfState::EquationOfState<true, ThermodynamicDim>&
109 : equation_of_state);
110 :
111 : template <size_t ThermodynamicDim>
112 1 : void characteristic_speeds(
113 : gsl::not_null<std::array<DataVector, 9>*> char_speeds,
114 : const Scalar<DataVector>& rest_mass_density,
115 : const Scalar<DataVector>& electron_fraction,
116 : const Scalar<DataVector>& specific_internal_energy,
117 : const Scalar<DataVector>& specific_enthalpy,
118 : const tnsr::I<DataVector, 3, Frame::Inertial>& spatial_velocity,
119 : const Scalar<DataVector>& lorentz_factor,
120 : const tnsr::I<DataVector, 3, Frame::Inertial>& magnetic_field,
121 : const Scalar<DataVector>& lapse, const tnsr::I<DataVector, 3>& shift,
122 : const tnsr::ii<DataVector, 3, Frame::Inertial>& spatial_metric,
123 : const tnsr::i<DataVector, 3>& unit_normal,
124 : const EquationsOfState::EquationOfState<true, ThermodynamicDim>&
125 : equation_of_state);
126 : /// @}
127 :
128 1 : namespace Tags {
129 : /// \brief Compute the characteristic speeds for the Valencia formulation of
130 : /// GRMHD with divergence cleaning.
131 : ///
132 : /// \details see grmhd::ValenciaDivClean::characteristic_speeds
133 1 : struct CharacteristicSpeedsCompute : Tags::CharacteristicSpeeds,
134 : db::ComputeTag {
135 0 : using base = Tags::CharacteristicSpeeds;
136 0 : using argument_tags =
137 : tmpl::list<hydro::Tags::RestMassDensity<DataVector>,
138 : hydro::Tags::ElectronFraction<DataVector>,
139 : hydro::Tags::SpecificInternalEnergy<DataVector>,
140 : hydro::Tags::SpecificEnthalpy<DataVector>,
141 : hydro::Tags::SpatialVelocity<DataVector, 3>,
142 : hydro::Tags::LorentzFactor<DataVector>,
143 : hydro::Tags::MagneticField<DataVector, 3>,
144 : gr::Tags::Lapse<DataVector>, gr::Tags::Shift<DataVector, 3>,
145 : gr::Tags::SpatialMetric<DataVector, 3>,
146 : ::Tags::Normalized<domain::Tags::UnnormalizedFaceNormal<3>>,
147 : hydro::Tags::GrmhdEquationOfState>;
148 :
149 0 : using volume_tags = tmpl::list<hydro::Tags::GrmhdEquationOfState>;
150 :
151 0 : using return_type = std::array<DataVector, 9>;
152 :
153 : template <size_t ThermodynamicDim>
154 0 : static constexpr void function(
155 : const gsl::not_null<return_type*> result,
156 : const Scalar<DataVector>& rest_mass_density,
157 : const Scalar<DataVector>& /* electron_fraction */,
158 : const Scalar<DataVector>& specific_internal_energy,
159 : const Scalar<DataVector>& specific_enthalpy,
160 : const tnsr::I<DataVector, 3, Frame::Inertial>& spatial_velocity,
161 : const Scalar<DataVector>& lorentz_factor,
162 : const tnsr::I<DataVector, 3, Frame::Inertial>& magnetic_field,
163 : const Scalar<DataVector>& lapse, const tnsr::I<DataVector, 3>& shift,
164 : const tnsr::ii<DataVector, 3, Frame::Inertial>& spatial_metric,
165 : const tnsr::i<DataVector, 3>& unit_normal,
166 : const EquationsOfState::EquationOfState<true, ThermodynamicDim>&
167 : equation_of_state) {
168 : characteristic_speeds<ThermodynamicDim>(
169 : result, rest_mass_density, specific_internal_energy, specific_enthalpy,
170 : spatial_velocity, lorentz_factor, magnetic_field, lapse, shift,
171 : spatial_metric, unit_normal, equation_of_state);
172 : }
173 : };
174 :
175 0 : struct LargestCharacteristicSpeed : db::SimpleTag {
176 0 : using type = double;
177 : };
178 :
179 0 : struct ComputeLargestCharacteristicSpeed : db::ComputeTag,
180 : LargestCharacteristicSpeed {
181 0 : using argument_tags =
182 : tmpl::list<gr::Tags::Lapse<DataVector>, gr::Tags::Shift<DataVector, 3>,
183 : gr::Tags::SpatialMetric<DataVector, 3>>;
184 0 : using return_type = double;
185 0 : using base = LargestCharacteristicSpeed;
186 0 : static void function(gsl::not_null<double*> speed,
187 : const Scalar<DataVector>& lapse,
188 : const tnsr::I<DataVector, 3>& shift,
189 : const tnsr::ii<DataVector, 3>& spatial_metric) {
190 : const auto shift_magnitude = magnitude(shift, spatial_metric);
191 : *speed = max(get(shift_magnitude) + get(lapse));
192 : }
193 : };
194 : } // namespace Tags
195 : } // namespace ValenciaDivClean
196 : } // namespace grmhd
|