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> 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 = 88 : tmpl::list<Tags::Psi, Tags::Pi, Tags::Phi<Dim>, ::Tags::dt<Tags::Psi>, 89 : ::Tags::dt<Tags::Pi>, ::Tags::dt<Tags::Phi<Dim>>>; 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 1 : tuples::TaggedTuple<Tags::Psi, Tags::Pi, Tags::Phi<Dim>> variables( 111 : const tnsr::I<DataVector, Dim>& x, double t, 112 : tmpl::list<Tags::Psi, Tags::Pi, Tags::Phi<Dim>> /*meta*/) const; 113 : 114 : /// Retrieve the time derivatives of the evolution variables 115 : tuples::TaggedTuple<::Tags::dt<Tags::Psi>, ::Tags::dt<Tags::Pi>, 116 : ::Tags::dt<Tags::Phi<Dim>>> 117 1 : variables(const tnsr::I<DataVector, Dim>& x, double t, 118 : tmpl::list<::Tags::dt<Tags::Psi>, ::Tags::dt<Tags::Pi>, 119 : ::Tags::dt<Tags::Phi<Dim>>> /*meta*/) const; 120 : 121 : // NOLINTNEXTLINE(google-runtime-references) 122 0 : void pup(PUP::er& p) override; 123 : 124 : private: 125 : template <size_t LocalDim> 126 : // NOLINTNEXTLINE(readability-redundant-declaration) 127 0 : friend bool operator==(const StandingWave<LocalDim>& lhs, 128 : const StandingWave<LocalDim>& rhs); 129 : template <size_t LocalDim> 130 : // NOLINTNEXTLINE(readability-redundant-declaration) 131 0 : friend bool operator!=(const StandingWave<LocalDim>& lhs, 132 : const StandingWave<LocalDim>& rhs); 133 : 134 0 : std::array<double, Dim> wave_vector_{}; 135 0 : std::array<double, Dim> center_{}; 136 0 : double amplitude_{}; 137 0 : double omega_{}; 138 : }; 139 : } // namespace ScalarWave::Solutions