NiHu  2.0
matsumoto_2010.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 
27 #ifndef MATSUMOTO_2010_HPP_INCLUDED
28 #define MATSUMOTO_2010_HPP_INCLUDED
29 
30 #include "../core/element_match.hpp"
31 #include "../core/integral_operator.hpp"
32 #include "../core/singular_integral_shortcut.hpp"
33 #include "../core/match_types.hpp"
34 #include "helmholtz_kernel.hpp"
35 #include "lib_element.hpp"
36 
37 #include <boost/math/constants/constants.hpp>
38 
39 namespace NiHu
40 {
41 
43 namespace matsumoto_internal
44 {
45 
47  template <unsigned order>
49  {
52  };
53 
55  template <unsigned order>
57 
58 }
59 
64 template <class WaveNumber, class TestField, class TrialField>
66  helmholtz_3d_HSP_kernel<WaveNumber>, TestField, TrialField, match::match_2d_type,
67  typename std::enable_if<
68  std::is_same<typename get_formalism<TestField, TrialField>::type, formalism::collocational>::value &&
69  std::is_same<typename TrialField::lset_t, tria_1_shape_set>::value &&
70  std::is_same<typename TrialField::nset_t, tria_0_shape_set>::value
71  >::type
72 >
73 {
74 public:
82  template <class result_t>
83  static result_t &eval(
84  result_t &result,
86  field_base<TestField> const &,
87  field_base<TrialField> const &trial_field,
88  element_match const &)
89  {
90  using namespace boost::math::double_constants;
91 
92  // Define the imaginary unit
93  std::complex<scalar_t> const I(0.0, 1.0);
94  // Get wave number from the kernel
95  auto const &k = kernel.derived().get_wave_number();
96 
97  // Obtain the element
98  auto const &tr_elem = trial_field.get_elem();
99  unsigned const N = tria_1_elem::num_nodes;
100 
101  // Obtain the coordinates and the center
102  auto const &coords = tr_elem.get_coords();
103  auto const &x0 = tr_elem.get_center();
104 
105  for(unsigned i = 0; i < N; ++i)
106  {
107  // Obtain the nodal distances
108  x_t const D = coords.col((i+1)%N) - coords.col(i);
109  double l = D.norm();
110 
111  // Iterate through quadrature points
112  for (auto it = quadr_t::quadrature.begin(); it != quadr_t::quadrature.end(); ++it)
113  {
114  // Actual point
115  x_t const x1 = coords.col((i+1)%N) * (1.0 + it->get_xi()(0))/2
116  + coords.col(i) * (1.0 - it->get_xi()(0))/2;
117  // Calculate distance from quadrature point
118  x_t const R = x1 - x0;
119  double r = R.norm();
120  // Calculate the Jacobian
121  double tmp = R.dot(D) / (r*l);
122  double jac = sqrt(1.0 - tmp*tmp) / r * l / 2.0;
123  // Accumulate the result
124  result(0,0) += jac * it->get_w() * (std::exp(-I*k*r) / r);
125  }
126  }
127  result(0,0) /= (-4 * pi);
128  result(0,0) -= I*k / 2.0;
129  return result;
130  }
131 private:
132  enum { quadrature_order = 31 };
133  typedef matsumoto_internal::line_quad_store<quadrature_order> quadr_t;
134  typedef typename tria_1_elem::xi_t xi_t;
135  typedef typename tria_1_elem::x_t x_t;
136  typedef typename kernel_base<helmholtz_3d_HSP_kernel<WaveNumber> >::scalar_t scalar_t;
137 };
138 
139 
144 template <class WaveNumber, class TestField, class TrialField>
146  helmholtz_3d_SLP_kernel<WaveNumber>, TestField, TrialField, match::match_2d_type,
147  typename std::enable_if<
148  std::is_same<typename get_formalism<TestField, TrialField>::type, formalism::collocational>::value &&
149  std::is_same<typename TrialField::lset_t, tria_1_shape_set>::value &&
150  std::is_same<typename TrialField::nset_t, tria_0_shape_set>::value
151  >::type
152 >
153 {
154 public:
162  template <class result_t>
163  static result_t &eval(
164  result_t &result,
166  field_base<TestField> const &,
167  field_base<TrialField> const &trial_field,
168  element_match const &)
169  {
170  using namespace boost::math::double_constants;
171 
172  // Define the imaginary unit
173  std::complex<scalar_t> const I(0.0, 1.0);
174  // Get wavenumber from the kernel
175  auto const &k = kernel.derived().get_wave_number();
176 
177  // Obtain the element
178  auto const &tr_elem = trial_field.get_elem();
179  unsigned const N = tria_1_elem::num_nodes;
180 
181  // Obtain the coordinates and the center
182  auto const &coords = tr_elem.get_coords();
183  auto const &x0 = tr_elem.get_center();
184 
185  for(unsigned i = 0; i < N; ++i)
186  {
187  // Obtain the nodal distances
188  x_t const D = coords.col((i+1)%N) - coords.col(i);
189  double l = D.norm();
190 
191 
192  // Iterate through quadrature points
193  for (auto it = quadr_t::quadrature.begin(); it != quadr_t::quadrature.end(); ++it)
194  {
195  // Actual point
196  x_t const x1 = coords.col((i+1)%N) * (1.0 + it->get_xi()(0))/2
197  + coords.col(i) * (1.0 - it->get_xi()(0))/2;
198 
199  // Calculate distance from quadrature point
200  x_t const R = x1 - x0;
201  double r = R.norm();
202  // Calculate the Jacobian
203  double tmp = R.dot(D) / (r*l);
204  double jac = sqrt(1.0 - tmp*tmp) / r * l / 2.0;
205  // Accumulate the result
206  result(0,0) += jac * it->get_w() * (std::exp(-I*k*r));
207  }
208  }
209  result(0,0) *= I / (4.0 * pi * k);
210  result(0,0) -= I/(2*k);
211  return result;
212  }
213 private:
214  enum { quadrature_order = 31 };
215  typedef matsumoto_internal::line_quad_store<quadrature_order> quadr_t;
216  typedef typename tria_1_elem::xi_t xi_t;
217  typedef typename tria_1_elem::x_t x_t;
218  typedef typename kernel_base<helmholtz_3d_SLP_kernel<WaveNumber> >::scalar_t scalar_t;
219 };
220 
221 } // end of namespace NiHu
222 
223 #endif /* MATSUMOTO_2010_HPP_INCLUDED */
224 
NiHu::matsumoto_internal::line_quad_store
store-wrapper of a statically stored line quadrature
Definition: matsumoto_2010.hpp:48
tmp
template metaprogramming functions
Definition: asymptotic_types.hpp:101
NiHu::singular_integral_shortcut< helmholtz_3d_SLP_kernel< WaveNumber >, TestField, TrialField, match::match_2d_type, typename std::enable_if< std::is_same< typename get_formalism< TestField, TrialField >::type, formalism::collocational >::value &&std::is_same< typename TrialField::lset_t, tria_1_shape_set >::value &&std::is_same< typename TrialField::nset_t, tria_0_shape_set >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< helmholtz_3d_SLP_kernel< WaveNumber > > const &kernel, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
evaluate the singular integral
Definition: matsumoto_2010.hpp:163
NiHu::kernel_base
CRTP base class of all BEM kernels.
Definition: kernel.hpp:133
NiHu::match::match_2d_type
std::integral_constant< int, 2 > match_2d_type
two elements are adjacent with a 2d (surface) match
Definition: match_types.hpp:42
NiHu::singular_integral_shortcut< helmholtz_3d_HSP_kernel< WaveNumber >, TestField, TrialField, match::match_2d_type, typename std::enable_if< std::is_same< typename get_formalism< TestField, TrialField >::type, formalism::collocational >::value &&std::is_same< typename TrialField::lset_t, tria_1_shape_set >::value &&std::is_same< typename TrialField::nset_t, tria_0_shape_set >::value >::type >::eval
static result_t & eval(result_t &result, kernel_base< helmholtz_3d_HSP_kernel< WaveNumber > > const &kernel, field_base< TestField > const &, field_base< TrialField > const &trial_field, element_match const &)
evaluate the singular integral
Definition: matsumoto_2010.hpp:83
NiHu::element_match
class describing the adjacency (match) state of two elements
Definition: element_match.hpp:39
NiHu::singular_integral_shortcut
a shortcut for the user to define customised singular integral methods
Definition: double_integral.hpp:709
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::gaussian_quadrature< line_domain >
Gaussian quadrature over a line domain.
Definition: gaussian_quadrature.hpp:107
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::matsumoto_internal::line_quad_store::quadrature
static const gaussian_quadrature< line_domain > quadrature
the stored static quadrature member
Definition: matsumoto_2010.hpp:51