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/Hydro/SmoothFlow.hpp" 14 : #include "PointwiseFunctions/Hydro/EquationsOfState/IdealFluid.hpp" 15 : #include "PointwiseFunctions/Hydro/Tags.hpp" 16 : #include "Utilities/MakeArray.hpp" 17 : #include "Utilities/TMPL.hpp" 18 : #include "Utilities/TaggedTuple.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 : 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 : 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