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
|