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"
9 : #include "DataStructures/TaggedTuple.hpp"
10 : #include "DataStructures/Tensor/TypeAliases.hpp"
11 : #include "Evolution/Systems/Burgers/Tags.hpp"
12 : #include "Options/Context.hpp"
13 : #include "Options/String.hpp"
14 : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
15 : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
16 : #include "Utilities/Serialization/CharmPupable.hpp"
17 : #include "Utilities/TMPL.hpp"
18 :
19 : /// \cond
20 : class DataVector;
21 :
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
|