NiHu  2.0
laplace_kernel.hpp
Go to the documentation of this file.
1 // This file is a part of NiHu, a C++ BEM template library.
2 //
3 // Copyright (C) 2012-2014 Peter Fiala <fiala@hit.bme.hu>
4 // Copyright (C) 2012-2014 Peter Rucz <rucz@hit.bme.hu>
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
24 
25 #ifndef NIHU_LAPLACE_KERNEL_HPP_INCLUDED
26 #define NIHU_LAPLACE_KERNEL_HPP_INCLUDED
27 
29 #include "guiggiani_1992.hpp"
31 #include "../core/global_definitions.hpp"
32 #include "../core/gaussian_quadrature.hpp"
33 
34 #include <boost/math/constants/constants.hpp>
35 
36 #include <cmath>
37 
38 namespace NiHu
39 {
40 
44 template <class Space>
46 
47 namespace distance_dependent_kernel_traits_ns
48 {
49  template <class Space>
50  struct space<laplace_kernel<Space> > : Space {};
51 
52  template <class Space>
53  struct result<laplace_kernel<Space> >
54  {
55  typedef typename Space::scalar_t type;
56  };
57 
58  template <class Space>
60 
61  template <class Space>
62  struct is_singular<laplace_kernel<Space> > : std::true_type {};
63 
64  template <class Space>
65  struct singular_core<laplace_kernel<Space> > {
67  };
68 
69  template <class Space>
71  : std::integral_constant<unsigned, 7> {};
72 
73  template <class Scalar>
75  : asymptotic::log<1> {};
76 
77  template <class Scalar>
79  : asymptotic::log<1> {};
80 
81  template <class Scalar>
83  : asymptotic::inverse<1> {};
84 
85  template <class Scalar>
87  : asymptotic::inverse<1> {};
88 } // end of distance_dependent_kernel_traits_ns
89 
90 
93 template <class scalar>
95  : public distance_dependent_kernel<laplace_kernel<space_2d<scalar> > >
96 {
97 private:
98  // f[0] = G(r)
99  void eval_impl(std::integral_constant<unsigned, 0>, scalar r, scalar *f) const
100  {
101  using namespace boost::math::double_constants;
102  *f = -std::log(r) / two_pi;
103  }
104 
105  // f[0] = G'(r)
106  void eval_impl(std::integral_constant<unsigned, 1>, scalar r, scalar *f) const
107  {
108  using namespace boost::math::double_constants;
109  *f = -1.0 / r / two_pi;
110  }
111 
112  // f[0] = G'' - G'/r, f[1] = G'/r
113  void eval_impl(std::integral_constant<unsigned, 2>, scalar r, scalar *f) const
114  {
115  using namespace boost::math::double_constants;
116  f[1] = -1.0 / (r*r) / two_pi;
117  f[0] = -2.0 * f[1];
118  }
119 
120  void eval_impl(std::integral_constant<unsigned, 3>, scalar r, scalar *f) const
121  {
122  using namespace boost::math::double_constants;
123  auto g = 1. / (r*r*r) / two_pi;
124  f[1] = 2.0 * g;
125  f[0] = -8.0 * g;
126  }
127 
128 public:
137  template <unsigned order>
138  void eval(scalar r, scalar *f) const
139  {
140  this->eval_impl(std::integral_constant<unsigned, order>(), r, f);
141  }
142 };
143 
144 
147 template <class scalar>
149  : public distance_dependent_kernel<laplace_kernel<space_3d<scalar> > >
150 {
151  // f[0] = G(r)
152  void eval_impl(std::integral_constant<unsigned, 0>, scalar r, scalar *f) const
153  {
154  using namespace boost::math::double_constants;
155  *f = 1. / r / (4. * pi);
156  }
157 
158  // f[0] = G'(r)
159  void eval_impl(std::integral_constant<unsigned, 1>, scalar r, scalar *f) const
160  {
161  using namespace boost::math::double_constants;
162  *f = -1. / (r*r) / (4. * pi);
163  }
164 
165  // f[0] = G'' - G'/r, f[1] = G'/r
166  void eval_impl(std::integral_constant<unsigned, 2>, scalar r, scalar *f) const
167  {
168  using namespace boost::math::double_constants;
169  auto g = 1./(r*r*r)/(4. * pi);
170  f[1] = -1. * g;
171  f[0] = 3. * g;
172  }
173 
174  void eval_impl(std::integral_constant<unsigned, 3>, scalar r, scalar *f) const
175  {
176  using namespace boost::math::double_constants;
177  auto g = 1. / (r*r*r*r) / (4. * pi);
178  f[1] = 3. * g;
179  f[0] = -15. * g;
180  }
181 
182 public:
191  template <unsigned order>
192  void eval(scalar r, scalar *f) const
193  {
194  this->eval_impl(std::integral_constant<unsigned, order>(), r, f);
195  }
196 };
197 
198 
200 namespace kernel_traits_ns
201 {
202  template <class Scalar>
206  laplace_kernel<space_2d<Scalar> >
207  > {};
208 
209  template <class Scalar>
213  laplace_kernel<space_2d<Scalar> >
214  >{};
215 
216  template <class Scalar>
219  > : asymptotic::inverse<1> {};
220 
221  template <class Scalar>
224  > : asymptotic::inverse<1> {};
225 
226  template <class Scalar>
229  > : asymptotic::inverse<1> {};
230 
231  template <class Scalar>
234  > : asymptotic::inverse<1> {};
235 
236  template <class Scalar>
239  > : asymptotic::inverse<2> {};
240 
241  template <class Scalar>
244  > : asymptotic::inverse<2> {};
245 }
246 
247 namespace kernel_traits_ns
248 {
249  template <class Scalar, int Nx, int Ny>
252  > : asymptotic::inverse<1 + Nx + Ny> {};
253 
254  template <class Scalar, int Nx, int Ny>
257  > : asymptotic::inverse<1 + Nx + Ny> {};
258 
259  // the normal derivative cancels the -2 singularity on a smooth boundary
260  // but not for the case of Galerkin edge or corner match
261  template <class Scalar>
264  > : asymptotic::inverse<1> {};
265 
266  // the normal derivative cancels the -2 singularity on a smooth boundary
267  // but not for the case of Galerkin edge or corner match
268  template <class Scalar>
271  > : asymptotic::inverse<1> {};
272 }
273 
274 
293 
294 } // end of namespace NiHu
295 
296 
297 namespace NiHu
298 {
299 
301 template <class Scalar>
304 >
305 {
306 public:
307  template <class guiggiani>
308  static void eval(guiggiani &obj)
309  {
310  using namespace boost::math::double_constants;
311 
312  auto g1vec = obj.get_rvec_series(_1()) * (
313  obj.get_rvec_series(_2()).dot(obj.get_Jvec_series(_0()))
314  + obj.get_rvec_series(_1()).dot(obj.get_Jvec_series(_1()))
315  );
316 
317  auto b0vec = -obj.get_Jvec_series(_0());
318  auto b1vec = 3. * g1vec - obj.get_Jvec_series(_1());
319 
320  auto a0 = b0vec.dot(obj.get_n0()) * obj.get_shape_series(_0());
321  auto a1 = b1vec.dot(obj.get_n0()) * obj.get_shape_series(_0())
322  + b0vec.dot(obj.get_n0()) * obj.get_shape_series(_1());
323 
324  auto Sm2 = -3. * obj.get_rvec_series(_1()).dot(obj.get_rvec_series(_2()));
325 
326  obj.set_laurent_coeff(_m1(), -(Sm2 * a0 + a1) / (4. * pi));
327  obj.set_laurent_coeff(_m2(), -a0 / (4. * pi));
328  }
329 };
330 
331 } // end of namespace NiHu
332 
333 #endif // NIHU_LAPLACE_KERNEL_HPP_INCLUDED
334 
NiHu::distance_dependent_kernel_traits_ns::quadrature_family
Definition: distance_dependent_kernel.hpp:29
NiHu::kernel_traits_ns::singularity_type
return the kernel's singularity type
Definition: kernel.hpp:59
NiHu::asymptotic::log
logarithmic singularity with specified order
Definition: asymptotic_types.hpp:41
NiHu::laplace_kernel< space_2d< scalar > >::eval
void eval(scalar r, scalar *f) const
Evaluate the kernel and its derivatives.
Definition: laplace_kernel.hpp:138
NiHu::laplace_kernel< space_3d< scalar > >::eval
void eval(scalar r, scalar *f) const
Evaluate the kernel and its derivatives.
Definition: laplace_kernel.hpp:192
NiHu::scalar
metafunction returning the scalar type
Definition: matrix_traits.hpp:66
NiHu::distance_dependent_kernel_traits_ns::far_field_behaviour
Definition: distance_dependent_kernel.hpp:41
NiHu::_m2
std::integral_constant< int, -2 > _m2
shorthand for constant minus two
Definition: guiggiani_1992.hpp:64
NiHu::distance_dependent_kernel_traits_ns::singular_core
Definition: distance_dependent_kernel.hpp:35
NiHu::space
class representing a coordinate space with a scalar and a dimension
Definition: space.hpp:36
NiHu::_2
std::integral_constant< int, 2 > _2
shorthand for constant two
Definition: guiggiani_1992.hpp:75
NiHu::distance_dependent_kernel_traits_ns::result
Definition: distance_dependent_kernel.hpp:26
NiHu::distance_dependent_kernel_traits_ns::singular_quadrature_order
Definition: distance_dependent_kernel.hpp:38
guiggiani_1992.hpp
Guiggiani's method for CPV and HPF collocational integrals.
NiHu::distance_dependent_kernel
Definition: distance_dependent_kernel.hpp:18
distance_dependent_kernel.hpp
Class NiHu::distance_dependent_kernel.
NiHu::_m1
std::integral_constant< int, -1 > _m1
shorthand for constant minus one
Definition: guiggiani_1992.hpp:69
NiHu::laplace_kernel
Kernel of the Laplace equation in two and three dimensions.
Definition: laplace_kernel.hpp:45
NiHu::distance_dependent_kernel_traits_ns::is_singular
Definition: distance_dependent_kernel.hpp:32
NiHu::distance_dependent_kernel_traits_ns::space
Definition: distance_dependent_kernel.hpp:23
NiHu::kernel_traits_ns::far_field_behaviour
return the far field asymptotic behaviour of the kernel
Definition: kernel.hpp:51
NiHu::_1
std::integral_constant< int, 1 > _1
shorthand for constant one
Definition: guiggiani_1992.hpp:73
normal_derivative_kernel.hpp
Class NiHu::normal_derivative_kernel.
NiHu::asymptotic::inverse
inverse singularity with specified order
Definition: asymptotic_types.hpp:50
NiHu::normal_derivative_kernel
Normal derivative of a distance dependent kernel.
Definition: normal_derivative_kernel.hpp:26
NiHu::polar_laurent_coeffs
definition of Laurent coefficients of singularities
Definition: guiggiani_1992.hpp:64
NiHu::_0
std::integral_constant< int, 0 > _0
shorthand for constant zero
Definition: guiggiani_1992.hpp:71
NiHu::distance_dependent_kernel_traits_ns::singularity_type
Definition: distance_dependent_kernel.hpp:44
NiHu::guiggiani
Implementation of Guiggiani's method.
Definition: guiggiani_1992.hpp:84
NiHu::gauss_family_tag
tag for the family of Gaussian quadratures
Definition: gaussian_quadrature.hpp:517