Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <memory>
7 : #include <optional>
8 : #include <pup.h>
9 : #include <string>
10 : #include <type_traits>
11 :
12 : #include "DataStructures/DataBox/Prefixes.hpp"
13 : #include "DataStructures/DataVector.hpp"
14 : #include "DataStructures/Tensor/Tensor.hpp"
15 : #include "DataStructures/Variables.hpp"
16 : #include "Evolution/BoundaryConditions/Type.hpp"
17 : #include "Evolution/Systems/ScalarWave/BoundaryConditions/BoundaryCondition.hpp"
18 : #include "Evolution/Systems/ScalarWave/Tags.hpp"
19 : #include "Options/Options.hpp"
20 : #include "Options/String.hpp"
21 : #include "PointwiseFunctions/AnalyticData/Tags.hpp"
22 : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
23 : #include "Utilities/Gsl.hpp"
24 : #include "Utilities/Serialization/CharmPupable.hpp"
25 : #include "Utilities/TMPL.hpp"
26 :
27 : /// \cond
28 : namespace domain::Tags {
29 : template <size_t Dim, typename Frame>
30 : struct Coordinates;
31 : } // namespace domain::Tags
32 : namespace Options {
33 : template <typename T>
34 : struct create_from_yaml;
35 : } // namespace Options
36 : /// \endcond
37 :
38 : namespace ScalarWave::BoundaryConditions {
39 : namespace detail {
40 : /// The type of spherical radiation boundary condition to impose
41 : enum class SphericalRadiationType {
42 : /// Impose \f$(\partial_t + \partial_r)\Psi=0\f$
43 : Sommerfeld,
44 : /// Impose \f$(\partial_t + \partial_r + r^{-1})\Psi=0\f$
45 : BaylissTurkel
46 : };
47 :
48 : SphericalRadiationType convert_spherical_radiation_type_from_yaml(
49 : const Options::Option& options);
50 : } // namespace detail
51 :
52 : /*!
53 : * \brief Impose spherical radiation boundary conditions.
54 : *
55 : * These can be imposed in one of two forms:
56 : *
57 : * \f{align*}{
58 : * \Pi=\partial_r\Psi,
59 : * \f}
60 : *
61 : * referred to as a Sommerfeld condition, or
62 : *
63 : * \f{align*}{
64 : * \Pi=\partial_r\Psi + \frac{1}{r}\Psi
65 : * \f}
66 : *
67 : * referred to as a Bayliss-Turkel condition.
68 : *
69 : * The Bayliss-Turkel condition produces fewer reflections than the Sommerfeld
70 : * condition.
71 : *
72 : * \warning These are implemented assuming the outer boundary is spherical and
73 : * centered at the origin of the radiation because the code sets
74 : * \f$\Pi=n^i\Phi_i\f$, where \f$n^i\f$ is the outward pointing unit normal
75 : * vector. It might be possible to generalize the condition to non-spherical
76 : * boundaries by using \f$x^i/r\f$ instead of \f$n^i\f$, but this hasn't been
77 : * tested.
78 : */
79 : template <size_t Dim>
80 1 : class SphericalRadiation final : public BoundaryCondition<Dim> {
81 : public:
82 0 : struct TypeOptionTag {
83 0 : using type = detail::SphericalRadiationType;
84 0 : static std::string name() { return "Type"; }
85 0 : static constexpr Options::String help{
86 : "Whether to impose Sommerfeld or first-order Bayliss-Turkel spherical "
87 : "radiation boundary conditions."};
88 : };
89 :
90 0 : using options = tmpl::list<TypeOptionTag>;
91 0 : static constexpr Options::String help{
92 : "Spherical radiation boundary conditions setting the value of Psi, Phi, "
93 : "and Pi either using the Sommerfeld or first-order Bayliss-Turkel "
94 : "method."};
95 :
96 0 : SphericalRadiation() = default;
97 0 : SphericalRadiation(detail::SphericalRadiationType type);
98 0 : SphericalRadiation(SphericalRadiation&&) = default;
99 0 : SphericalRadiation& operator=(SphericalRadiation&&) = default;
100 0 : SphericalRadiation(const SphericalRadiation&) = default;
101 0 : SphericalRadiation& operator=(const SphericalRadiation&) = default;
102 0 : ~SphericalRadiation() override = default;
103 :
104 0 : explicit SphericalRadiation(CkMigrateMessage* msg);
105 :
106 0 : WRAPPED_PUPable_decl_base_template(
107 : domain::BoundaryConditions::BoundaryCondition, SphericalRadiation);
108 :
109 0 : auto get_clone() const -> std::unique_ptr<
110 : domain::BoundaryConditions::BoundaryCondition> override;
111 :
112 0 : static constexpr evolution::BoundaryConditions::Type bc_type =
113 : evolution::BoundaryConditions::Type::Ghost;
114 :
115 0 : void pup(PUP::er& p) override;
116 :
117 0 : using dg_interior_evolved_variables_tags =
118 : tmpl::list<Tags::Psi, Tags::Phi<Dim>>;
119 0 : using dg_interior_temporary_tags =
120 : tmpl::list<domain::Tags::Coordinates<Dim, Frame::Inertial>,
121 : Tags::ConstraintGamma2>;
122 0 : using dg_gridless_tags = tmpl::list<>;
123 :
124 0 : std::optional<std::string> dg_ghost(
125 : gsl::not_null<Scalar<DataVector>*> psi_ext,
126 : gsl::not_null<Scalar<DataVector>*> pi_ext,
127 : gsl::not_null<tnsr::i<DataVector, Dim, Frame::Inertial>*> phi_ext,
128 : gsl::not_null<Scalar<DataVector>*> gamma2_ext,
129 : const std::optional<
130 : tnsr::I<DataVector, Dim, Frame::Inertial>>& /*face_mesh_velocity*/,
131 : const tnsr::i<DataVector, Dim, Frame::Inertial>& normal_covector,
132 : const Scalar<DataVector>& psi,
133 : const tnsr::i<DataVector, Dim, Frame::Inertial>& phi,
134 : const tnsr::I<DataVector, Dim, Frame::Inertial>& coords,
135 : const Scalar<DataVector>& gamma2) const;
136 :
137 : private:
138 0 : detail::SphericalRadiationType type_{
139 : detail::SphericalRadiationType::Sommerfeld};
140 : };
141 : } // namespace ScalarWave::BoundaryConditions
142 :
143 : template <>
144 : struct Options::create_from_yaml<
145 : ScalarWave::BoundaryConditions::detail::SphericalRadiationType> {
146 : template <typename Metavariables>
147 : static typename ScalarWave::BoundaryConditions::detail::SphericalRadiationType
148 : create(const Options::Option& options) {
149 : return ScalarWave::BoundaryConditions::detail::
150 : convert_spherical_radiation_type_from_yaml(options);
151 : }
152 : };
|