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 <limits>
8 : #include <pup.h>
9 :
10 : #include "DataStructures/Tensor/TypeAliases.hpp"
11 : #include "Options/String.hpp"
12 : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
13 : #include "PointwiseFunctions/AnalyticSolutions/GeneralRelativity/Minkowski.hpp"
14 : #include "PointwiseFunctions/AnalyticSolutions/Hydro/SmoothFlow.hpp"
15 : #include "PointwiseFunctions/AnalyticSolutions/RelativisticEuler/Solutions.hpp"
16 : #include "PointwiseFunctions/Hydro/EquationsOfState/IdealFluid.hpp"
17 : #include "PointwiseFunctions/Hydro/TagsDeclarations.hpp"
18 : #include "PointwiseFunctions/Hydro/Temperature.hpp"
19 : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
20 : #include "Utilities/MakeArray.hpp"
21 : #include "Utilities/Serialization/CharmPupable.hpp"
22 : #include "Utilities/TMPL.hpp"
23 : #include "Utilities/TaggedTuple.hpp"
24 :
25 : namespace RelativisticEuler::Solutions {
26 :
27 : /*!
28 : * \brief Smooth wave propagating in Minkowski spacetime.
29 : *
30 : * The relativistic Euler equations in Minkowski spacetime accept a
31 : * solution with constant pressure and uniform spatial velocity provided
32 : * that the rest mass density satisfies the advection equation
33 : *
34 : * \f{align*}{
35 : * \partial_t\rho + v^i\partial_i\rho = 0,
36 : * \f}
37 : *
38 : * and the specific internal energy is a function of the rest mass density only,
39 : * \f$\epsilon = \epsilon(\rho)\f$. For testing purposes, this class implements
40 : * this solution for the case where \f$\rho\f$ is a sine wave. The user
41 : * specifies the mean flow velocity of the fluid, the wavevector of the density
42 : * profile, and the amplitude \f$A\f$ of the density profile. In Cartesian
43 : * coordinates \f$(x, y, z)\f$, and using dimensionless units, the primitive
44 : * variables at a given time \f$t\f$ are then
45 : *
46 : * \f{align*}{
47 : * \rho(\vec{x},t) &= 1 + A \sin(\vec{k}\cdot(\vec{x} - \vec{v}t)) \\
48 : * \vec{v}(\vec{x},t) &= [v_x, v_y, v_z]^{T},\\
49 : * P(\vec{x},t) &= P, \\
50 : * \epsilon(\vec{x}, t) &= \frac{P}{(\gamma - 1)\rho}\\
51 : * \f}
52 : *
53 : * where we have assumed \f$\epsilon\f$ and \f$\rho\f$ to be related through an
54 : * equation mathematically equivalent to the equation of state of an ideal gas,
55 : * where the pressure is held constant.
56 : */
57 : template <size_t Dim>
58 1 : class SmoothFlow : public evolution::initial_data::InitialData,
59 : virtual public MarkAsAnalyticSolution,
60 : public AnalyticSolution<Dim>,
61 : public hydro::TemperatureInitialization<SmoothFlow<Dim>>,
62 : private hydro::Solutions::SmoothFlow<Dim, true> {
63 0 : using smooth_flow = hydro::Solutions::SmoothFlow<Dim, true>;
64 :
65 : public:
66 0 : using options = typename smooth_flow::options;
67 :
68 0 : static constexpr Options::String help = {
69 : "Smooth flow in Minkowski spacetime."};
70 :
71 0 : SmoothFlow() = default;
72 0 : SmoothFlow(const SmoothFlow& /*rhs*/) = default;
73 0 : SmoothFlow& operator=(const SmoothFlow& /*rhs*/) = default;
74 0 : SmoothFlow(SmoothFlow&& /*rhs*/) = default;
75 0 : SmoothFlow& operator=(SmoothFlow&& /*rhs*/) = default;
76 0 : ~SmoothFlow() = default;
77 :
78 0 : SmoothFlow(const std::array<double, Dim>& mean_velocity,
79 : const std::array<double, Dim>& wavevector, double pressure,
80 : double adiabatic_index, double perturbation_size);
81 :
82 0 : auto get_clone() const
83 : -> std::unique_ptr<evolution::initial_data::InitialData> override;
84 :
85 : /// \cond
86 : explicit SmoothFlow(CkMigrateMessage* msg);
87 : using PUP::able::register_constructor;
88 : WRAPPED_PUPable_decl_template(SmoothFlow);
89 : /// \endcond
90 :
91 : using smooth_flow::equation_of_state;
92 : using typename smooth_flow::equation_of_state_type;
93 :
94 : // Overload the variables function from the base class.
95 : using smooth_flow::variables;
96 :
97 : template <typename DataType>
98 0 : auto variables(const tnsr::I<DataType, Dim>& x, double t,
99 : tmpl::list<hydro::Tags::Temperature<DataType>> /*meta*/) const
100 : -> tuples::TaggedTuple<hydro::Tags::Temperature<DataType>> {
101 : return hydro::TemperatureInitialization<SmoothFlow<Dim>>::variables(
102 : x, t, tmpl::list<hydro::Tags::Temperature<DataType>>{});
103 : }
104 :
105 : template <typename DataType>
106 0 : auto variables(const tnsr::I<DataType, Dim>& x, double /*t*/,
107 : tmpl::list<hydro::Tags::ElectronFraction<DataType>> /*meta*/)
108 : const -> tuples::TaggedTuple<hydro::Tags::ElectronFraction<DataType>>;
109 :
110 : /// Retrieve a collection of hydro variables at `(x, t)`
111 : template <typename DataType, typename... Tags>
112 1 : tuples::TaggedTuple<Tags...> variables(const tnsr::I<DataType, Dim>& x,
113 : const double t,
114 : tmpl::list<Tags...> /*meta*/) const {
115 : static_assert(sizeof...(Tags) > 1,
116 : "The generic template will recurse infinitely if only one "
117 : "tag is being retrieved.");
118 : return {get<Tags>(variables(x, t, tmpl::list<Tags>{}))...};
119 : }
120 :
121 : /// Retrieve the metric variables
122 : template <typename DataType, typename Tag>
123 1 : tuples::TaggedTuple<Tag> variables(const tnsr::I<DataType, Dim>& x, double t,
124 : tmpl::list<Tag> /*meta*/) const {
125 : return background_spacetime_.variables(x, t, tmpl::list<Tag>{});
126 : }
127 :
128 : template <typename DataType>
129 0 : tuples::TaggedTuple<hydro::Tags::MagneticField<DataType, Dim>> variables(
130 : const tnsr::I<DataType, Dim>& x, double t,
131 : tmpl::list<hydro::Tags::MagneticField<DataType, Dim>> /*meta*/) const;
132 :
133 : template <typename DataType>
134 0 : tuples::TaggedTuple<hydro::Tags::DivergenceCleaningField<DataType>> variables(
135 : const tnsr::I<DataType, Dim>& x, double t,
136 : tmpl::list<hydro::Tags::DivergenceCleaningField<DataType>> /*meta*/)
137 : const;
138 :
139 : // NOLINTNEXTLINE(google-runtime-references)
140 0 : void pup(PUP::er& /*p*/) override;
141 :
142 : private:
143 : template <size_t SpatialDim>
144 : friend bool
145 0 : operator==( // NOLINT (clang-tidy: readability-redundant-declaration)
146 : const SmoothFlow<SpatialDim>& lhs, const SmoothFlow<SpatialDim>& rhs);
147 :
148 0 : gr::Solutions::Minkowski<Dim> background_spacetime_{};
149 : };
150 :
151 : template <size_t Dim>
152 0 : bool operator!=(const SmoothFlow<Dim>& lhs, const SmoothFlow<Dim>& rhs);
153 : } // namespace RelativisticEuler::Solutions
|