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 <pup.h> 8 : #include <string> 9 : #include <vector> 10 : 11 : #include "DataStructures/Tensor/TypeAliases.hpp" 12 : #include "Elliptic/BoundaryConditions/BoundaryCondition.hpp" 13 : #include "Elliptic/BoundaryConditions/BoundaryConditionType.hpp" 14 : #include "Options/Context.hpp" 15 : #include "Options/String.hpp" 16 : #include "Utilities/Gsl.hpp" 17 : #include "Utilities/Serialization/CharmPupable.hpp" 18 : #include "Utilities/TMPL.hpp" 19 : 20 : /// \cond 21 : class DataVector; 22 : /// \endcond 23 : 24 : namespace Poisson::BoundaryConditions { 25 : 26 : /// Impose Robin boundary conditions \f$a u + b n_i \nabla^i u = c\f$. The 27 : /// boundary condition is imposed as Neumann-type (i.e. on \f$n_i \nabla^i u\f$) 28 : /// if \f$|b| > 0\f$ and as Dirichlet-type (i.e. on \f$u\f$) if \f$b = 0\f$. 29 : template <size_t Dim> 30 1 : class Robin : public elliptic::BoundaryConditions::BoundaryCondition<Dim> { 31 : private: 32 0 : using Base = elliptic::BoundaryConditions::BoundaryCondition<Dim>; 33 : 34 : public: 35 0 : static constexpr Options::String help = 36 : "Robin boundary conditions a * u + b * n_i grad(u)^i = c. The boundary " 37 : "condition is imposed as Neumann-type (i.e. on n_i grad(u)^i) if abs(b) " 38 : "> 0 and as Dirichlet-type (i.e. on u) if b = 0."; 39 : 40 0 : struct DirichletWeight { 41 0 : using type = double; 42 0 : static constexpr Options::String help = "The parameter 'a'"; 43 : }; 44 : 45 0 : struct NeumannWeight { 46 0 : using type = double; 47 0 : static constexpr Options::String help = "The parameter 'b'"; 48 : }; 49 : 50 0 : struct Constant { 51 0 : using type = double; 52 0 : static constexpr Options::String help = "The parameter 'c'"; 53 : }; 54 : 55 0 : using options = tmpl::list<DirichletWeight, NeumannWeight, Constant>; 56 : 57 0 : Robin() = default; 58 0 : Robin(const Robin&) = default; 59 0 : Robin& operator=(const Robin&) = default; 60 0 : Robin(Robin&&) = default; 61 0 : Robin& operator=(Robin&&) = default; 62 0 : ~Robin() = default; 63 : 64 : /// \cond 65 : explicit Robin(CkMigrateMessage* m) : Base(m) {} 66 : using PUP::able::register_constructor; 67 : WRAPPED_PUPable_decl_template(Robin); 68 : /// \endcond 69 : 70 0 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition> get_clone() 71 : const override { 72 : return std::make_unique<Robin>(*this); 73 : } 74 : 75 0 : Robin(double dirichlet_weight, double neumann_weight, double constant, 76 : const Options::Context& context = {}); 77 : 78 0 : double dirichlet_weight() const { return dirichlet_weight_; } 79 0 : double neumann_weight() const { return neumann_weight_; } 80 0 : double constant() const { return constant_; } 81 : 82 0 : std::vector<elliptic::BoundaryConditionType> boundary_condition_types() 83 : const override { 84 : return {1, neumann_weight_ == 0. 85 : ? elliptic::BoundaryConditionType::Dirichlet 86 : : elliptic::BoundaryConditionType::Neumann}; 87 : } 88 : 89 0 : using argument_tags = tmpl::list<>; 90 0 : using volume_tags = tmpl::list<>; 91 : 92 0 : void apply(gsl::not_null<Scalar<DataVector>*> field, 93 : gsl::not_null<Scalar<DataVector>*> n_dot_field_gradient, 94 : const tnsr::i<DataVector, Dim>& deriv_field) const; 95 : 96 0 : using argument_tags_linearized = tmpl::list<>; 97 0 : using volume_tags_linearized = tmpl::list<>; 98 : 99 0 : void apply_linearized( 100 : gsl::not_null<Scalar<DataVector>*> field_correction, 101 : gsl::not_null<Scalar<DataVector>*> n_dot_field_gradient_correction, 102 : const tnsr::i<DataVector, Dim>& deriv_field_correction) const; 103 : 104 0 : void pup(PUP::er& p) override; 105 : 106 : private: 107 0 : double dirichlet_weight_ = std::numeric_limits<double>::signaling_NaN(); 108 0 : double neumann_weight_ = std::numeric_limits<double>::signaling_NaN(); 109 0 : double constant_ = std::numeric_limits<double>::signaling_NaN(); 110 : }; 111 : 112 : template <size_t Dim> 113 0 : bool operator==(const Robin<Dim>& lhs, const Robin<Dim>& rhs); 114 : 115 : template <size_t Dim> 116 0 : bool operator!=(const Robin<Dim>& lhs, const Robin<Dim>& rhs); 117 : 118 : } // namespace Poisson::BoundaryConditions