NiHu  2.0
elastodynamics_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-2015 Peter Fiala <fiala@hit.bme.hu>
4 // Copyright (C) 2012-2015 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 
26 #ifndef ELASTODYNAMICS_KERNEL_HPP_INCLUDED
27 #define ELASTODYNAMICS_KERNEL_HPP_INCLUDED
28 
29 #include <boost/math/constants/constants.hpp>
30 #include <boost/math/special_functions/bessel.hpp>
31 
32 #include "../core/global_definitions.hpp"
33 #include "../core/kernel.hpp"
34 #include "../core/gaussian_quadrature.hpp"
35 #include "location_normal.hpp"
36 #include "elastostatics_kernel.hpp"
37 
38 namespace NiHu
39 {
40 
43 {
44 public:
53  elastodynamics_data(double nu, double rho, double mu, double omega)
54  : m_nu(nu), m_rho(rho), m_mu(mu), m_omega(omega) {}
55  double get_poisson_ratio() const { return m_nu; }
56  double get_mass_density() const { return m_rho; }
57  double get_shear_modulus() const { return m_mu; }
58  double get_frequency() const { return m_omega; }
59 
60 private:
61  double m_nu;
62  double m_rho;
63  double m_mu;
64  double m_omega;
65 };
66 
67 class elastodynamics_3d_U_kernel;
68 
70 template <>
72 {
75  using result_t = Eigen::Matrix<std::complex<double>, 3, 3>;
77  static bool const is_symmetric = true;
79  static bool const is_singular = true;
80 };
81 
83 template <>
85 {
87  static unsigned const singular_quadrature_order = 7;
89 };
90 
92  : public kernel_base<elastodynamics_3d_U_kernel>
93  , public elastodynamics_data
94 {
95 public:
96  elastodynamics_3d_U_kernel(double nu, double rho, double mu, double omega)
97  : elastodynamics_data(nu, rho, mu, omega)
98  {
99  }
100 
101  result_t operator()(
102  location_input_3d const &x,
103  location_input_3d const &y) const
104  {
105  using namespace std::complex_literals;
106  using namespace boost::math::double_constants;
107 
108  // compute distance and its gradient
109  auto rvec = y.get_x() - x.get_x();
110  auto r = rvec.norm();
111  auto gradr = rvec.normalized();
112 
113  // material properties and Helmholtz numbers
114  auto nu = get_poisson_ratio();
115  auto a2 = (1.-2.*nu)/2./(1.-nu);
116  auto a = std::sqrt(a2);
117  auto mu = get_shear_modulus();
118  auto rho = get_mass_density();
119  auto cS = std::sqrt(mu/rho);
120 
121  auto om = get_frequency();
122  auto kSr = om / cS * r;
123  auto kPr = a * kSr;
124 
125  std::complex<double> psi =
126  std::exp(-1.i*kPr) * a2 * (1.i/kPr + 1./(kPr*kPr)) +
127  std::exp(-1.i*kSr) * (1. - 1.i/kSr - 1./(kSr*kSr));
128 
129  std::complex<double> chi =
130  std::exp(-1.i*kPr) * a2 * (1. - 3.i/kPr - 3./(kPr*kPr)) -
131  std::exp(-1.i*kSr) * (1. - 3.i/kSr - 3./(kSr*kSr));
132 
133  // matrix valued result
134  return ( psi * result_t::Identity() + chi * (gradr * gradr.transpose()) ) / (4.*pi*mu*r);
135  }
136 }; // end of class elastodynamics_3d_U_kernel
137 
138 
139 
142 
144 template <>
146 {
149  using result_t = Eigen::Matrix<std::complex<double>, 3, 3>;
151  static bool const is_symmetric = false;
153  static bool const is_singular = true;
154 };
155 
157 template <>
159 {
161  static unsigned const singular_quadrature_order = 7;
163 };
164 
166  : public kernel_base<elastodynamics_3d_T_kernel>
167  , public elastodynamics_data
168 {
169 public:
170  elastodynamics_3d_T_kernel(double nu, double rho, double mu, double omega)
171  : elastodynamics_data(nu, rho, mu, omega)
172  {
173  }
174 
175  result_t operator()(
176  location_input_3d const &x,
177  location_normal_input_3d const &y) const
178  {
179  using namespace std::complex_literals;
180  using namespace boost::math::double_constants;
181 
182  // compute distance and its gradient
183  auto rvec = y.get_x() - x.get_x();
184  auto r = rvec.norm();
185  auto const &n = y.get_unit_normal();
186  auto gradr = rvec.normalized();
187  double rdn = gradr.dot(n);
188 
189  // material properties and Helmholtz numbers
190  auto nu = get_poisson_ratio();
191  auto a2 = (1.-2.*nu)/2./(1.-nu);
192  auto a = std::sqrt(a2);
193  auto mu = get_shear_modulus();
194  auto lambdapermu = (1./a2 - 2.);
195  auto rho = get_mass_density();
196  auto cS = std::sqrt(mu/rho);
197 
198  auto om = get_frequency();
199  auto kSr = om / cS * r;
200  auto kPr = a * kSr;
201 
202  std::complex<double> psi =
203  std::exp(-1.i*kPr) * a2 * ( 1.i/kPr + 1./(kPr*kPr)) +
204  std::exp(-1.i*kSr) * (1. - 1.i/kSr - 1./(kSr*kSr));
205 
206  std::complex<double> chi =
207  std::exp(-1.i*kPr) * a2 * (1. - 3.i/kPr - 3./(kPr*kPr)) -
208  std::exp(-1.i*kSr) * (1. - 3.i/kSr - 3./(kSr*kSr));
209 
210  std::complex<double> dpsi =
211  std::exp(-1.i*kPr) * a2 * (1. - 2.i/kPr - 2./(kPr*kPr)) -
212  std::exp(-1.i*kSr) * (1. + 1.i*kSr - 2.i/kSr - 2./(kSr*kSr));
213 
214  std::complex<double> dchi =
215  std::exp(-1.i*kSr) * (3. + 1.i*kSr - 6.i/kSr - 6./(kSr*kSr)) -
216  std::exp(-1.i*kPr) * a2 * (3. + 1.i*kPr - 6.i/kPr - 6./(kPr*kPr));
217 
218  std::complex<double> A = dpsi - psi;
219  std::complex<double> B = dchi - 3.*chi;
220  std::complex<double> C = chi;
221 
222  // matrix valued result
223  return (
224  rdn * (result_t::Identity() * (A+C) + 2.*B*(gradr * gradr.transpose()))
225  +
226  (2.*C + lambdapermu*(A+B+4.*C)) * (gradr * n.transpose())
227  +
228  (A+C) * (n * gradr.transpose())
229  ) / (4.*pi*r*r);
230  }
231 }; // end of class elastodynamics_3d_T_kernel
232 
233 
234 
236 
238 template <>
240 {
243  using result_t = Eigen::Matrix<std::complex<double>, 2, 2>;
245  static bool const is_symmetric = true;
246  using far_field_behaviour_t = asymptotic::inverse<1>; // \todo check this
247  static bool const is_singular = true;
248 };
249 
251 template <>
253 {
255  static unsigned const singular_quadrature_order = 7;
257 };
258 
260  : public kernel_base<elastodynamics_2d_U_kernel>
261  , public elastodynamics_data
262 {
263 public:
264  elastodynamics_2d_U_kernel(double nu, double rho, double mu, double omega)
265  : elastodynamics_data(nu, rho, mu, omega)
266  {
267  }
268 
269  result_t operator()(
270  location_input_2d const &x,
271  location_input_2d const &y) const
272  {
273  using namespace std::complex_literals;
274  using namespace boost::math::double_constants;
275  using boost::math::cyl_hankel_2;
276 
277  // compute distance and its gradient
278  auto rvec = y.get_x() - x.get_x();
279  auto r = rvec.norm();
280  auto gradr = rvec.normalized();
281 
282  // material properties and Helmholtz numbers
283  auto nu = get_poisson_ratio();
284  auto a2 = (1.-2.*nu)/2./(1.-nu);
285  auto a = std::sqrt(a2);
286  auto mu = get_shear_modulus();
287  auto rho = get_mass_density();
288  auto cS = std::sqrt(mu/rho);
289 
290  auto om = get_frequency();
291  auto kSr = om / cS * r;
292  auto kPr = a * kSr;
293 
294  std::complex<double> psi = .25i * ((cyl_hankel_2(1, kSr)/kSr - a2 * cyl_hankel_2(1, kPr) / kPr) - cyl_hankel_2(0, kSr));
295 
296  std::complex<double> chi = .25i * (a2 *cyl_hankel_2(2, kPr) - cyl_hankel_2(2, kSr));
297 
298  // matrix valued result
299  return ( psi * result_t::Identity() + chi * (gradr * gradr.transpose()) ) / mu;
300  }
301 }; // end of class elastodynamics_2d_U_kernel
302 
303 } // end of namespace NiHu
304 
305 #endif // ELASTODYNAMICS_KERNEL_HPP_INCLUDED
NiHu::elastodynamics_data::elastodynamics_data
elastodynamics_data(double nu, double rho, double mu, double omega)
Construct a new elastodynamics data object.
Definition: elastodynamics_kernel.hpp:53
NiHu::asymptotic::log< 1 >
C
Definition: bbfmm_covariance.cpp:47
elastostatics_kernel.hpp
implementation of fundamental solutions of elastostatics
NiHu::elastostatics_2d_U_kernel
The displacement kernel of 2D elastostatics.
Definition: elastostatics_kernel.hpp:115
NiHu::singular_kernel_traits
singular traits class of a kernel
Definition: kernel.hpp:101
NiHu::elastodynamics_2d_U_kernel
Definition: elastodynamics_kernel.hpp:259
NiHu::location_normal_jacobian_input
a class representing a normal + Jacobian input
Definition: location_normal.hpp:79
NiHu::kernel_traits::is_singular
@ is_singular
indicates if the kernel is singular
Definition: kernel.hpp:91
NiHu::kernel_base
CRTP base class of all BEM kernels.
Definition: kernel.hpp:133
NiHu::kernel_traits
traits class of a kernel
Definition: kernel.hpp:71
NiHu::singular_kernel_traits::singular_quadrature_order
@ singular_quadrature_order
the quadrature order singular integrals are handled with
Definition: kernel.hpp:111
NiHu::kernel_traits::is_symmetric
@ is_symmetric
indicates if the kernel is symmetric
Definition: kernel.hpp:89
NiHu::elastodynamics_data
Class representing parameters of the elastodynamics kernel.
Definition: elastodynamics_kernel.hpp:42
NiHu::elastodynamics_3d_T_kernel
Definition: elastodynamics_kernel.hpp:165
NiHu::asymptotic::inverse< 1 >
NiHu::elastostatics_3d_U_kernel
the displacement kernel for 3d isotropic elastostatics
Definition: elastostatics_kernel.hpp:269
NiHu::location_input::get_x
const x_t & get_x(void) const
return the location
Definition: location_normal.hpp:65
location_normal.hpp
implementation of location and normal kernel inputs
NiHu::elastodynamics_3d_U_kernel
Definition: elastodynamics_kernel.hpp:91
NiHu::kernel_base< elastodynamics_3d_U_kernel >::result_t
traits_t::result_t result_t
compile time check if the two kernel inputs are compatible
Definition: kernel.hpp:147
NiHu::kernel_base< elastodynamics_3d_U_kernel >::is_symmetric
static const bool is_symmetric
true if K(x,y) = K(y,x)
Definition: kernel.hpp:162
NiHu::elastostatics_3d_T_kernel
the traction kernel for 3d isotropic elastostatics
Definition: elastostatics_kernel.hpp:329
NiHu::location_input
a class representing a simple location
Definition: location_normal.hpp:37
NiHu::location_normal_jacobian_input::get_unit_normal
const x_t & get_unit_normal(void) const
return the unit normal vector
Definition: location_normal.hpp:116
NiHu::gauss_family_tag
tag for the family of Gaussian quadratures
Definition: gaussian_quadrature.hpp:517