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 : };