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/TaggedTuple.hpp"
11 : #include "DataStructures/Tensor/TypeAliases.hpp"
12 : #include "Options/String.hpp"
13 : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
14 : #include "PointwiseFunctions/AnalyticSolutions/Hydro/SmoothFlow.hpp"
15 : #include "PointwiseFunctions/Hydro/EquationsOfState/IdealFluid.hpp"
16 : #include "PointwiseFunctions/Hydro/Tags.hpp"
17 : #include "Utilities/MakeArray.hpp"
18 : #include "Utilities/TMPL.hpp"
19 :
20 : namespace NewtonianEuler::Solutions {
21 : /*!
22 : * \brief Smooth density wave advecting across the domain.
23 : *
24 : * A solution with constant pressure and uniform spatial velocity provided
25 : * that the rest mass density satisfies the advection equation
26 : *
27 : * \f{align*}{
28 : * \partial_t\rho + v^i\partial_i\rho = 0,
29 : * \f}
30 : *
31 : * and the specific internal energy is a function of the rest mass density only,
32 : * \f$\epsilon = \epsilon(\rho)\f$. For testing purposes, this class implements
33 : * this solution for the case where \f$\rho\f$ is a sine wave. The user
34 : * specifies the mean flow velocity of the fluid, the wavevector of the density
35 : * profile, and the amplitude \f$A\f$ of the density profile. In Cartesian
36 : * coordinates \f$(x, y, z)\f$, and using dimensionless units, the primitive
37 : * variables at a given time \f$t\f$ are then
38 : *
39 : * \f{align*}{
40 : * \rho(\vec{x},t) &= 1 + A \sin(\vec{k}\cdot(\vec{x} - \vec{v}t)) \\
41 : * \vec{v}(\vec{x},t) &= [v_x, v_y, v_z]^{T},\\
42 : * P(\vec{x},t) &= P, \\
43 : * \epsilon(\vec{x}, t) &= \frac{P}{(\gamma - 1)\rho}\\
44 : * \f}
45 : *
46 : * where we have assumed \f$\epsilon\f$ and \f$\rho\f$ to be related through an
47 : * equation mathematically equivalent to the equation of state of an ideal gas,
48 : * where the pressure is held constant.
49 : */
50 : template <size_t Dim>
51 1 : class SmoothFlow : public evolution::initial_data::InitialData,
52 : virtual public MarkAsAnalyticSolution,
53 : private hydro::Solutions::SmoothFlow<Dim, false> {
54 0 : using smooth_flow = hydro::Solutions::SmoothFlow<Dim, false>;
55 :
56 : public:
57 0 : using options = typename smooth_flow::options;
58 :
59 0 : static constexpr Options::String help = {
60 : "Smooth density wave advecting across a domain."};
61 :
62 0 : SmoothFlow() = default;
63 0 : SmoothFlow(const SmoothFlow& /*rhs*/) = default;
64 0 : SmoothFlow& operator=(const SmoothFlow& /*rhs*/) = default;
65 0 : SmoothFlow(SmoothFlow&& /*rhs*/) = default;
66 0 : SmoothFlow& operator=(SmoothFlow&& /*rhs*/) = default;
67 0 : ~SmoothFlow() override = default;
68 :
69 0 : auto get_clone() const
70 : -> std::unique_ptr<evolution::initial_data::InitialData> override;
71 :
72 : /// \cond
73 : explicit SmoothFlow(CkMigrateMessage* msg);
74 : using PUP::able::register_constructor;
75 : WRAPPED_PUPable_decl_template(SmoothFlow);
76 : /// \endcond
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 : using smooth_flow::equation_of_state;
83 : using typename smooth_flow::equation_of_state_type;
84 :
85 : // Overload the variables function from the base class.
86 0 : using smooth_flow::variables;
87 :
88 : /// Retrieve a collection of hydro variables at `(x, t)`
89 : template <typename DataType, typename... Tags>
90 1 : tuples::TaggedTuple<Tags...> variables(const tnsr::I<DataType, Dim>& x,
91 : const double t,
92 : tmpl::list<Tags...> /*meta*/) const {
93 : static_assert(sizeof...(Tags) > 1,
94 : "The generic template will recurse infinitely if only one "
95 : "tag is being retrieved.");
96 : return {tuples::get<Tags>(variables(x, t, tmpl::list<Tags>{}))...};
97 : }
98 :
99 : // NOLINTNEXTLINE(google-runtime-references)
100 0 : void pup(PUP::er& /*p*/) override;
101 :
102 : private:
103 : template <size_t SpatialDim>
104 : friend bool
105 0 : operator==( // NOLINT (clang-tidy: readability-redundant-declaration)
106 : const SmoothFlow<SpatialDim>& lhs, const SmoothFlow<SpatialDim>& rhs);
107 : };
108 :
109 : template <size_t Dim>
110 0 : bool operator!=(const SmoothFlow<Dim>& lhs, const SmoothFlow<Dim>& rhs);
111 : } // namespace NewtonianEuler::Solutions
|