Robin.hpp
1 // 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 
11 #include "Elliptic/BoundaryConditions/BoundaryCondition.hpp"
12 #include "Options/Options.hpp"
14 #include "Utilities/Gsl.hpp"
15 #include "Utilities/TMPL.hpp"
16 
17 /// \cond
18 class DataVector;
19 /// \endcond
20 
21 namespace Poisson::BoundaryConditions {
22 namespace detail {
23 
24 struct RobinImpl {
25  static constexpr Options::String help =
26  "Robin boundary conditions a * u + b * n_i grad(u)^i = c. The boundary "
27  "condition is imposed as Neumann-type (i.e. on n_i grad(u)^i) if abs(b) "
28  "> 0 and as Dirichlet-type (i.e. on u) if b = 0.";
29 
30  struct DirichletWeight {
31  using type = double;
32  static constexpr Options::String help = "The parameter 'a'";
33  };
34 
35  struct NeumannWeight {
36  using type = double;
37  static constexpr Options::String help = "The parameter 'b'";
38  };
39 
40  struct Constant {
41  using type = double;
42  static constexpr Options::String help = "The parameter 'c'";
43  };
44 
45  using options = tmpl::list<DirichletWeight, NeumannWeight, Constant>;
46 
47  RobinImpl() = default;
48  RobinImpl(const RobinImpl&) noexcept = default;
49  RobinImpl& operator=(const RobinImpl&) noexcept = default;
50  RobinImpl(RobinImpl&&) noexcept = default;
51  RobinImpl& operator=(RobinImpl&&) noexcept = default;
52  ~RobinImpl() noexcept = default;
53 
54  RobinImpl(double dirichlet_weight, double neumann_weight, double constant,
55  const Options::Context& context = {});
56 
57  double dirichlet_weight() const noexcept;
58  double neumann_weight() const noexcept;
59  double constant() const noexcept;
60 
61  using argument_tags = tmpl::list<>;
62  using volume_tags = tmpl::list<>;
63 
64  void apply(
66  gsl::not_null<Scalar<DataVector>*> n_dot_field_gradient) const noexcept;
67 
68  using argument_tags_linearized = tmpl::list<>;
69  using volume_tags_linearized = tmpl::list<>;
70 
71  void apply_linearized(gsl::not_null<Scalar<DataVector>*> field_correction,
73  n_dot_field_gradient_correction) const noexcept;
74 
75  void pup(PUP::er& p) noexcept;
76 
77  private:
78  double dirichlet_weight_ = std::numeric_limits<double>::signaling_NaN();
79  double neumann_weight_ = std::numeric_limits<double>::signaling_NaN();
80  double constant_ = std::numeric_limits<double>::signaling_NaN();
81 };
82 
83 bool operator==(const RobinImpl& lhs, const RobinImpl& rhs) noexcept;
84 bool operator!=(const RobinImpl& lhs, const RobinImpl& rhs) noexcept;
85 
86 } // namespace detail
87 
88 // The following implements the registration and factory-creation mechanism
89 
90 /// \cond
91 template <size_t Dim, typename Registrars>
92 struct Robin;
93 
94 namespace Registrars {
95 template <size_t Dim>
96 struct Robin {
97  template <typename Registrars>
99 };
100 } // namespace Registrars
101 /// \endcond
102 
103 /// Impose Robin boundary conditions \f$a u + b n_i \nabla^i u = c\f$. The
104 /// boundary condition is imposed as Neumann-type (i.e. on \f$n_i \nabla^i u\f$)
105 /// if \f$|b| > 0\f$ and as Dirichlet-type (i.e. on \f$u\f$) if \f$b = 0\f$.
106 template <size_t Dim, typename Registrars = tmpl::list<Registrars::Robin<Dim>>>
107 class Robin
108  : public elliptic::BoundaryConditions::BoundaryCondition<Dim, Registrars>,
109  public detail::RobinImpl {
110  private:
112 
113  public:
114  Robin() = default;
115  Robin(const Robin&) noexcept = default;
116  Robin& operator=(const Robin&) noexcept = default;
117  Robin(Robin&&) noexcept = default;
118  Robin& operator=(Robin&&) noexcept = default;
119  ~Robin() noexcept = default;
120  using RobinImpl::RobinImpl;
121 
122  /// \cond
123  explicit Robin(CkMigrateMessage* m) noexcept : Base(m) {}
124  using PUP::able::register_constructor;
126  /// \endcond
127 
129  const noexcept override {
130  return std::make_unique<Robin>(*this);
131  }
132 
133  void pup(PUP::er& p) noexcept override {
134  Base::pup(p);
135  RobinImpl::pup(p);
136  }
137 };
138 
139 /// \cond
140 template <size_t Dim, typename Registrars>
141 PUP::able::PUP_ID Robin<Dim,
142  Registrars>::my_PUP_ID = 0; // NOLINT
143 /// \endcond
144 
145 } // namespace Poisson::BoundaryConditions
CharmPupable.hpp
Options.hpp
Options::Context
Definition: Options.hpp:41
WRAPPED_PUPable_decl_template
#define WRAPPED_PUPable_decl_template(className)
Mark derived classes as serializable.
Definition: CharmPupable.hpp:22
cstddef
elliptic::BoundaryConditions::BoundaryCondition
Base class for boundary conditions for elliptic systems.
Definition: BoundaryCondition.hpp:91
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:46
Poisson::BoundaryConditions::Robin
Impose Robin boundary conditions . The boundary condition is imposed as Neumann-type (i....
Definition: Robin.hpp:107
std::numeric_limits::signaling_NaN
T signaling_NaN(T... args)
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
Gsl.hpp
TypeAliases.hpp
Options::String
const char *const String
The string used in option structs.
Definition: Options.hpp:32
std::unique_ptr< domain::BoundaryConditions::BoundaryCondition >
TMPL.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecPiecewisePolynomial.hpp:13
string