NiHu  2.0
laplace_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-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 
22 
23 #ifndef LAPLACE_2D_SINGULAR_COLLOCATION_INTEGRALS_HPP_INCLUDED
24 #define LAPLACE_2D_SINGULAR_COLLOCATION_INTEGRALS_HPP_INCLUDED
25 
26 #include "../core/match_types.hpp"
27 #include "../core/singular_integral_shortcut.hpp"
28 #include "../util/math_functions.hpp"
29 #include "integral_shortcut_concepts.hpp"
30 #include "lib_element.hpp"
31 #include "laplace_kernel.hpp"
32 #include "normal_derivative_singular_integrals.hpp"
33 #include "quadrature_store_helper.hpp"
34 
35 #include <boost/math/constants/constants.hpp>
36 
37 #define NIHU_PRINT_DEBUG
38 
39 #ifdef NIHU_PRINT_DEBUG
40 #include <iostream>
41 #endif
42 
43 namespace NiHu
44 {
45 
55 template <class TestField, class TrialField, size_t order>
57 {
58  typedef TestField test_field_t;
59  typedef TrialField trial_field_t;
60 
61  typedef typename test_field_t::nset_t test_shape_t;
62  typedef typename trial_field_t::nset_t trial_shape_t;
63 
64  static size_t const nTest = test_shape_t::num_nodes;
65  static size_t const nTrial = trial_shape_t::num_nodes;
66 
67  typedef Eigen::Matrix<double, nTest, nTrial> result_t;
68  typedef Eigen::Matrix<double, 1, nTrial> result_row_t;
69 
70  typedef typename trial_field_t::elem_t elem_t;
71  typedef typename elem_t::domain_t domain_t;
72 
73  typedef typename domain_t::xi_t xi_t;
74  typedef typename elem_t::x_t x_t;
75 
77  static size_t const inner_order =
78  trial_field_t::nset_t::polynomial_order + // Ny (exact)
79  elem_t::lset_t::jacobian_order * 2; // Jy (possible overkill for quadratic, exact for linear)
81 
82 public:
83 
89  static result_row_t eval_row(xi_t const &xi0, elem_t const &elem)
90  {
91  using boost::math::double_constants::two_pi;
92 
93  result_row_t result_row;
94  result_row.setZero();
95 
96  // the singular location
97  x_t x = elem.get_x(xi0);
98 
99  // traverse integration domains
100  // dom = 0: (-1 .. xi0)
101  // dom = 1: (xi0 .. +1)
102  for (int dom = 0; dom < 2; ++dom) {
103  xi_t xi_lim = domain_t::get_corner(dom);
104  double jac = std::abs(xi_lim(0) - xi0(0));
105 
106  // the collocation point is in the corner
107  if (jac < 1e-5)
108  continue;
109 
110  // traverse regular quadrature points
111  for (auto const &q : reg_quadrature_t::quadrature) {
112  // transform quadrature to [0 1];
113  double v = (q.get_xi()(0) + 1.) / 2.;
114  double wv = q.get_w() / 2;
115 
116  xi_t eta = xi0 + v * (xi_lim - xi0);
117  double r = (elem.get_x(eta) - x).norm();
118  double Jeta = elem.get_dx(eta).norm();
119 
120  // evaluate Green's function
121  double Greg = -std::log(r / v) / two_pi;
122 
123  // integrate difference numerically
124  result_row += Greg * Jeta * jac * wv
125  * trial_shape_t::template eval_shape<0>(eta);
126  } // loop over regular quadrature
127 
128  // traverse log quadrature points
129  for (auto const &q : log_quadrature_t::quadrature) {
130  double v = q.get_xi()(0);
131  double wv = q.get_w();
132 
133  xi_t eta = xi0 + v * (xi_lim - xi0);
134  double Jeta = elem.get_dx(eta).norm();
135 
136  // evaluate Green's function
137  double Glog = 1.0 / two_pi;
138 
139  // integrate difference numerically
140  result_row += Glog * Jeta * jac * wv
141  * trial_shape_t::template eval_shape<0>(eta);
142  } // loop over log quadrature
143  } // loop over subdomains
144  return result_row;
145  }
146 
150  static result_t eval(elem_t const &elem)
151  {
152 #ifdef NIHU_PRINT_DEBUG
153  static bool printed = false;
154  if (!printed) {
155  std::cout << "Using laplace_2d_SLP_collocation_curved, inner order: " << inner_order << std::endl;
156  printed = true;
157  }
158 #endif
159 
160  result_t result;
161 
162  // traverse collocation points (rows)
163  for (size_t i = 0; i < nTest; ++i) {
164  xi_t const &xi0 = test_shape_t::corner_at(i);
165  result.row(i) = eval_row(xi0, elem);
166  } // loop over collocation points
167 
168  return result;
169  } // function eval
170 }; // class laplace_2d_SLP_collocation_curved
171 
172 
179 template <class TestField, class TrialField>
181 {
182  typedef TestField test_field_t;
183  typedef TrialField trial_field_t;
184 
185  typedef typename test_field_t::nset_t test_shape_set_t;
186  typedef typename trial_field_t::nset_t trial_shape_set_t;
187 
188  typedef line_1_elem elem_t;
189 
190  typedef typename test_shape_set_t::xi_t xi_t;
191 
192  static size_t const rows = test_shape_set_t::num_nodes;
193  static size_t const cols = trial_shape_set_t::num_nodes;
194 
195  typedef Eigen::Matrix<double, rows, cols> result_t;
196  typedef Eigen::Matrix<double, 1, cols> result_row_t;
197 
198 public:
204  static result_row_t eval_row(xi_t const &xi0, elem_t const &elem)
205  {
206  using boost::math::double_constants::two_pi;
207 
208  // get Jacobian
209  double jac = elem.get_normal().norm();
210 
211  result_row_t result_row;
212  result_row.setZero();
213 
214  for (size_t s = 0; s < 2; s++) // s == 0 : left side, s == 1 : right side
215  {
216  double sign = (s == 0 ? 1. : -1.);
217  double rho = 1. + sign * xi0(0); // length of the actual side in intrinsic
218  if (rho < 1e-5)
219  continue;
220 
221  double d = jac * rho; // physical length of the actual side
222  double logd = std::log(d);
223 
224  auto N0 = trial_shape_set_t::template eval_shape<0>(xi0);
225  result_row += N0 * d * (1. - logd);
226 
227  if (trial_shape_set_t::polynomial_order >= 1) {
228  auto N1 = (trial_shape_set_t::template eval_shape<1>(xi0) / jac).eval();
229  result_row += -sign * N1 * d * d * (1. / 2. - logd) / 2.;
230  }
231 
232  if (trial_shape_set_t::polynomial_order >= 2) {
233  auto N2 = (trial_shape_set_t::template eval_shape<2>(xi0) / jac / jac / 2.).eval();
234  result_row += N2 * d * d * d * (1. / 3. - logd) / 3.;
235  }
236  } // loop over two sides of the integration domain
237 
238  return result_row / two_pi;
239  } // function eval
240 
241 
245  static result_t eval(elem_t const &elem)
246  {
247 #ifdef NIHU_PRINT_DEBUG
248  static bool printed = false;
249  if (!printed) {
250  std::cout << "Using laplace_2d_SLP_collocation_straight" << std::endl;
251  printed = true;
252  }
253 #endif
254 
255  result_t result;
256  // traverse collocational points
257  for (size_t i = 0; i < rows; ++i) {
258  xi_t const &xi0 = test_shape_set_t::corner_at(i);
259  result.row(i) = eval_row(xi0, elem);
260  } // loop over collocation points
261  return result;
262  } // function eval
263 }; // class laplace_2d_SLP_collocation_straight
264 
265 
272 template <class TestField, class TrialField, size_t order>
274 {
275  typedef TestField test_field_t;
276  typedef TrialField trial_field_t;
277 
278  typedef typename test_field_t::nset_t test_shape_t;
279  typedef typename trial_field_t::nset_t trial_shape_t;
280 
281  static size_t const nTest = test_shape_t::num_nodes;
282  static size_t const nTrial = trial_shape_t::num_nodes;
283 
284  typedef Eigen::Matrix<double, nTest, nTrial> result_t;
285 
286  typedef typename trial_field_t::elem_t elem_t;
287  typedef typename elem_t::domain_t domain_t;
288 
289  typedef typename domain_t::xi_t xi_t;
290  typedef typename elem_t::x_t x_t;
291 
293 
295 
296 public:
300  static result_t eval(elem_t const &elem)
301  {
302 #ifdef NIHU_PRINT_DEBUG
303  static bool printed = false;
304  if (!printed) {
305  std::cout << "Using laplace_2d_DLP_collocation_curved" << std::endl;
306  printed = true;
307  }
308 #endif
309 
310  kernel_t kernel;
311 
312  result_t result = result_t::Zero();
313 
314  // traverse collocation points
315  for (size_t i = 0; i < nTest; ++i) {
316  xi_t const &xi0 = test_shape_t::corner_at(i);
317 
318  // singular point and jacobians
319  x_t x = elem.get_x(xi0);
320 
321  // traverse integration domains
322  for (int dom = 0; dom < 2; ++dom) {
323  double low = xi0(0), high = domain_t::get_corner(dom)(0);
324  xi_t center;
325  center << (low + high) / 2.;
326 
327  // traverse quadrature points
328  for (auto const &q : quadrature_t::quadrature) {
329  // transform quadrature to [low high];
330  xi_t xi = q.get_xi() * ((high - low) / 2.) + center;
331  double w = q.get_w() * (std::abs(high - low) / 2.);
332 
333  // get trial location, jacobian and normal
334  x_t y = elem.get_x(xi);
335  x_t Jy = elem.get_normal(xi);
336 
337  // evaluate Green's function
338  double G = kernel(x, y, Jy);
339  // evaluate shape function
340  auto Ny = trial_shape_t::template eval_shape<0>(xi);
341  // integrate kernel
342  result.row(i) += G * Ny * w;
343  } // quadrature points
344  } // loop over subdomains
345  } // loop over collocation points
346 
347  return result;
348  } // function eval
349 }; // laplace_2d_DLP_collocation_curved
350 
351 
358 template <class TestField, class TrialField, size_t order>
360 {
361  typedef TestField test_field_t;
362  typedef TrialField trial_field_t;
363 
364  typedef typename test_field_t::nset_t test_shape_t;
365  typedef typename trial_field_t::nset_t trial_shape_t;
366 
367  static size_t const nTest = test_shape_t::num_nodes;
368  static size_t const nTrial = trial_shape_t::num_nodes;
369 
370  typedef Eigen::Matrix<double, nTest, nTrial> result_t;
371 
372  typedef typename trial_field_t::elem_t elem_t;
373  typedef typename elem_t::domain_t domain_t;
374 
375  typedef typename domain_t::xi_t xi_t;
376  typedef typename elem_t::x_t x_t;
377 
379 
381 
382 public:
386  static result_t eval(elem_t const &elem)
387  {
388 #ifdef NIHU_PRINT_DEBUG
389  static bool printed = false;
390  if (!printed) {
391  std::cout << "Using laplace_2d_DLPt_collocation_curved" << std::endl;
392  printed = true;
393  }
394 #endif
395 
396  kernel_t kernel;
397 
398  result_t result = result_t::Zero();
399 
400  // traverse collocation points
401  for (size_t i = 0; i < nTest; ++i) {
402  xi_t const &xi0 = test_shape_t::corner_at(i);
403 
404  // singular point and jacobians
405  x_t x = elem.get_x(xi0);
406  x_t nx = elem.get_normal(xi0).normalized();
407 
408  // traverse integration domains
409  for (int dom = 0; dom < 2; ++dom) {
410  double low = xi0(0), high = domain_t::get_corner(dom)(0);
411  xi_t center;
412  center << (low + high) / 2.;
413 
414  // traverse quadrature points
415  for (auto const &q : quadrature_t::quadrature) {
416  // transform quadrature to [low high];
417  xi_t xi = q.get_xi() * ((high - low) / 2.) + center;
418  double w = q.get_w() * (std::abs(high - low) / 2.);
419 
420  // get trial location, jacobian and normal
421  x_t y = elem.get_x(xi);
422  double Jy = elem.get_dx(xi).norm();
423 
424  // evaluate Green's function
425  double G = kernel(x, y, nx);
426  // evaluate shape function
427  auto Ny = trial_shape_t::template eval_shape<0>(xi);
428  // integrate kernel
429  result.row(i) += G * Jy * Ny * w;
430  } // quadrature points
431  } // loop over subdomains
432  } // loop over collocation points
433 
434  return result;
435  } // function eval
436 }; // laplace_2d_DLPt_collocation_curved
437 
438 
444 template <class TestField, class TrialField, size_t order>
446 {
447  typedef TestField test_field_t;
448  typedef TrialField trial_field_t;
449 
450  typedef typename test_field_t::nset_t test_shape_t;
451  typedef typename trial_field_t::nset_t trial_shape_t;
452 
453  static size_t const nTest = test_shape_t::num_nodes;
454  static size_t const nTrial = trial_shape_t::num_nodes;
455 
456  typedef Eigen::Matrix<double, nTest, nTrial> result_t;
457 
458  typedef typename trial_field_t::elem_t elem_t;
459  typedef typename elem_t::domain_t domain_t;
460 
461  typedef typename domain_t::xi_t xi_t;
462  typedef typename elem_t::x_t x_t;
463 
465 
467 
468 public:
472  static result_t eval(elem_t const &elem)
473  {
474 #ifdef NIHU_PRINT_DEBUG
475  static bool printed = false;
476  if (!printed) {
477  std::cout << "Using laplace_2d_HSP_collocation_curved" << std::endl;
478  printed = true;
479  }
480 #endif
481 
482  using namespace boost::math::double_constants;
483 
484  kernel_t kernel;
485 
486  result_t result = result_t::Zero();
487 
488  xi_t const &a = domain_t::get_corner(0);
489  xi_t const &b = domain_t::get_corner(1);
490 
491  // traverse collocation points
492  for (size_t i = 0; i < nTest; ++i) {
493  xi_t const &xi0 = test_shape_t::corner_at(i);
494 
495  // trial shape function and its derivative at singular point
496  auto N0 = trial_shape_t::template eval_shape<0>(xi0);
497  auto N1 = trial_shape_t::template eval_shape<1>(xi0);
498 
499  // singular point and normal at singular point
500  x_t x = elem.get_x(xi0);
501  x_t Jxvec = elem.get_normal(xi0);
502  x_t nx = Jxvec.normalized();
503  double jac0 = Jxvec.norm();
504  double twopiJ0 = two_pi * jac0;
505 
506  for (int dom = 0; dom < 2; ++dom) {
507  double high = domain_t::get_corner(dom)(0);
508  double low = xi0(0);
509  xi_t center;
510  center << (low + high) / 2.;
511 
512  // traverse quadrature points
513  for (auto const &q : quadrature_t::quadrature) {
514  // transform quadrature to [xi0 b];
515  xi_t xi = q.get_xi() * ((high - low) / 2.) + center;
516  double w = q.get_w() * (std::abs(high - low) / 2.);
517  double rho = xi(0) - xi0(0);
518 
519  // get trial location, jacobian and normal
520  x_t y = elem.get_x(xi);
521  x_t Jyvec = elem.get_normal(xi);
522  x_t ny = Jyvec.normalized();
523  double jac = Jyvec.norm();
524 
525  // evaluate Green's function
526  double G = kernel(x, y, nx, ny);
527  // multiply by Shape function and Jacobian
528  auto N = trial_shape_t::template eval_shape<0>(xi);
529  auto F = G * N * jac;
530  // evaluate singular part
531  auto F0 = (N0 / rho + N1) / rho / twopiJ0;
532 
533  // integrate difference numerically
534  result.row(i) += (F - F0) * w;
535  } // loop over quadrature points
536  } // loop over domains
537 
538  // add analytic integral of singular part
539  result.row(i) += ((1. / (a(0) - xi0(0)) - 1. / (b(0) - xi0(0))) * N0 +
540  std::log(std::abs((b(0) - xi0(0)) / (a(0) - xi0(0)))) * N1) / twopiJ0;
541  } // collocation points
542  return result;
543  } // function eval
544 }; // class laplace_2d_HSP_collocation_curved
545 
546 
551 template <class TestField, class TrialField>
553 {
554  typedef TestField test_field_t;
555  typedef TrialField trial_field_t;
556 
557  typedef typename test_field_t::nset_t test_shape_set_t;
558  typedef typename trial_field_t::nset_t trial_shape_set_t;
559 
560  typedef typename test_field_t::elem_t elem_t;
561 
562  typedef typename test_shape_set_t::xi_t xi_t;
563 
564  static size_t const nTest = test_shape_set_t::num_nodes;
565  static size_t const nTrial = trial_shape_set_t::num_nodes;
566 
567  typedef Eigen::Matrix<double, nTest, nTrial> result_t;
568 
569 public:
573  static result_t eval(elem_t const &elem)
574  {
575  using namespace boost::math::double_constants;
576 
577 #ifdef NIHU_PRINT_DEBUG
578  static bool printed = false;
579  if (!printed) {
580  std::cout << "Using laplace_2d_HSP_collocation_straight" << std::endl;
581  printed = true;
582  }
583 #endif
584 
585  double jac = elem.get_normal().norm();
586 
587  result_t result = result_t::Zero();
588 
589  // integration limits in intrinsic coordinates
590  double const a = -1.;
591  double const b = +1.;
592 
593  for (size_t i = 0; i < nTest; ++i) {
594  xi_t xi0 = test_shape_set_t::corner_at(i);
595  auto N = trial_shape_set_t::template eval_shape<0>(xi0);
596  result.row(i) = N * (-1. / (b - xi0(0)) - -1. / (a - xi0(0)));
597 
598  if (trial_shape_set_t::polynomial_order >= 1) {
599  auto dN = trial_shape_set_t::template eval_shape<1>(xi0);
600  result.row(i) += dN * std::log(std::abs((b - xi0(0)) / (a - xi0(0))));
601  }
602 
603  if (trial_shape_set_t::polynomial_order >= 2) {
604  auto ddN = trial_shape_set_t::template eval_shape<2>(xi0);
605  result.row(i) += ddN / 2. * (b - a);
606  }
607  } // collocation points
608 
609  return result / (two_pi * jac);
610  } // function eval
611 }; // class laplace_2d_HSP_collocation_straight
612 
616 template <class TestField, class TrialField>
618  typename std::enable_if<
619  is_collocational<TestField, TrialField>::value &&
620  is_straight_line<TrialField>::value
621  >::type
622 >
623 {
624 public:
630  template <class result_t>
631  static result_t &eval(
632  result_t &result,
634  field_base<TestField> const &,
635  field_base<TrialField> const &trial_field,
636  element_match const &)
637  {
639  TestField, TrialField
640  >::eval(trial_field.get_elem());
641  return result;
642  }
643 };
644 
645 
649 template <class TestField, class TrialField>
651  typename std::enable_if<
652  is_collocational<TestField, TrialField>::value &&
653  is_straight_line<TrialField>::value
654  >::type
655 >
656 {
657  typedef typename TrialField::elem_t trial_elem_t;
658  typedef typename trial_elem_t::domain_t domain_t;
659  typedef typename domain_t::xi_t xi_t;
660  static unsigned const order = 8;
662  typedef typename TestField::nset_t test_nset_t;
663  typedef typename TrialField::nset_t trial_nset_t;
664  static size_t const nTest = test_nset_t::num_nodes;
665 
666 public:
674  template <class result_t>
675  static result_t &eval(
676  result_t &result,
678  field_base<TestField> const &test_field,
679  field_base<TrialField> const &trial_field,
680  element_match const &match)
681  {
682  unsigned test_idx = match.get_overlap().get_ind1();
683  auto test_singular_xi = TestField::elem_t::lset_t::corner_at(test_idx);
684 
685  unsigned trial_idx = match.get_overlap().get_ind2();
686  auto trial_singular_xi = TrialField::elem_t::lset_t::corner_at(trial_idx);
687 
688  auto const &test_elem = test_field.get_elem();
689  auto const &trial_elem = trial_field.get_elem();
690 
691  for (size_t i = 0; i < nTest; ++i)
692  {
693  auto xi0 = TestField::nset_t::corner_at(i);
694  if (xi0 == test_singular_xi)
695  {
696  // singular integral
697  result.row(i) = laplace_2d_SLP_collocation_straight<TestField, TrialField>::eval_row(trial_singular_xi, trial_field.get_elem());
698  }
699  else
700  {
701  result.row(i).setZero();
702  for (auto const &q : reg_quadrature_t::quadrature) {
703  xi_t xi = q.get_xi();
704  double w = q.get_w();
705  double jac = trial_elem.get_normal(xi).norm();
706  double K = kernel(test_elem.get_x(xi0), trial_elem.get_x(xi));
707  result.row(i) += (w * jac * K) * trial_nset_t::template eval_shape<0>(xi);
708  }
709  }
710  }
711 
712  return result;
713  }
714 };
715 
716 
717 
721 template <class TestField, class TrialField>
723  typename std::enable_if<
724  is_collocational<TestField, TrialField>::value &&
725  is_straight_line<TrialField>::value
726  >::type
727 >
728 {
729  typedef typename TrialField::elem_t trial_elem_t;
730  typedef typename trial_elem_t::x_t x_t;
731  typedef typename trial_elem_t::domain_t domain_t;
732  typedef typename domain_t::xi_t xi_t;
733  static unsigned const order = 8;
735  typedef typename TestField::nset_t test_nset_t;
736  typedef typename TrialField::nset_t trial_nset_t;
737  static size_t const nTest = test_nset_t::num_nodes;
738 
739 public:
747  template <class result_t>
748  static result_t &eval(
749  result_t &result,
751  field_base<TestField> const &test_field,
752  field_base<TrialField> const &trial_field,
753  element_match const &match)
754  {
755  unsigned test_idx = match.get_overlap().get_ind1();
756  auto test_singular_xi = TestField::elem_t::lset_t::corner_at(test_idx);
757 
758  // unsigned trial_idx = match.get_overlap().get_ind2();
759  // auto trial_singular_xi = TrialField::elem_t::lset_t::corner_at(trial_idx);
760 
761  auto const &test_elem = test_field.get_elem();
762  auto const &trial_elem = trial_field.get_elem();
763 
764  for (size_t i = 0; i < nTest; ++i)
765  {
766  auto xi0 = TestField::nset_t::corner_at(i);
767  if (xi0 == test_singular_xi)
768  {
769  // singular integral
770  result.row(i).setZero();
771  }
772  else
773  {
774  result.row(i).setZero();
775  for (auto const &q : reg_quadrature_t::quadrature) {
776  xi_t xi = q.get_xi();
777  double w = q.get_w();
778  x_t normal = trial_elem.get_normal(xi);
779  x_t unit_normal = normal.normalized();
780  double jac = normal.norm();
781  double K = kernel.derived()(test_elem.get_x(xi0), trial_elem.get_x(xi), unit_normal);
782  result.row(i) += (w * jac * K) * trial_nset_t::template eval_shape<0>(xi);
783  }
784  }
785  }
786 
787  return result;
788  }
789 };
790 
791 
792 
793 
797 template <class TestField, class TrialField>
798 // requires Collocational<TestField, TrialField> && NotStraightLine<TrialField>
800  typename std::enable_if<
801  is_collocational<TestField, TrialField>::value &&
802  !is_straight_line<TrialField>::value
803  >::type
804 >
805 {
806 public:
812  template <class result_t>
813  static result_t &eval(
814  result_t &result,
816  field_base<TestField> const &,
817  field_base<TrialField> const &trial_field,
818  element_match const &)
819  {
821  TestField, TrialField, 8
822  >::eval(trial_field.get_elem());
823  return result;
824  }
825 };
826 
827 
831 template <class TestField, class TrialField>
832 // requires Collocational<TestField, TrialField> && NotStraightLine<TrialField>
834  typename std::enable_if<
835  is_collocational<TestField, TrialField>::value &&
836  !is_straight_line<TrialField>::value
837  >::type
838 >
839 {
840 public:
846  template <class result_t>
847  static result_t &eval(
848  result_t &result,
850  field_base<TestField> const &,
851  field_base<TrialField> const &trial_field,
852  element_match const &)
853  {
855  trial_field.get_elem());
856  return result;
857  }
858 };
859 
860 
864 template <class TestField, class TrialField>
865 // requires Collocational<TestField, TrialField> && NotStraightLine<TrialField>
867  typename std::enable_if<
868  is_collocational<TestField, TrialField>::value &&
869  !is_straight_line<TrialField>::value
870  >::type
871 >
872 {
873 public:
879  template <class result_t>
880  static result_t &eval(
881  result_t &result,
883  field_base<TestField> const &,
884  field_base<TrialField> const &trial_field,
885  element_match const &)
886  {
888  trial_field.get_elem());
889  return result;
890  }
891 };
892 
893 
897 template <class TestField, class TrialField>
898 // requires Collocational<TestField, TrialField> && NotStraightLine<TrialField>
900  typename std::enable_if<
901  is_collocational<TestField, TrialField>::value &&
902  !is_straight_line<TrialField>::value
903  >::type
904 >
905 {
906 public:
912  template <class result_t>
913  static result_t &eval(
914  result_t &result,
916  field_base<TestField> const &,
917  field_base<TrialField> const &trial_field,
918  element_match const &)
919  {
921  TestField, TrialField, 10
922  >::eval(trial_field.get_elem());
923  return result;
924  }
925 };
926 
927 
931 template <class TestField, class TrialField>
932 // requires Collocational<TestField, TrialField> && StraightLine<TrialField>
934  typename std::enable_if<
935  is_collocational<TestField, TrialField>::value &&
936  is_straight_line<TrialField>::value
937  >::type
938 >
939 {
940 public:
946  template <class result_t>
947  static result_t &eval(
948  result_t &result,
950  field_base<TestField> const &,
951  field_base<TrialField> const &trial_field,
952  element_match const &)
953  {
955  trial_field.get_elem());
956  return result;
957  }
958 };
959 
960 } // namespace NiHu
961 
962 #endif
NiHu::log_quad_store
Definition: quadrature_store_helper.hpp:24
NiHu::singular_integral_shortcut< laplace_2d_HSP_kernel, TestField, TrialField, match::match_1d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&is_straight_line< TrialField >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< laplace_2d_HSP_kernel > const &, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
Evaluate the integral.
Definition: laplace_2d_singular_collocation_integrals.hpp:947
NiHu::singular_integral_shortcut< laplace_2d_SLP_kernel, TestField, TrialField, match::match_1d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&is_straight_line< TrialField >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< laplace_2d_SLP_kernel > const &, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
Evaluate the integral.
Definition: laplace_2d_singular_collocation_integrals.hpp:631
NiHu::bessel::K
make_complex< T >::type K(T const &z)
K_nu(z) modified Bessel function.
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::singular_integral_shortcut< laplace_2d_HSP_kernel, TestField, TrialField, match::match_1d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&!is_straight_line< TrialField >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< laplace_2d_HSP_kernel > const &, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
evaluate singular integral
Definition: laplace_2d_singular_collocation_integrals.hpp:913
NiHu::laplace_2d_HSP_collocation_straight::eval
static result_t eval(elem_t const &elem)
Evaluate the integral.
Definition: laplace_2d_singular_collocation_integrals.hpp:573
NiHu::laplace_2d_SLP_collocation_straight::eval
static result_t eval(elem_t const &elem)
Evaluate the integral.
Definition: laplace_2d_singular_collocation_integrals.hpp:245
laplace_kernel.hpp
implementation of kernels of the Laplace equation
NiHu::laplace_2d_DLP_collocation_curved::eval
static result_t eval(elem_t const &elem)
Evaluate the integral.
Definition: laplace_2d_singular_collocation_integrals.hpp:300
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::laplace_2d_DLPt_collocation_curved::eval
static result_t eval(elem_t const &elem)
Evaluate the integral.
Definition: laplace_2d_singular_collocation_integrals.hpp:386
NiHu::regular_quad_store
store-wrapper of a statically stored quadrature
Definition: quadrature_store_helper.hpp:13
NiHu::match::match_0d_type
std::integral_constant< int, 0 > match_0d_type
two elements are adjacent with a 0d (vertex) match
Definition: match_types.hpp:38
NiHu::element_match::get_overlap
const element_overlapping & get_overlap() const
return overlapping state
Definition: element_match.hpp:58
NiHu::kernel_base
CRTP base class of all BEM kernels.
Definition: kernel.hpp:133
NiHu::singular_integral_shortcut< laplace_2d_DLP_kernel, TestField, TrialField, match::match_0d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&is_straight_line< TrialField >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< laplace_2d_DLP_kernel > const &kernel, field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, element_match const &match)
Evaluate the integral.
Definition: laplace_2d_singular_collocation_integrals.hpp:748
NiHu::singular_integral_shortcut< laplace_2d_DLP_kernel, TestField, TrialField, match::match_1d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&!is_straight_line< TrialField >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< laplace_2d_DLP_kernel > const &, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
evaluate singular integral
Definition: laplace_2d_singular_collocation_integrals.hpp:847
NiHu::element_match
class describing the adjacency (match) state of two elements
Definition: element_match.hpp:39
NiHu::laplace_2d_SLP_collocation_straight
Collocational integral of the SLP kernel over a straight line.
Definition: laplace_2d_singular_collocation_integrals.hpp:180
NiHu::laplace_2d_HSP_collocation_curved::eval
static result_t eval(elem_t const &elem)
Evaluate the integral.
Definition: laplace_2d_singular_collocation_integrals.hpp:472
NiHu::singular_integral_shortcut
a shortcut for the user to define customised singular integral methods
Definition: double_integral.hpp:709
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::singular_integral_shortcut< laplace_2d_DLPt_kernel, TestField, TrialField, match::match_1d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&!is_straight_line< TrialField >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< laplace_2d_DLPt_kernel > const &, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
evaluate singular integral
Definition: laplace_2d_singular_collocation_integrals.hpp:880
NiHu::field_base::get_elem
const elem_t & get_elem() const
return underlying element
Definition: field.hpp:149
NiHu::element_overlapping::get_ind2
unsigned get_ind2(void) const
return index of first coincident node in element 2
Definition: element.hpp:55
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::laplace_2d_SLP_collocation_straight::eval_row
static result_row_t eval_row(xi_t const &xi0, elem_t const &elem)
evaluate a row of the result matrix (single collocation point)
Definition: laplace_2d_singular_collocation_integrals.hpp:204
NiHu::element_overlapping::get_ind1
unsigned get_ind1(void) const
return index of first coincident node in element 1
Definition: element.hpp:49
NiHu::laplace_2d_HSP_collocation_straight
Collocational integral of the HSP kernel over a straight line.
Definition: laplace_2d_singular_collocation_integrals.hpp:552
NiHu::singular_integral_shortcut< laplace_2d_SLP_kernel, TestField, TrialField, match::match_0d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&is_straight_line< TrialField >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< laplace_2d_SLP_kernel > const &kernel, field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, element_match const &match)
Evaluate the integral.
Definition: laplace_2d_singular_collocation_integrals.hpp:675
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::laplace_2d_DLPt_collocation_curved
Collocational integral of the DLPt kernel over a curved line.
Definition: laplace_2d_singular_collocation_integrals.hpp:359
NiHu::laplace_2d_SLP_collocation_curved
Collocational integral of the SLP kernel.
Definition: laplace_2d_singular_collocation_integrals.hpp:56
NiHu::normal_derivative_kernel
Normal derivative of a distance dependent kernel.
Definition: normal_derivative_kernel.hpp:26
lib_element.hpp
NiHu::laplace_2d_HSP_collocation_curved
Collocational integral of the HSP kernel over a curved line.
Definition: laplace_2d_singular_collocation_integrals.hpp:445
NiHu::laplace_2d_DLP_collocation_curved
Collocational integral of the DLP kernel over a curved line.
Definition: laplace_2d_singular_collocation_integrals.hpp:273
NiHu::laplace_2d_SLP_collocation_curved::eval_row
static result_row_t eval_row(xi_t const &xi0, elem_t const &elem)
evaluate a row of the result matrix (single collocation point)
Definition: laplace_2d_singular_collocation_integrals.hpp:89
NiHu::laplace_2d_SLP_collocation_curved::eval
static result_t eval(elem_t const &elem)
Evaluate the integral.
Definition: laplace_2d_singular_collocation_integrals.hpp:150
NiHu::regular_quad_store::quadrature
static const gaussian_quadrature< domain_t > quadrature
the stored static quadrature member
Definition: quadrature_store_helper.hpp:16
NiHu::singular_integral_shortcut< laplace_2d_SLP_kernel, TestField, TrialField, match::match_1d_type, typename std::enable_if< is_collocational< TestField, TrialField >::value &&!is_straight_line< TrialField >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< laplace_2d_SLP_kernel > const &, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
Evaluate the integral.
Definition: laplace_2d_singular_collocation_integrals.hpp:813