21 #ifndef NIHU_HELMHOLTZ_3D_SINGULAR_INTEGRALS_HPP_INCLUDED
22 #define NIHU_HELMHOLTZ_3D_SINGULAR_INTEGRALS_HPP_INCLUDED
24 #include <boost/math/constants/constants.hpp>
27 #include "field_type_helpers.hpp"
31 #include "normal_derivative_singular_integrals.hpp"
33 #include "../core/match_types.hpp"
34 #include "../core/singular_integral_shortcut.hpp"
35 #include "../util/math_functions.hpp"
37 #if NIHU_MEX_DEBUGGING
47 template <
unsigned order>
56 template <
class wavenumber_t>
57 static std::complex<double> dynamic_part(
double const &r, wavenumber_t
const &k)
59 using namespace std::complex_literals;
60 return -1.i*k * std::exp(-1.i*k*r / 2.0) * sinc(k*r / 2.0);
72 template <
class elem_t,
class wavenumber_t>
73 static std::complex<double>
eval(
76 wavenumber_t
const &k)
78 using namespace boost::math::double_constants;
82 enum { N = elem_t::domain_t::num_corners };
84 double r[N], theta[N], alpha[N];
89 for (
unsigned i = 0; i < N; ++i)
90 I_stat += r[i] * std::sin(alpha[i]) *
91 std::log(std::tan((alpha[i] + theta[i]) / 2.0) / std::tan(alpha[i] / 2.0)
95 std::complex<double> I_dyn = 0.0;
96 for (
auto it = quadr_t::quadrature.begin(); it != quadr_t::quadrature.end(); ++it)
98 double r = (elem.get_x(it->get_xi()) - x0).norm();
99 double jac = elem.get_normal(it->get_xi()).norm();
100 I_dyn += dynamic_part(r, k) * it->get_w() * jac;
104 return (I_stat + I_dyn) / (4.0 * pi);
109 template <
unsigned order>
113 template <
class wavenumber_t>
114 static std::complex<double> dynamic_part(
double const &r, wavenumber_t
const &k)
116 using namespace std::complex_literals;
117 std::complex<double>
const ikr(1.i*k*r);
118 if (std::abs(r) > 1e-3)
119 return (std::exp(-ikr)*(1.0 + ikr) - 1.0 + ikr*ikr / 2.0) / r / r / r;
121 return -1.i*k*k*k * (
122 1.0 / 3.0 - ikr*(1.0 / 8.0 - ikr*(1.0 / 30.0 - ikr*(1.0 / 144.0 - ikr*(1.0 / 840.0 - ikr / 5760.0))))
135 template <
class elem_t,
class wavenumber_t>
136 static std::complex<double>
eval(
139 wavenumber_t
const &k)
141 using namespace boost::math::double_constants;
144 enum { N = elem_t::domain_t::num_corners };
146 #if NIHU_MEX_DEBUGGING
147 static bool printed =
false;
150 mexPrintf(
"Integrating Helmholtz HSP over constant plane, N = %d\n", N);
155 double r[N], theta[N], alpha[N];
159 double IG0 = 0.0, IddG0 = 0.0;
160 for (
unsigned i = 0; i < N; ++i)
166 IG0 += r[i] * std::sin(alpha[i]) *
167 std::log(std::tan((alpha[i] + theta[i]) / 2.0) / tan(alpha[i] / 2.0));
168 IddG0 += (std::cos(alpha[i] + theta[i]) - std::cos(alpha[i])) / (r[i] * std::sin(alpha[i]));
172 std::complex<double> I_acc = 0.0;
173 for (
auto it = quadr_t::quadrature.begin(); it != quadr_t::quadrature.end(); ++it)
175 double r = (elem.get_x(it->get_xi()) - x0).norm();
176 double jac = elem.get_normal(it->get_xi()).norm();
177 I_acc += dynamic_part(r, k) * it->get_w() * jac;
181 return (IddG0 + k*k / 2.0 * IG0 + I_acc) / (4.0 * pi);
189 template <
class WaveNumber,
class TestField,
class TrialField>
192 typename std::enable_if<
193 is_collocational<TestField, TrialField>::value &&
194 is_constant_tria<TrialField>::value
206 template <
class result_t>
216 trial_field.
get_elem().get_center(),
217 kernel.derived().get_wave_number());
227 template <
class WaveNumber,
class TestField,
class TrialField>
230 typename std::enable_if<
231 is_collocational<TestField, TrialField>::value &&
232 is_constant_tria<TrialField>::value
244 template <
class result_t>
254 trial_field.
get_elem().get_center(),
255 kernel.derived().get_wave_number());
264 template <
class WaveNumber,
class TestField,
class TrialField>
267 typename std::enable_if<
268 is_collocational<TestField, TrialField>::value &&
269 !is_constant_tria<TrialField>::value
280 template <
class result_t>
288 #if NIHU_MEX_DEBUGGING
289 static bool printed =
false;
292 mexPrintf(
"Calling Guiggiani now\n");
297 auto const &elem = trial_field.
get_elem();
298 guiggiani_t gui(elem, kernel.derived());
299 for (
unsigned r = 0; r < TestField::num_dofs; ++r)
301 auto const &xi0 = TestField::nset_t::corner_at(r);
302 gui.integrate(result.row(r), xi0, elem.get_normal(xi0));
312 #endif // NIHU_HELMHOLTZ_3D_SINGULAR_INTEGRALS_HPP_INCLUDED