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 :
8 : #include "DataStructures/TaggedTuple.hpp"
9 : #include "DataStructures/Tensor/Tensor.hpp"
10 : #include "Evolution/Systems/ScalarWave/Tags.hpp"
11 : #include "Options/String.hpp"
12 : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
13 : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
14 : #include "Utilities/Serialization/CharmPupable.hpp"
15 : #include "Utilities/TMPL.hpp"
16 :
17 : /// \cond
18 : class DataVector;
19 :
20 : namespace PUP {
21 : class er;
22 : } // namespace PUP
23 : /// \endcond
24 :
25 : namespace ScalarWave::Solutions {
26 : /*!
27 : * \brief An exact solution to the semidiscretized DG ScalarWave
28 : * system with an upwind flux
29 : *
30 : * This solution takes into account the spatial discretization error,
31 : * and so should show convergence in time integration accuracy to
32 : * roundoff at any resolution.
33 : *
34 : * \warning This is not really a pointwise function, as the solution
35 : * depends on the spatial discretization. It will only work on a
36 : * periodic domain of length \f$2 \pi\f$ (or an integer multiple) with
37 : * equally sized linear elements.
38 : */
39 1 : class SemidiscretizedDg : public evolution::initial_data::InitialData,
40 : public MarkAsAnalyticSolution {
41 : public:
42 0 : using tags = tmpl::list<Tags::Pi, Tags::Phi<1>, Tags::Psi>;
43 :
44 0 : struct Harmonic {
45 0 : using type = int;
46 0 : static constexpr Options::String help =
47 : "Number of wave periods across the domain";
48 : };
49 :
50 0 : struct Amplitudes {
51 0 : using type = std::array<double, 4>;
52 0 : static constexpr Options::String help =
53 : "Amplitudes of the independent modes of the harmonic";
54 : };
55 :
56 0 : using options = tmpl::list<Harmonic, Amplitudes>;
57 :
58 0 : static constexpr Options::String help =
59 : "A solution of the semidiscretized DG system on linear elements\n"
60 : "with spatial period 2 pi.";
61 :
62 0 : SemidiscretizedDg(int harmonic, const std::array<double, 4>& amplitudes);
63 :
64 0 : SemidiscretizedDg() = default;
65 0 : ~SemidiscretizedDg() override = default;
66 :
67 0 : auto get_clone() const
68 : -> std::unique_ptr<evolution::initial_data::InitialData> override;
69 :
70 : /// \cond
71 : explicit SemidiscretizedDg(CkMigrateMessage* msg);
72 : using PUP::able::register_constructor;
73 : WRAPPED_PUPable_decl_template(SemidiscretizedDg);
74 : /// \endcond
75 :
76 : /// Retrieve the evolution variables at time `t` and spatial coordinates `x`
77 : template <typename... Tags>
78 1 : tuples::TaggedTuple<Tags...> variables(const tnsr::I<DataVector, 1>& x,
79 : double t,
80 : tmpl::list<Tags...> /*meta*/) const {
81 : static_assert(
82 : tmpl2::flat_all_v<tmpl::list_contains_v<tags, Tags>...>,
83 : "At least one of the requested tags is not supported. The requested "
84 : "tags are listed as template parameters of the `variables` function.");
85 : return {get<Tags>(variables(x, t, tmpl::list<Tags>{}))...};
86 : }
87 :
88 : /// \cond
89 : tuples::TaggedTuple<Tags::Pi> variables(const tnsr::I<DataVector, 1>& x,
90 : double t,
91 : tmpl::list<Tags::Pi> /*meta*/) const;
92 :
93 : tuples::TaggedTuple<Tags::Phi<1>> variables(
94 : const tnsr::I<DataVector, 1>& x, double t,
95 : tmpl::list<Tags::Phi<1>> /*meta*/) const;
96 :
97 : tuples::TaggedTuple<Tags::Psi> variables(
98 : const tnsr::I<DataVector, 1>& x, double t,
99 : tmpl::list<Tags::Psi> /*meta*/) const;
100 : /// \endcond
101 :
102 : // NOLINTNEXTLINE(google-runtime-references)
103 0 : void pup(PUP::er& p) override;
104 :
105 : private:
106 0 : int harmonic_{std::numeric_limits<int>::max()};
107 0 : std::array<double, 4> amplitudes_{
108 : {std::numeric_limits<double>::signaling_NaN(),
109 : std::numeric_limits<double>::signaling_NaN(),
110 : std::numeric_limits<double>::signaling_NaN(),
111 : std::numeric_limits<double>::signaling_NaN()}};
112 : };
113 : } // namespace ScalarWave::Solutions
|