Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <limits> 7 : 8 : #include "DataStructures/DataBox/Prefixes.hpp" // IWYU pragma: keep 9 : #include "DataStructures/Tensor/TypeAliases.hpp" 10 : #include "Evolution/Systems/Burgers/Tags.hpp" // IWYU pragma: keep 11 : #include "Options/Context.hpp" 12 : #include "Options/String.hpp" 13 : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp" 14 : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp" 15 : #include "Utilities/Serialization/CharmPupable.hpp" 16 : #include "Utilities/TMPL.hpp" 17 : #include "Utilities/TaggedTuple.hpp" 18 : 19 : /// \cond 20 : class DataVector; 21 : // IWYU pragma: no_forward_declare Tensor 22 : namespace PUP { 23 : class er; 24 : } // namespace PUP 25 : /// \endcond 26 : 27 : namespace Burgers::Solutions { 28 : /// \brief A propagating shock between two constant states 29 : /// 30 : /// The shock propagates left-to-right, with profile 31 : /// \f$U(x, t) = U_R + (U_L - U_R) H(-(x - x_0 - v t))\f$. 32 : /// Here \f$U_L\f$ and \f$U_R\f$ are the left and right constant states, 33 : /// satisfying \f$U_L > U_R\f$; \f$H\f$ is the Heaviside function; \f$x_0\f$ is 34 : /// the initial (i.e., \f$t=0\f$) position of the shock; and 35 : /// \f$v = 0.5 (U_L + U_R)\f$ is the speed of the shock. 36 : /// 37 : /// \note At the shock, where \f$x = x_0 + vt\f$, we have \f$U(x, t) = U_L\f$. 38 : /// (This is inherited from the Heaviside implementation `step_function`.) 39 : /// Additionally, the time derivative \f$\partial_t u0\f$ is zero, rather than 40 : /// the correct delta function. 41 1 : class Step : public evolution::initial_data::InitialData, 42 : public MarkAsAnalyticSolution { 43 : public: 44 0 : struct LeftValue { 45 0 : using type = double; 46 0 : static type lower_bound() { return 0.0; } 47 0 : static constexpr Options::String help{"The value of U, left of the shock"}; 48 : }; 49 0 : struct RightValue { 50 0 : using type = double; 51 0 : static type lower_bound() { return 0.0; } 52 0 : static constexpr Options::String help{"The value of U, right of the shock"}; 53 : }; 54 0 : struct InitialPosition { 55 0 : using type = double; 56 0 : static constexpr Options::String help{"The shock's position at t==0"}; 57 : }; 58 : 59 0 : using options = tmpl::list<LeftValue, RightValue, InitialPosition>; 60 0 : static constexpr Options::String help{"A propagating shock solution"}; 61 : 62 0 : Step(double left_value, double right_value, double initial_shock_position, 63 : const Options::Context& context = {}); 64 : 65 0 : Step() = default; 66 0 : Step(const Step&) = default; 67 0 : Step& operator=(const Step&) = default; 68 0 : Step(Step&&) = default; 69 0 : Step& operator=(Step&&) = default; 70 0 : ~Step() override = default; 71 : 72 0 : auto get_clone() const 73 : -> std::unique_ptr<evolution::initial_data::InitialData> override; 74 : 75 : /// \cond 76 : explicit Step(CkMigrateMessage* msg); 77 : using PUP::able::register_constructor; 78 : WRAPPED_PUPable_decl_template(Step); 79 : /// \endcond 80 : 81 : template <typename T> 82 0 : Scalar<T> u(const tnsr::I<T, 1>& x, double t) const; 83 : 84 : template <typename T> 85 0 : Scalar<T> du_dt(const tnsr::I<T, 1>& x, double t) const; 86 : 87 0 : tuples::TaggedTuple<Tags::U> variables(const tnsr::I<DataVector, 1>& x, 88 : double t, 89 : tmpl::list<Tags::U> /*meta*/) const; 90 : 91 0 : tuples::TaggedTuple<::Tags::dt<Tags::U>> variables( 92 : const tnsr::I<DataVector, 1>& x, double t, 93 : tmpl::list<::Tags::dt<Tags::U>> /*meta*/) const; 94 : 95 : // NOLINTNEXTLINE(google-runtime-references) 96 0 : void pup(PUP::er& p) override; 97 : 98 : private: 99 0 : double left_value_ = std::numeric_limits<double>::signaling_NaN(); 100 0 : double right_value_ = std::numeric_limits<double>::signaling_NaN(); 101 0 : double initial_shock_position_ = std::numeric_limits<double>::signaling_NaN(); 102 : }; 103 : } // namespace Burgers::Solutions