NiHu  2.0
helmholtz_2d_singular_collocation_integrals.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-2018 Peter Fiala <fiala@hit.bme.hu>
4 // Copyright (C) 2012-2018 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 
21 #ifndef NIHU_HELMHOLTZ_2D_SINGULAR_COLLOCATION_INTEGRALS_HPP_INCLUDED
22 #define NIHU_HELMHOLTZ_2D_SINGULAR_COLLOCATION_INTEGRALS_HPP_INCLUDED
23 
24 #include <boost/math/constants/constants.hpp>
25 
26 #include "helmholtz_kernel.hpp"
27 #include "field_type_helpers.hpp"
28 #include "lib_element.hpp"
30 #include "normal_derivative_singular_integrals.hpp"
31 #include "../core/match_types.hpp"
32 #include "../core/singular_integral_shortcut.hpp"
33 #include "../util/math_functions.hpp"
34 
35 namespace NiHu
36 {
37 
47 template <class TestField, class TrialField, size_t order>
49 {
50  typedef TestField test_field_t;
51  typedef TrialField trial_field_t;
52 
53  typedef typename test_field_t::nset_t test_shape_t;
54  typedef typename trial_field_t::nset_t trial_shape_t;
55 
56  static size_t const nTest = test_shape_t::num_nodes;
57  static size_t const nTrial = trial_shape_t::num_nodes;
58 
59  typedef Eigen::Matrix<std::complex<double>, nTest, nTrial> result_t;
60 
61  typedef typename trial_field_t::elem_t elem_t;
62  typedef typename elem_t::domain_t domain_t;
63 
64  typedef typename domain_t::xi_t xi_t;
65  typedef typename elem_t::x_t x_t;
66 
69 
70 
71 public:
76  template <class WaveNumber>
77  static result_t eval(elem_t const &elem, WaveNumber const &k)
78  {
79 #ifdef NIHU_PRINT_DEBUG
80  static bool printed = false;
81  if (!printed) {
82  std::cout << "Using helmholtz_2d_SLP_collocation_curved" << std::endl;
83  printed = true;
84  }
85 #endif
86 
87  using namespace boost::math::double_constants;
88 
90 
91  result_t result = result_t::Zero();
92 
93  // traverse collocation points (rows)
94  for (size_t i = 0; i < nTest; ++i) {
95  xi_t const &xi0 = test_shape_t::corner_at(i);
96 
97  // the singular location
98  x_t x = elem.get_x(xi0);
99 
100  // traverse integration domains
101  for (int dom = 0; dom < 2; ++dom) {
102  xi_t xi_lim = domain_t::get_corner(dom);
103  double jac = std::abs(xi_lim(0) - xi0(0));
104 
105  // traverse regular quadrature points
106  for (auto const &q : reg_quadrature_t::quadrature) {
107  // transform quadrature to [0 1];
108  double v = (q.get_xi()(0) + 1.) / 2.;
109  double wv = q.get_w() / 2;
110 
111  xi_t eta = xi0 + v * (xi_lim - xi0);
112  double r = (elem.get_x(eta) - x).norm();
113  double Jeta = elem.get_dx(eta).norm();
114 
115  // evaluate Green's function
116  std::complex<double> Gtot;
117  kernel.template eval<0>(r, &Gtot);
118  double Glog = -std::log(v) / two_pi;
119  std::complex<double> Greg = Gtot - Glog;
120 
121  // integrate difference numerically
122  result.row(i) += Greg * Jeta * jac * wv
123  * trial_shape_t::template eval_shape<0>(eta);
124  } // loop over regular quadrature
125 
126  // traverse log quadrature points
127  for (auto const &q : log_quadrature_t::quadrature) {
128  double v = q.get_xi()(0);
129  double wv = q.get_w();
130 
131  xi_t eta = xi0 + v * (xi_lim - xi0);
132  double Jeta = elem.get_dx(eta).norm();
133 
134  // evaluate Green's function
135  double Glog = 1.0 / two_pi;
136 
137  // integrate difference numerically
138  result.row(i) += Glog * Jeta * jac * wv
139  * trial_shape_t::template eval_shape<0>(eta);
140  } // loop over log quadrature
141  } // loop over subdomains
142  } // loop over collocation points
143 
144  return result;
145  } // function eval
146 }; //class helmholtz_2d_SLP_collocation_curved
147 
148 
155 template <unsigned expansion_length>
157 {
158 public:
165  template <class wavenumber_t>
166  static std::complex<double> eval(
167  line_1_elem const &elem,
168  line_1_elem::x_t const &x0,
169  wavenumber_t const &k)
170  {
171 #ifdef NIHU_PRINT_DEBUG
172  static bool printed = false;
173  if (!printed) {
174  std::cout << "Using helmholtz_2d_SLP_collocation_constant_line" << std::endl;
175  printed = true;
176  }
177 #endif
178 
179  using namespace boost::math::double_constants;
180 
181  std::complex<double> const c(euler, half_pi);
182 
183  // compute elem radius
184  auto R = (x0 - elem.get_coords().col(0)).norm();
185 
186  auto Q = k * R / 2.;
187  auto clnq = c + std::log(Q);
188 
189  auto res(clnq - 1.); // initial (k=0) value of the result
190  decltype(Q) B(1.); // the power term in the series
191  double Cn = 0.0; // the harmonic series up to n = 0
192  for (unsigned n = 1; n <= expansion_length; ++n) {
193  B *= -Q*Q / n / n; // the actual power term
194  Cn += 1. / n; // the actual harmonic term
195  res += B / (2 * n + 1) * (clnq - Cn - 1. / (2 * n + 1));
196  }
197 
198  return -R / pi * res;
199  } // function eval
200 }; // helmholtz_2d_SLP_collocation_constant_line
201 
202 
204 template <class TestField, class TrialField, size_t order>
206 {
207  typedef TestField test_field_t;
208  typedef TrialField trial_field_t;
209 
210  typedef typename test_field_t::nset_t test_shape_t;
211  typedef typename trial_field_t::nset_t trial_shape_t;
212 
213  static size_t const nTest = test_shape_t::num_nodes;
214  static size_t const nTrial = trial_shape_t::num_nodes;
215 
216  typedef Eigen::Matrix<std::complex<double>, nTest, nTrial> result_t;
217 
218  typedef typename trial_field_t::elem_t elem_t;
219  typedef typename elem_t::domain_t domain_t;
220 
221  typedef typename domain_t::xi_t xi_t;
222  typedef typename elem_t::x_t x_t;
223 
225 
226 public:
227 
228  template <class wave_number_t>
229  static result_t eval(elem_t const &elem, wave_number_t const &k)
230  {
231 #ifdef NIHU_PRINT_DEBUG
232  static bool printed = false;
233  if (!printed) {
234  std::cout << "Using helmholtz_2d_DLP_collocation_general" << std::endl;
235  printed = true;
236  }
237 #endif
238 
239  result_t result = result_t::Zero();
240 
242 
243  // traverse collocation points
244  for (size_t i = 0; i < nTest; ++i) {
245  xi_t xi0 = test_shape_t::corner_at(i);
246 
247  // singular point and normal at singular point
248  x_t x = elem.get_x(xi0);
249 
250  for (size_t dom = 0; dom < 2; ++dom) {
251  xi_t const &a = domain_t::get_corner(dom);
252 
253  // traverse quadrature points
254  for (auto it = quadr_t::quadrature.begin(); it != quadr_t::quadrature.end(); ++it) {
255  // transform quadrature to [a xi0]
256  xi_t xi = it->get_xi() * ((xi0(0)-a(0))/2.) + (xi0+a)/2.;
257  double w = it->get_w() * std::abs(xi0(0)-a(0))/2.;
258  double rho = xi(0) - xi0(0);
259 
260  // get trial location, jacobian and normal
261  x_t y = elem.get_x(xi);
262  x_t Jyvec = elem.get_normal(xi);
263 
264  // evaluate Green's function
265  std::complex<double> G = kernel(x, y, Jyvec);
266  // multiply by Shape function and Jacobian
267  auto N = trial_shape_t::template eval_shape<0>(xi);
268  auto F = G * N;
269 
270  // integrate difference numerically
271  result.row(i) += F * w;
272  } // quadrature points
273  } // domains
274  } // collocation points
275  return result;
276  } // function eval
277 }; // class helmholtz_2d_DLP_collocation_general
278 
279 
286 template <class TestField, class TrialField, size_t order>
288 {
289  typedef TestField test_field_t;
290  typedef TrialField trial_field_t;
291 
292  typedef typename test_field_t::nset_t test_shape_t;
293  typedef typename trial_field_t::nset_t trial_shape_t;
294 
295  static size_t const nTest = test_shape_t::num_nodes;
296  static size_t const nTrial = trial_shape_t::num_nodes;
297 
298  typedef Eigen::Matrix<std::complex<double>, nTest, nTrial> result_t;
299 
300  typedef typename trial_field_t::elem_t elem_t;
301  typedef typename elem_t::domain_t domain_t;
302 
303  typedef typename domain_t::xi_t xi_t;
304  typedef typename elem_t::x_t x_t;
305 
307 
308 public:
309  template <class wave_number_t>
310  static result_t eval(elem_t const &elem, wave_number_t const &k)
311  {
312 #ifdef NIHU_PRINT_DEBUG
313  static bool printed = false;
314  if (!printed) {
315  std::cout << "Using helmholtz_2d_DLPt_collocation_general" << std::endl;
316  printed = true;
317  }
318 #endif
319 
320  result_t result = result_t::Zero();
321 
323 
324  // traverse collocation points
325  for (size_t i = 0; i < nTest; ++i)
326  {
327  xi_t xi0 = test_shape_t::corner_at(i);
328 
329  // singular point and normal at singular point
330  x_t x = elem.get_x(xi0);
331  x_t Jxvec = elem.get_normal(xi0);
332  x_t nx = Jxvec.normalized();
333 
334  for (size_t dom = 0; dom < 2; ++dom) {
335  xi_t const &a = domain_t::get_corner(dom);
336 
337  // traverse quadrature points
338  for (auto it = quadr_t::quadrature.begin(); it != quadr_t::quadrature.end(); ++it) {
339  // transform quadrature to [a xi0]
340  xi_t xi = it->get_xi() * ((xi0(0)-a(0))/2.) + (xi0+a)/2.;
341  double w = it->get_w() * std::abs(xi0(0)-a(0)) / 2.;
342  double rho = xi(0) - xi0(0);
343 
344  // get trial location, jacobian and normal
345  x_t y = elem.get_x(xi);
346  x_t Jyvec = elem.get_normal(xi);
347  double jac = Jyvec.norm();
348 
349  // evaluate Green's function
350  std::complex<double> G = kernel(x, y, nx);
351  // multiply by Shape function and Jacobian
352  auto N = trial_shape_t::template eval_shape<0>(xi);
353  auto F = G * jac * N;
354 
355  // integrate numerically
356  result.row(i) += F * w;
357  } // quadrature points
358  } // domains
359  } // collocation points
360  return result;
361  } // function eval
362 }; // class helmholtz_2d_DLPt_collocation_general
363 
364 
370 template <class TestField, class TrialField, size_t order>
372 {
373  typedef TestField test_field_t;
374  typedef TrialField trial_field_t;
375 
376  typedef typename test_field_t::nset_t test_shape_t;
377  typedef typename trial_field_t::nset_t trial_shape_t;
378 
379  static size_t const nTest = test_shape_t::num_nodes;
380  static size_t const nTrial = trial_shape_t::num_nodes;
381 
382  typedef Eigen::Matrix<std::complex<double>, nTest, nTrial> result_t;
383 
384  typedef typename trial_field_t::elem_t elem_t;
385  typedef typename elem_t::domain_t domain_t;
386 
387  typedef typename domain_t::xi_t xi_t;
388  typedef typename elem_t::x_t x_t;
389 
391 
392 public:
393 
398  template <class WaveNumber>
399  static result_t eval(elem_t const &elem, WaveNumber const &k)
400  {
401 #ifdef NIHU_PRINT_DEBUG
402  static bool printed = false;
403  if (!printed) {
404  std::cout << "Using helmholtz_2d_HSP_collocation_general" << std::endl;
405  printed = true;
406  }
407 #endif
408 
409  using namespace boost::math::double_constants;
410 
411  // instantiate and clear result matrix
412  result_t result = result_t::Zero();
413 
414  // instantiate the kernel
416 
417  // integration limits in the reference domain
418  xi_t const &a = domain_t::get_corner(0);
419  xi_t const &b = domain_t::get_corner(1);
420 
421  // traverse collocation points
422  for (size_t i = 0; i < nTest; ++i)
423  {
424  // the collocation point
425  xi_t const &xi0 = test_shape_t::corner_at(i);
426 
427  // trial shape function and its derivative at the singular point
428  auto N0 = trial_shape_t::template eval_shape<0>(xi0);
429  auto N1 = trial_shape_t::template eval_shape<1>(xi0);
430 
431  // singular point and normal at singular point in physical domain
432  x_t x = elem.get_x(xi0);
433  x_t Jxvec = elem.get_normal(xi0);
434  x_t nx = Jxvec.normalized();
435  double jac0 = Jxvec.norm();
436 
437  // traverse quadrature points
438  for (auto it = quadr_t::quadrature.begin(); it != quadr_t::quadrature.end(); ++it)
439  {
440  // transform quadrature to [a xi0]
441  xi_t xi = it->get_xi() * ((xi0(0)-a(0))/2.) + (xi0+a)/2.;
442  double w = it->get_w() * ((xi0(0)-a(0))/2.);
443  double rho = xi(0) - xi0(0);
444 
445  // get trial location, jacobian and normal
446  x_t y = elem.get_x(xi);
447  x_t Jyvec = elem.get_normal(xi);
448  x_t ny = Jyvec.normalized();
449  double jac = Jyvec.norm();
450 
451  // evaluate Green's function
452  std::complex<double> G = kernel(x, y, nx, ny);
453  // multiply by Shape function and Jacobian
454  auto N = trial_shape_t::template eval_shape<0>(xi);
455  auto F = (G * jac) * N;
456  // evaluate singular part
457  auto F0 = (
458  (N0/rho + N1)/rho/jac0
459  - k*k/2. * N0 * jac0 * std::log(std::abs(rho) * jac0)
460  ) / two_pi;
461 
462  // integrate difference numerically
463  result.row(i) += (F - F0) * w;
464  }
465 
466  // traverse quadrature points
467  for (auto it = quadr_t::quadrature.begin(); it != quadr_t::quadrature.end(); ++it)
468  {
469  // transform quadrature to [xi0 b];
470  xi_t xi = it->get_xi() * ((b(0)-xi0(0))/2.) + (xi0+b)/2.;
471  double w = it->get_w() * ((b(0)-xi0(0))/2.);
472  double rho = xi(0) - xi0(0);
473 
474  // get trial location, jacobian and normal
475  x_t y = elem.get_x(xi);
476  x_t Jyvec = elem.get_normal(xi);
477  x_t ny = Jyvec.normalized();
478  double jac = Jyvec.norm();
479 
480  // evaluate Green's function
481  std::complex<double> G = kernel(x, y, nx, ny);
482  // multiply by Shape function and Jacobian
483  auto N = trial_shape_t::template eval_shape<0>(xi);
484  auto F = (G * jac) * N;
485  // evaluate singular part
486  auto F0 = (
487  (N0/rho + N1)/rho/jac0
488  - k*k/2. * N0 * jac0 * std::log(std::abs(rho) * jac0)
489  ) / two_pi;
490 
491  // integrate difference numerically
492  result.row(i) += (F - F0) * w;
493  }
494 
495  // add analytic integral of singular part
496  double d1 = std::abs(a(0) - xi0(0)) * jac0;
497  double d2 = std::abs(b(0) - xi0(0)) * jac0;
498  result.row(i) += (
499  ((1./(a(0)-xi0(0)) - 1./(b(0)-xi0(0))) * N0 +
500  std::log(std::abs((b(0)-xi0(0)) / (a(0)-xi0(0)))) * N1) / jac0
501  - k*k/2. *
502  N0 * (d1 * (std::log(d1) - 1.) + d2 * (std::log(d2) - 1.))
503  ) / two_pi;
504  }
505  return result;
506  }
507 };
508 
509 
511 template <class TestField, class TrialField, size_t order>
513 {
514  typedef TestField test_field_t;
515  typedef TrialField trial_field_t;
516 
517  typedef typename test_field_t::nset_t test_shape_t;
518  typedef typename trial_field_t::nset_t trial_shape_t;
519 
520  static size_t const nTest = test_shape_t::num_nodes;
521  static size_t const nTrial = trial_shape_t::num_nodes;
522 
523  typedef Eigen::Matrix<std::complex<double>, nTest, nTrial> result_t;
524 
525  typedef NiHu::line_1_elem elem_t;
526  typedef typename elem_t::domain_t domain_t;
527 
528  typedef typename domain_t::xi_t xi_t;
529  typedef typename elem_t::x_t x_t;
530 
532 
533 public:
534 
539  template <class WaveNumber>
540  static result_t eval(elem_t const &elem, WaveNumber const &k)
541  {
542 #ifdef NIHU_PRINT_DEBUG
543  static bool printed = false;
544  if (!printed) {
545  std::cout << "Using helmholtz_2d_HSP_collocation_straight_line" << std::endl;
546  printed = true;
547  }
548 #endif
549 
550  using namespace boost::math::double_constants;
551 
552  // instantiate and clear result matrix
553  result_t result = result_t::Zero();
554 
555  // instantiate the kernel
557 
558  // integration limits in the reference domain
559  xi_t const &a = domain_t::get_corner(0);
560  xi_t const &b = domain_t::get_corner(1);
561 
562  // traverse collocation points
563  for (size_t i = 0; i < nTest; ++i)
564  {
565  // the collocation point
566  xi_t const &xi0 = test_shape_t::corner_at(i);
567 
568  // trial shape function and its derivative at the singular point
569  auto N0 = trial_shape_t::template eval_shape<0>(xi0);
570  auto N1 = trial_shape_t::template eval_shape<1>(xi0);
571 
572  // singular point and normal in physical domain
573  x_t x = elem.get_x(xi0);
574  x_t Jvec = elem.get_normal(xi0);
575  x_t n = Jvec.normalized();
576  double jac = Jvec.norm();
577 
578  // traverse quadrature points
579  for (auto it = quadr_t::quadrature.begin(); it != quadr_t::quadrature.end(); ++it)
580  {
581  // transform quadrature to [a xi0]
582  xi_t xi = it->get_xi() * ((xi0(0)-a(0))/2.) + (xi0+a)/2.;
583  double w = it->get_w() * ((xi0(0)-a(0))/2.);
584  double rho = xi(0) - xi0(0);
585 
586  // get trial location, jacobian and normal
587  x_t y = elem.get_x(xi);
588 
589  // evaluate Green's function
590  std::complex<double> G = kernel(x, y, n, n);
591  // multiply by Shape function and Jacobian
592  auto N = trial_shape_t::template eval_shape<0>(xi);
593  auto F = (G * jac) * N;
594  // evaluate singular part
595  auto F0 = (
596  (N0/rho + N1)/rho/jac
597  - k*k/2. * N0 * jac * std::log(std::abs(rho) * jac)
598  ) / two_pi;
599 
600  // integrate difference numerically
601  result.row(i) += (F - F0) * w;
602  }
603 
604  // traverse quadrature points
605  for (auto it = quadr_t::quadrature.begin(); it != quadr_t::quadrature.end(); ++it)
606  {
607  // transform quadrature to [xi0 b];
608  xi_t xi = it->get_xi() * ((b(0)-xi0(0))/2.) + (xi0+b)/2.;
609  double w = it->get_w() * ((b(0)-xi0(0))/2.);
610  double rho = xi(0) - xi0(0);
611 
612  // get trial location, jacobian and normal
613  x_t y = elem.get_x(xi);
614 
615  // evaluate Green's function
616  std::complex<double> G = kernel(x, y, n, n);
617  // multiply by Shape function and Jacobian
618  auto N = trial_shape_t::template eval_shape<0>(xi);
619  auto F = (G * jac) * N;
620  // evaluate singular part
621  auto F0 = (
622  (N0/rho + N1)/rho/jac
623  - k*k/2. * N0 * jac * std::log(std::abs(rho) * jac)
624  ) / two_pi;
625 
626  // integrate difference numerically
627  result.row(i) += (F - F0) * w;
628  }
629 
630  // add analytic integral of singular part
631  double d1 = std::abs(a(0) - xi0(0)) * jac;
632  double d2 = std::abs(b(0) - xi0(0)) * jac;
633  result.row(i) += (
634  ((1./(a(0)-xi0(0)) - 1./(b(0)-xi0(0))) * N0 +
635  std::log(std::abs((b(0)-xi0(0)) / (a(0)-xi0(0)))) * N1) / jac
636  - k*k/2. *
637  N0 * (d1 * (std::log(d1) - 1.) + d2 * (std::log(d2) - 1.))
638  ) / two_pi;
639  }
640  return result;
641  }
642 };
643 
644 
649 template <class WaveNumber, class TestField, class TrialField>
651  helmholtz_2d_SLP_kernel<WaveNumber>, TestField, TrialField, match::match_1d_type,
652  typename std::enable_if<
653  is_collocational<TestField, TrialField>::value &&
654  is_constant_line<TrialField>::value
655  >::type
656 >
657 {
658 public:
666  template <class result_t>
667  static result_t &eval(
668  result_t &result,
670  field_base<TestField> const &,
671  field_base<TrialField> const &trial_field,
672  element_match const &)
673  {
675  trial_field.get_elem(),
676  trial_field.get_elem().get_center(),
677  kernel.derived().get_wave_number());
678 
679  return result;
680  }
681 };
682 
683 
688 template <class WaveNumber, class TestField, class TrialField>
690  helmholtz_2d_SLP_kernel<WaveNumber>, TestField, TrialField, match::match_1d_type,
691  typename std::enable_if<
692  is_collocational<TestField, TrialField>::value &&
693  !is_constant_line<TrialField>::value
694  >::type
695 >
696 {
697 public:
705  template <class result_t>
706  static result_t &eval(
707  result_t &result,
709  field_base<TestField> const &,
710  field_base<TrialField> const &trial_field,
711  element_match const &)
712  {
714  TestField, TrialField, 30
715  >::eval(trial_field.get_elem(),
716  kernel.derived().get_wave_number());
717 
718  return result;
719  }
720 };
721 
722 
727 template <class WaveNumber, class TestField, class TrialField>
729  helmholtz_2d_DLP_kernel<WaveNumber>, TestField, TrialField, match::match_1d_type,
730  typename std::enable_if<
731  is_collocational<TestField, TrialField>::value &&
732  !(std::is_same<typename TrialField::elem_t::lset_t, line_1_shape_set>::value)
733  >::type
734 >
735 {
736 public:
744  template <class result_t>
745  static result_t &eval(
746  result_t &result,
748  field_base<TestField> const &,
749  field_base<TrialField> const &trial_field,
750  element_match const &)
751  {
753  trial_field.get_elem(),
754  kernel.derived().get_wave_number());
755 
756  return result;
757  }
758 };
759 
760 
765 template <class WaveNumber, class TestField, class TrialField>
767  helmholtz_2d_DLPt_kernel<WaveNumber>, TestField, TrialField, match::match_1d_type,
768  typename std::enable_if<
769  is_collocational<TestField, TrialField>::value &&
770  !(std::is_same<typename TrialField::elem_t::lset_t, line_1_shape_set>::value)
771  >::type
772 >
773 {
774 public:
782  template <class result_t>
783  static result_t &eval(
784  result_t &result,
786  field_base<TestField> const &,
787  field_base<TrialField> const &trial_field,
788  element_match const &)
789  {
791  trial_field.get_elem(),
792  kernel.derived().get_wave_number());
793 
794  return result;
795  }
796 };
797 
798 
803 template <class WaveNumber, class TestField, class TrialField>
805  helmholtz_2d_HSP_kernel<WaveNumber>, TestField, TrialField, match::match_1d_type,
806  typename std::enable_if<
807  is_collocational<TestField, TrialField>::value &&
808  std::is_same<typename TrialField::elem_t::lset_t, line_1_shape_set>::value
809  >::type
810 >
811 {
812 public:
820  template <class result_t>
821  static result_t &eval(
822  result_t &result,
824  field_base<TestField> const &,
825  field_base<TrialField> const &trial_field,
826  element_match const &)
827  {
829  trial_field.get_elem(),
830  kernel.derived().get_wave_number());
831 
832  return result;
833  }
834 };
835 
836 
841 template <class WaveNumber, class TestField, class TrialField>
843  helmholtz_2d_HSP_kernel<WaveNumber>, TestField, TrialField, match::match_1d_type,
844  typename std::enable_if<
845  is_collocational<TestField, TrialField>::value &&
846  !std::is_same<typename TrialField::elem_t::lset_t, line_1_shape_set>::value
847  >::type
848 >
849 {
850 public:
858  template <class result_t>
859  static result_t &eval(
860  result_t &result,
862  field_base<TestField> const &,
863  field_base<TrialField> const &trial_field,
864  element_match const &)
865  {
867  trial_field.get_elem(),
868  kernel.derived().get_wave_number());
869 
870  return result;
871  }
872 };
873 
874 } // end of namespace NiHu
875 
876 #endif // NIHU_HELMHOLTZ_2D_SINGULAR_COLLOCATION_INTEGRALS_HPP_INCLUDED
877 
NiHu::log_quad_store
Definition: quadrature_store_helper.hpp:24
NiHu::surface_element::get_normal
normal_return_type get_normal(xi_t const &xi=domain_t::get_center()) const
return element normal
Definition: element.hpp:611
NiHu::helmholtz_2d_HSP_collocation_general
Collocational integral of the 2D HSP kernel over a general curved line with general shape sets Full s...
Definition: helmholtz_2d_singular_collocation_integrals.hpp:371
NiHu::surface_element::x_t
element_traits::location_value_type< Derived, 0 >::type x_t
type of the element's physical location variable
Definition: element.hpp:220
NiHu::singular_integral_shortcut< helmholtz_2d_DLPt_kernel< WaveNumber >, TestField, TrialField, match::match_1d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&!(std::is_same< typename TrialField::elem_t::lset_t, line_1_shape_set >::value) >::type >::eval
static result_t & eval(result_t &result, kernel_base< helmholtz_2d_DLPt_kernel< WaveNumber > > const &kernel, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
evaluate singular integral
Definition: helmholtz_2d_singular_collocation_integrals.hpp:783
NiHu::volume_element::x_t
element_traits::location_value_type< Derived, 0 >::type x_t
type of the element's physical location variable
Definition: element.hpp:220
NiHu::singular_integral_shortcut< helmholtz_2d_HSP_kernel< WaveNumber >, TestField, TrialField, match::match_1d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&!std::is_same< typename TrialField::elem_t::lset_t, line_1_shape_set >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< helmholtz_2d_HSP_kernel< WaveNumber > > const &kernel, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
evaluate singular integral
Definition: helmholtz_2d_singular_collocation_integrals.hpp:859
NiHu::regular_quad_store
store-wrapper of a statically stored quadrature
Definition: quadrature_store_helper.hpp:13
laplace_2d_singular_integrals.hpp
Analytical expressions for the singular integrals of 2D Laplace kernels.
NiHu::surface_element::domain_t
typename base_t::domain_t domain_t
the domain type
Definition: element.hpp:569
NiHu::kernel_base
CRTP base class of all BEM kernels.
Definition: kernel.hpp:133
NiHu::helmholtz_2d_SLP_collocation_constant_line::eval
static std::complex< double > eval(line_1_elem const &elem, line_1_elem::x_t const &x0, wavenumber_t const &k)
Evaluate the integral.
Definition: helmholtz_2d_singular_collocation_integrals.hpp:166
NiHu::singular_integral_shortcut< helmholtz_2d_SLP_kernel< WaveNumber >, TestField, TrialField, match::match_1d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&!is_constant_line< TrialField >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< helmholtz_2d_SLP_kernel< WaveNumber > > const &kernel, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
evaluate singular integral
Definition: helmholtz_2d_singular_collocation_integrals.hpp:706
NiHu::element_match
class describing the adjacency (match) state of two elements
Definition: element_match.hpp:39
NiHu::helmholtz_2d_SLP_collocation_curved::eval
static result_t eval(elem_t const &elem, WaveNumber const &k)
Evaluate the integral.
Definition: helmholtz_2d_singular_collocation_integrals.hpp:77
NiHu::helmholtz_2d_HSP_collocation_straight_line
Collocational singular integral of the 2D Helmholtz HSP kernel over a straight line element.
Definition: helmholtz_2d_singular_collocation_integrals.hpp:512
NiHu::singular_integral_shortcut
a shortcut for the user to define customised singular integral methods
Definition: double_integral.hpp:709
NiHu::helmholtz_2d_HSP_collocation_straight_line::eval
static result_t eval(elem_t const &elem, WaveNumber const &k)
evaluate the singular integral
Definition: helmholtz_2d_singular_collocation_integrals.hpp:540
NiHu::match::match_1d_type
std::integral_constant< int, 1 > match_1d_type
two elements are adjacent with a 1d (line) match
Definition: match_types.hpp:40
NiHu::helmholtz_2d_HSP_collocation_general::eval
static result_t eval(elem_t const &elem, WaveNumber const &k)
evaluate the singular integral
Definition: helmholtz_2d_singular_collocation_integrals.hpp:399
NiHu::field_base::get_elem
const elem_t & get_elem() const
return underlying element
Definition: field.hpp:149
NiHu::field_base
CRTP base class of all fields.
Definition: field.hpp:111
NiHu::surface_element
class describing a surface element that provides a normal vector
Definition: element.hpp:451
NiHu::helmholtz_2d_DLPt_collocation_general
Collocational integral of the 2D DLPt kernel over a general curved line with general shape sets.
Definition: helmholtz_2d_singular_collocation_integrals.hpp:287
NiHu::singular_integral_shortcut< helmholtz_2d_DLP_kernel< WaveNumber >, TestField, TrialField, match::match_1d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&!(std::is_same< typename TrialField::elem_t::lset_t, line_1_shape_set >::value) >::type >::eval
static result_t & eval(result_t &result, kernel_base< helmholtz_2d_DLP_kernel< WaveNumber > > const &kernel, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
evaluate singular integral
Definition: helmholtz_2d_singular_collocation_integrals.hpp:745
NiHu::log_quad_store::quadrature
static const log_gaussian_quadrature quadrature
definition of the statically stored quadrature member
Definition: quadrature_store_helper.hpp:26
NiHu::volume_element::domain_t
typename base_t::domain_t domain_t
the domain type
Definition: element.hpp:637
NiHu::helmholtz_2d_SLP_collocation_constant_line
Collocational singular integral of the 2D Helmholtz SLP kernel over a constant line element.
Definition: helmholtz_2d_singular_collocation_integrals.hpp:156
NiHu::singular_integral_shortcut< helmholtz_2d_SLP_kernel< WaveNumber >, TestField, TrialField, match::match_1d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&is_constant_line< TrialField >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< helmholtz_2d_SLP_kernel< WaveNumber > > const &kernel, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
evaluate singular integral
Definition: helmholtz_2d_singular_collocation_integrals.hpp:667
NiHu::normal_derivative_kernel
Normal derivative of a distance dependent kernel.
Definition: normal_derivative_kernel.hpp:26
lib_element.hpp
helmholtz_kernel.hpp
Kernels of the Helmholtz equation .
NiHu::helmholtz_2d_DLP_collocation_general
Collocational integral of the 2D DLP kernel over a general curved line with general shape sets.
Definition: helmholtz_2d_singular_collocation_integrals.hpp:205
NiHu::helmholtz_2d_SLP_collocation_curved
Collocational integral of the 2D SLP kernel over a curved line with general shape sets.
Definition: helmholtz_2d_singular_collocation_integrals.hpp:48
NiHu::singular_integral_shortcut< helmholtz_2d_HSP_kernel< WaveNumber >, TestField, TrialField, match::match_1d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&std::is_same< typename TrialField::elem_t::lset_t, line_1_shape_set >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< helmholtz_2d_HSP_kernel< WaveNumber > > const &kernel, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
evaluate singular integral
Definition: helmholtz_2d_singular_collocation_integrals.hpp:821
NiHu::regular_quad_store::quadrature
static const gaussian_quadrature< domain_t > quadrature
the stored static quadrature member
Definition: quadrature_store_helper.hpp:16