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/DataVector.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 1 : namespace ScalarSelfForce::BoundaryConditions { 20 : 21 : /*! 22 : * \brief Angular boundary conditions for the m-mode field. 23 : * 24 : * The angular boundary conditions are given in Eqs. (4.5-4.6) in 25 : * \cite Osburn:2022bby : 26 : * \begin{align} 27 : * &\Psi_{m\neq 0} = 0 \\ 28 : * &\partial_{\cos\theta} \Psi_{m=0} = 0 29 : * \end{align} 30 : */ 31 1 : class Angular : public elliptic::BoundaryConditions::BoundaryCondition<2> { 32 : private: 33 0 : using Base = elliptic::BoundaryConditions::BoundaryCondition<2>; 34 : 35 : public: 36 0 : struct MModeNumber { 37 0 : static constexpr Options::String help = 38 : "Mode number 'm' of the scalar field"; 39 0 : using type = int; 40 : }; 41 : 42 0 : static constexpr Options::String help = "Angular boundary condition"; 43 0 : using options = tmpl::list<MModeNumber>; 44 : 45 0 : Angular() = default; 46 0 : Angular(const Angular&) = default; 47 0 : Angular& operator=(const Angular&) = default; 48 0 : Angular(Angular&&) = default; 49 0 : Angular& operator=(Angular&&) = default; 50 0 : ~Angular() override = default; 51 : 52 0 : explicit Angular(int m_mode_number); 53 : 54 0 : int m_mode_number() const { return m_mode_number_; } 55 : 56 : /// \cond 57 : explicit Angular(CkMigrateMessage* m); 58 : using PUP::able::register_constructor; 59 : WRAPPED_PUPable_decl_template(Angular); 60 : /// \endcond 61 : 62 0 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition> get_clone() 63 : const override { 64 : return std::make_unique<Angular>(*this); 65 : } 66 : 67 0 : std::vector<elliptic::BoundaryConditionType> boundary_condition_types() 68 : const override { 69 : return {m_mode_number_ == 0 ? elliptic::BoundaryConditionType::Neumann 70 : : elliptic::BoundaryConditionType::Dirichlet}; 71 : } 72 : 73 0 : using argument_tags = tmpl::list<>; 74 0 : using volume_tags = tmpl::list<>; 75 : 76 0 : void apply(gsl::not_null<Scalar<ComplexDataVector>*> field, 77 : gsl::not_null<Scalar<ComplexDataVector>*> n_dot_field_gradient, 78 : const tnsr::i<ComplexDataVector, 2>& deriv_field) const; 79 : 80 0 : using argument_tags_linearized = tmpl::list<>; 81 0 : using volume_tags_linearized = tmpl::list<>; 82 : 83 0 : void apply_linearized( 84 : gsl::not_null<Scalar<ComplexDataVector>*> field_correction, 85 : gsl::not_null<Scalar<ComplexDataVector>*> n_dot_field_gradient_correction, 86 : const tnsr::i<ComplexDataVector, 2>& deriv_field_correction) const; 87 : 88 : // NOLINTNEXTLINE 89 0 : void pup(PUP::er& p) override; 90 : 91 : private: 92 0 : friend bool operator==(const Angular& lhs, const Angular& rhs); 93 : 94 0 : int m_mode_number_{}; 95 : }; 96 : 97 0 : bool operator!=(const Angular& lhs, const Angular& rhs); 98 : 99 : } // namespace ScalarSelfForce::BoundaryConditions