Line data Source code
1 1 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : /// \file
5 : /// Defines ScalarWave::Solutions::StandingWave
6 :
7 : #pragma once
8 :
9 : #include <array>
10 : #include <cstddef>
11 : #include <memory>
12 :
13 : #include "DataStructures/TaggedTuple.hpp"
14 : #include "DataStructures/Tensor/TypeAliases.hpp"
15 : #include "Options/String.hpp"
16 : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
17 : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
18 : #include "Utilities/Serialization/CharmPupable.hpp"
19 : #include "Utilities/TMPL.hpp"
20 :
21 : /// \cond
22 : class DataVector;
23 : namespace ScalarWave::Tags {
24 : struct Psi;
25 : struct Pi;
26 : template <size_t Dim, typename Frame>
27 : struct Phi;
28 : } // namespace ScalarWave::Tags
29 : namespace Tags {
30 : template <typename Tag>
31 : struct dt;
32 : } // namespace Tags
33 :
34 : namespace PUP {
35 : class er;
36 : } // namespace PUP
37 : /// \endcond
38 :
39 : namespace ScalarWave::Solutions {
40 : /*!
41 : * \brief A standing wave solution to the Euclidean wave equation
42 : *
43 : * The solution is given by
44 : * \f$\Psi(\vec{x},t) = A \sin(\vec{k} \cdot (\vec{x} - \vec{x_0}))
45 : * \cos(\omega t)\f$
46 : * with the wave vector \f$\vec{k}\f$, frequency
47 : * \f$\omega = ||\vec{k}||\f$, amplitude \f$A\f$, and center
48 : * \f$\vec{x_0}\f$. The first-order variables follow the ScalarWave
49 : * conventions \f$\Pi = -\partial_t \Psi\f$ and \f$\Phi_i = \partial_i \Psi\f$.
50 : *
51 : * At \f$t = 0\f$ this gives \f$\Pi = 0\f$, meaning the initial data
52 : * decomposes into equal left-moving and right-moving components.
53 : *
54 : * \tparam Dim the spatial dimension of the solution
55 : */
56 : template <size_t Dim>
57 1 : class StandingWave : public evolution::initial_data::InitialData,
58 : public MarkAsAnalyticSolution {
59 : public:
60 0 : static constexpr size_t volume_dim = Dim;
61 :
62 0 : struct WaveVector {
63 0 : using type = std::array<double, Dim>;
64 0 : static constexpr Options::String help = {
65 : "The wave vector of the standing wave."};
66 : };
67 :
68 0 : struct Center {
69 0 : using type = std::array<double, Dim>;
70 0 : static constexpr Options::String help = {
71 : "The center of the spatial profile."};
72 : };
73 :
74 0 : struct Amplitude {
75 0 : using type = double;
76 0 : static constexpr Options::String help = {
77 : "The amplitude of the standing wave."};
78 : };
79 :
80 0 : using options = tmpl::list<WaveVector, Center, Amplitude>;
81 :
82 0 : static constexpr Options::String help = {
83 : "A standing wave solution of the Euclidean wave equation. "
84 : "Psi = A sin(k.(x-x0)) cos(omega t), with omega = |k|. "
85 : "At t=0, Pi=0 so the wave has equal left- and right-moving components."};
86 :
87 0 : using tags = tmpl::list<Tags::Psi, Tags::Pi, Tags::Phi<Dim, Frame::Inertial>,
88 : ::Tags::dt<Tags::Psi>, ::Tags::dt<Tags::Pi>,
89 : ::Tags::dt<Tags::Phi<Dim, Frame::Inertial>>>;
90 :
91 0 : StandingWave() = default;
92 0 : StandingWave(std::array<double, Dim> wave_vector,
93 : std::array<double, Dim> center, double amplitude);
94 0 : StandingWave(const StandingWave&) = default;
95 0 : StandingWave& operator=(const StandingWave&) = default;
96 0 : StandingWave(StandingWave&&) = default;
97 0 : StandingWave& operator=(StandingWave&&) = default;
98 0 : ~StandingWave() override = default;
99 :
100 0 : auto get_clone() const
101 : -> std::unique_ptr<evolution::initial_data::InitialData> override;
102 :
103 : /// \cond
104 : explicit StandingWave(CkMigrateMessage* msg);
105 : using PUP::able::register_constructor;
106 : WRAPPED_PUPable_decl_template(StandingWave);
107 : /// \endcond
108 :
109 : /// Retrieve the evolution variables at time `t` and spatial coordinates `x`
110 : tuples::TaggedTuple<Tags::Psi, Tags::Pi, Tags::Phi<Dim, Frame::Inertial>>
111 1 : variables(const tnsr::I<DataVector, Dim>& x, double t,
112 : tmpl::list<Tags::Psi, Tags::Pi,
113 : Tags::Phi<Dim, Frame::Inertial>> /*meta*/) const;
114 :
115 : /// Retrieve the time derivatives of the evolution variables
116 : tuples::TaggedTuple<::Tags::dt<Tags::Psi>, ::Tags::dt<Tags::Pi>,
117 : ::Tags::dt<Tags::Phi<Dim, Frame::Inertial>>>
118 1 : variables(
119 : const tnsr::I<DataVector, Dim>& x, double t,
120 : tmpl::list<::Tags::dt<Tags::Psi>, ::Tags::dt<Tags::Pi>,
121 : ::Tags::dt<Tags::Phi<Dim, Frame::Inertial>>> /*meta*/) const;
122 :
123 : // NOLINTNEXTLINE(google-runtime-references)
124 0 : void pup(PUP::er& p) override;
125 :
126 : private:
127 : template <size_t LocalDim>
128 : // NOLINTNEXTLINE(readability-redundant-declaration)
129 0 : friend bool operator==(const StandingWave<LocalDim>& lhs,
130 : const StandingWave<LocalDim>& rhs);
131 : template <size_t LocalDim>
132 : // NOLINTNEXTLINE(readability-redundant-declaration)
133 0 : friend bool operator!=(const StandingWave<LocalDim>& lhs,
134 : const StandingWave<LocalDim>& rhs);
135 :
136 0 : std::array<double, Dim> wave_vector_{};
137 0 : std::array<double, Dim> center_{};
138 0 : double amplitude_{};
139 0 : double omega_{};
140 : };
141 : } // namespace ScalarWave::Solutions
|