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/Tensor/TypeAliases.hpp"
9 : #include "Evolution/Systems/GrMhd/ValenciaDivClean/PrimitiveFromConservativeOptions.hpp"
10 : #include "Evolution/Systems/GrMhd/ValenciaDivClean/TagsDeclarations.hpp"
11 : #include "PointwiseFunctions/GeneralRelativity/TagsDeclarations.hpp"
12 : #include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp"
13 : #include "PointwiseFunctions/Hydro/TagsDeclarations.hpp"
14 : #include "Utilities/TMPL.hpp"
15 :
16 : /// \cond
17 : namespace gsl {
18 : template <typename T>
19 : class not_null;
20 : } // namespace gsl
21 :
22 : class DataVector;
23 : /// \endcond
24 :
25 : namespace grmhd {
26 : namespace ValenciaDivClean {
27 : /*!
28 : * \brief Compute the primitive variables from the conservative variables
29 : *
30 : * For the Valencia formulation of the GRMHD system with divergence cleaning,
31 : * the conversion of the evolved conserved variables to the primitive variables
32 : * cannot be expressed in closed analytic form and requires a root find.
33 : *
34 : * [Siegel {\em et al}, The Astrophysical Journal 859:71(2018)]
35 : * (http://iopscience.iop.org/article/10.3847/1538-4357/aabcc5/meta)
36 : * compares several inversion methods.
37 : *
38 : * If `ErrorOnFailure` is `false` then the returned `bool` will be `false` if
39 : * recovery failed and `true` if it succeeded.
40 : *
41 : * If `EnforcePhysicality` is `false` then the hydrodynamic inversion will
42 : * return with an error if the input conservatives are unphysical, i.e., if no
43 : * solution exits. The exact behavior is governed by `ErrorOnFailure`.
44 : */
45 : template <typename OrderedListOfPrimitiveRecoverySchemes,
46 : bool ErrorOnFailure = true>
47 1 : struct PrimitiveFromConservative {
48 0 : using return_tags =
49 : tmpl::list<hydro::Tags::RestMassDensity<DataVector>,
50 : hydro::Tags::ElectronFraction<DataVector>,
51 : hydro::Tags::SpecificInternalEnergy<DataVector>,
52 : hydro::Tags::SpatialVelocity<DataVector, 3>,
53 : hydro::Tags::MagneticField<DataVector, 3>,
54 : hydro::Tags::DivergenceCleaningField<DataVector>,
55 : hydro::Tags::LorentzFactor<DataVector>,
56 : hydro::Tags::Pressure<DataVector>,
57 : hydro::Tags::Temperature<DataVector>>;
58 :
59 0 : using argument_tags = tmpl::list<
60 : grmhd::ValenciaDivClean::Tags::TildeD,
61 : grmhd::ValenciaDivClean::Tags::TildeYe,
62 : grmhd::ValenciaDivClean::Tags::TildeTau,
63 : grmhd::ValenciaDivClean::Tags::TildeS<>,
64 : grmhd::ValenciaDivClean::Tags::TildeB<>,
65 : grmhd::ValenciaDivClean::Tags::TildePhi,
66 : gr::Tags::SpatialMetric<DataVector, 3>,
67 : gr::Tags::InverseSpatialMetric<DataVector, 3>,
68 : gr::Tags::SqrtDetSpatialMetric<DataVector>,
69 : hydro::Tags::GrmhdEquationOfState,
70 : grmhd::ValenciaDivClean::Tags::PrimitiveFromConservativeOptions>;
71 :
72 : template <bool EnforcePhysicality = true>
73 0 : static bool apply(
74 : gsl::not_null<Scalar<DataVector>*> rest_mass_density,
75 : gsl::not_null<Scalar<DataVector>*> electron_fraction,
76 : gsl::not_null<Scalar<DataVector>*> specific_internal_energy,
77 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> spatial_velocity,
78 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> magnetic_field,
79 : gsl::not_null<Scalar<DataVector>*> divergence_cleaning_field,
80 : gsl::not_null<Scalar<DataVector>*> lorentz_factor,
81 : gsl::not_null<Scalar<DataVector>*> pressure,
82 : gsl::not_null<Scalar<DataVector>*> temperature,
83 : const Scalar<DataVector>& tilde_d, const Scalar<DataVector>& tilde_ye,
84 : const Scalar<DataVector>& tilde_tau,
85 : const tnsr::i<DataVector, 3, Frame::Inertial>& tilde_s,
86 : const tnsr::I<DataVector, 3, Frame::Inertial>& tilde_b,
87 : const Scalar<DataVector>& tilde_phi,
88 : const tnsr::ii<DataVector, 3, Frame::Inertial>& spatial_metric,
89 : const tnsr::II<DataVector, 3, Frame::Inertial>& inv_spatial_metric,
90 : const Scalar<DataVector>& sqrt_det_spatial_metric,
91 : const EquationsOfState::EquationOfState<true, 3>& equation_of_state,
92 : const grmhd::ValenciaDivClean::PrimitiveFromConservativeOptions&
93 : primitive_from_conservative_options);
94 :
95 : private:
96 : template <bool EnforcePhysicality, typename EosType>
97 0 : static bool impl(
98 : gsl::not_null<Scalar<DataVector>*> rest_mass_density,
99 : gsl::not_null<Scalar<DataVector>*> electron_fraction,
100 : gsl::not_null<Scalar<DataVector>*> specific_internal_energy,
101 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> spatial_velocity,
102 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> magnetic_field,
103 : gsl::not_null<Scalar<DataVector>*> divergence_cleaning_field,
104 : gsl::not_null<Scalar<DataVector>*> lorentz_factor,
105 : gsl::not_null<Scalar<DataVector>*> pressure,
106 : gsl::not_null<Scalar<DataVector>*> temperature,
107 : const Scalar<DataVector>& tilde_d, const Scalar<DataVector>& tilde_ye,
108 : const Scalar<DataVector>& tilde_tau,
109 : const tnsr::i<DataVector, 3, Frame::Inertial>& tilde_s,
110 : const tnsr::I<DataVector, 3, Frame::Inertial>& tilde_b,
111 : const Scalar<DataVector>& tilde_phi,
112 : const tnsr::ii<DataVector, 3, Frame::Inertial>& spatial_metric,
113 : const tnsr::II<DataVector, 3, Frame::Inertial>& inv_spatial_metric,
114 : const Scalar<DataVector>& sqrt_det_spatial_metric,
115 : const EosType& equation_of_state,
116 : const grmhd::ValenciaDivClean::PrimitiveFromConservativeOptions&
117 : primitive_from_conservative_options);
118 :
119 : // Use Kastaun hydro inversion if B is dynamically unimportant
120 0 : static constexpr bool use_hydro_optimization = true;
121 : };
122 : } // namespace ValenciaDivClean
123 : } // namespace grmhd
|