Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <cstddef> 7 : #include <string> 8 : #include <vector> 9 : 10 : #include "DataStructures/ComplexDataVector.hpp" 11 : #include "DataStructures/Tensor/TypeAliases.hpp" 12 : #include "Domain/Tags.hpp" 13 : #include "Elliptic/BoundaryConditions/BoundaryCondition.hpp" 14 : #include "Elliptic/BoundaryConditions/BoundaryConditionType.hpp" 15 : #include "Options/String.hpp" 16 : #include "Utilities/Gsl.hpp" 17 : #include "Utilities/TMPL.hpp" 18 : 19 : namespace GrSelfForce::BoundaryConditions { 20 : 21 : /*! 22 : * \brief Radial Sommerfeld boundary conditions for the m-mode metric 23 : * perturbations. 24 : * 25 : * These radial boundary conditions enforce an outgoing direction of radiation 26 : * propagation. They apply both near the Kerr horizon (inner radial 27 : * boundary) and at large distance (outer radial boundary): 28 : * 29 : * \begin{equation} 30 : * n_i F^i = i m \Omega \Psi_m 31 : * \end{equation} 32 : * 33 : * These boundary conditions currently assume a circular equatorial orbit. 34 : */ 35 1 : class Sommerfeld : public elliptic::BoundaryConditions::BoundaryCondition<2> { 36 : private: 37 0 : using Base = elliptic::BoundaryConditions::BoundaryCondition<2>; 38 0 : using GradTensorType = 39 : TensorMetafunctions::prepend_spatial_index<tnsr::aa<ComplexDataVector, 3>, 40 : 2, UpLo::Lo, Frame::Inertial>; 41 : 42 : public: 43 0 : struct BlackHoleMass { 44 0 : static constexpr Options::String help = 45 : "Kerr mass parameter 'M' of the black hole"; 46 0 : using type = double; 47 : }; 48 0 : struct BlackHoleSpin { 49 0 : static constexpr Options::String help = 50 : "Kerr dimensionless spin parameter 'chi' of the black hole"; 51 0 : using type = double; 52 : }; 53 0 : struct OrbitalRadius { 54 0 : static constexpr Options::String help = 55 : "Radius 'r_0' of the circular orbit"; 56 0 : using type = double; 57 : }; 58 0 : struct MModeNumber { 59 0 : static constexpr Options::String help = 60 : "Mode number 'm' of the scalar field"; 61 0 : using type = int; 62 : }; 63 : 64 0 : static constexpr Options::String help = 65 : "Radial Sommerfeld boundary condition"; 66 0 : using options = 67 : tmpl::list<BlackHoleMass, BlackHoleSpin, OrbitalRadius, MModeNumber>; 68 : 69 0 : Sommerfeld() = default; 70 0 : Sommerfeld(const Sommerfeld&) = default; 71 0 : Sommerfeld& operator=(const Sommerfeld&) = default; 72 0 : Sommerfeld(Sommerfeld&&) = default; 73 0 : Sommerfeld& operator=(Sommerfeld&&) = default; 74 0 : ~Sommerfeld() override = default; 75 : 76 0 : explicit Sommerfeld(double black_hole_mass, double black_hole_spin, 77 : double orbital_radius, int m_mode_number); 78 : 79 0 : double black_hole_mass() const { return black_hole_mass_; } 80 0 : double black_hole_spin() const { return black_hole_spin_; } 81 0 : double orbital_radius() const { return orbital_radius_; } 82 0 : int m_mode_number() const { return m_mode_number_; } 83 : 84 : /// \cond 85 : explicit Sommerfeld(CkMigrateMessage* m); 86 : using PUP::able::register_constructor; 87 : WRAPPED_PUPable_decl_template(Sommerfeld); 88 : /// \endcond 89 : 90 0 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition> get_clone() 91 : const override; 92 : 93 0 : std::vector<elliptic::BoundaryConditionType> boundary_condition_types() 94 : const override { 95 : return {elliptic::BoundaryConditionType::Neumann}; 96 : } 97 : 98 0 : using argument_tags = tmpl::list<>; 99 0 : using volume_tags = tmpl::list<>; 100 : 101 0 : void apply( 102 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> field, 103 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> n_dot_field_gradient, 104 : const GradTensorType& deriv_field) const; 105 : 106 0 : using argument_tags_linearized = tmpl::list<>; 107 0 : using volume_tags_linearized = tmpl::list<>; 108 : 109 0 : void apply_linearized( 110 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> field_correction, 111 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> 112 : n_dot_field_correction_gradient, 113 : const GradTensorType& deriv_field_correction) const; 114 : 115 : // NOLINTNEXTLINE 116 0 : void pup(PUP::er& p) override; 117 : 118 : private: 119 0 : friend bool operator==(const Sommerfeld& lhs, const Sommerfeld& rhs); 120 : 121 0 : double black_hole_mass_{std::numeric_limits<double>::signaling_NaN()}; 122 0 : double black_hole_spin_{std::numeric_limits<double>::signaling_NaN()}; 123 0 : double orbital_radius_{std::numeric_limits<double>::signaling_NaN()}; 124 0 : int m_mode_number_{}; 125 : }; 126 : 127 0 : bool operator!=(const Sommerfeld& lhs, const Sommerfeld& rhs); 128 : 129 : } // namespace GrSelfForce::BoundaryConditions