Bembel
DoubleLayerPotential.hpp
1 // This file is part of Bembel, the higher order C++ boundary element library.
2 //
3 // Copyright (C) 2024 see <http://www.bembel.eu>
4 //
5 // It was written as part of a cooperation of J. Doelz, H. Harbrecht, S. Kurz,
6 // M. Multerer, S. Schoeps, and F. Wolf at Technische Universitaet Darmstadt,
7 // Universitaet Basel, and Universita della Svizzera italiana, Lugano. This
8 // source code is subject to the GNU General Public License version 3 and
9 // provided WITHOUT ANY WARRANTY, see <http://www.bembel.eu> for further
10 // information.
11 #ifndef BEMBEL_SRC_HELMHOLTZ_DOUBLELAYERPOTENTIAL_HPP_
12 #define BEMBEL_SRC_HELMHOLTZ_DOUBLELAYERPOTENTIAL_HPP_
13 
14 namespace Bembel {
15 // forward declaration of class HelmholtzDoubleLayerPotential in order to define
16 // traits
17 template <typename LinOp>
18 class HelmholtzDoubleLayerPotential;
19 
20 template <typename LinOp>
22  typedef Eigen::VectorXcd::Scalar Scalar;
23  static constexpr int OutputSpaceDimension = 1;
24 };
25 
29 template <typename LinOp>
31  : public PotentialBase<HelmholtzDoubleLayerPotential<LinOp>, LinOp> {
32  // implementation of the kernel evaluation, which may be based on the
33  // information available from the superSpace
34  public:
36  Eigen::Matrix<typename PotentialReturnScalar<
38  std::complex<double>>::Scalar,
39  1, 1>
40  evaluateIntegrand_impl(const FunctionEvaluator<LinOp> &fun_ev,
41  const ElementTreeNode &element,
42  const Eigen::Vector3d &point,
43  const SurfacePoint &p) const {
44  // get evaluation points on unit square
45  auto s = p.segment<2>(0);
46 
47  // get quadrature weights
48  auto ws = p(2);
49 
50  // get points on geometry and tangential derivatives
51  auto x_f = p.segment<3>(3);
52  auto x_f_dx = p.segment<3>(6);
53  auto x_f_dy = p.segment<3>(9);
54 
55  // compute unnormalized normal from tangential derivatives
56  auto x_n = x_f_dx.cross(x_f_dy);
57 
58  // assemble Galerkin solution
59  auto cauchy_value = fun_ev.evaluate(element, p);
60 
61  // integrand without basis functions
62  // dot: adjoint in first variable
63  auto integrand = evaluateKernelGrad(point, x_f, x_n) * cauchy_value * ws;
64 
65  return integrand;
66  }
67 
71  std::complex<double> evaluateKernelGrad(const Eigen::Vector3d &x,
72  const Eigen::Vector3d &y,
73  const Eigen::Vector3d &y_n) const {
74  auto c = x - y;
75  auto r = c.norm();
76  auto r3 = r * r * r;
77  auto i = std::complex<double>(0., 1.);
78  return c.dot(y_n) * std::exp(-i * wavenumber_ * r) *
79  (1. + i * wavenumber_ * r) / 4. / BEMBEL_PI / r3;
80  }
82  // setters
84  void set_wavenumber(std::complex<double> wavenumber) {
85  wavenumber_ = wavenumber;
86  }
88  // getters
90  std::complex<double> get_wavenumber() { return wavenumber_; }
91 
92  private:
93  std::complex<double> wavenumber_;
94 };
95 
96 } // namespace Bembel
97 #endif // BEMBEL_SRC_HELMHOLTZ_DOUBLELAYERPOTENTIAL_HPP_
The ElementTreeNode corresponds to an element in the element tree.
std::complex< double > evaluateKernelGrad(const Eigen::Vector3d &x, const Eigen::Vector3d &y, const Eigen::Vector3d &y_n) const
Gradient of fundamental solution of Helmholtz problem.
Eigen::Matrix< double, 12, 1 > SurfacePoint
typedef of SurfacePoint
Routines for the evalutation of pointwise errors.
Definition: AnsatzSpace.hpp:14
struct containing specifications on the linear operator has to be specialized or derived for any part...
functional base class. this serves as a common interface for existing functionals.
Definition: Potential.hpp:81
Base case for specifying the return type of the potential.
Definition: Potential.hpp:36
struct containing specifications on the functional has to be specialized or derived for any particula...
Definition: Potential.hpp:28