NiHu  2.0
helmholtz_3d_hf_fmm.hpp
Go to the documentation of this file.
1 
7 #ifndef NIHU_HELMHOLTZ_3D_HF_FMM_HPP_INCLUDED
8 #define NIHU_HELMHOLTZ_3D_HF_FMM_HPP_INCLUDED
9 
10 #include "cluster.hpp"
11 #include "cluster_tree.hpp"
12 #include "fmm_operator.hpp"
15 #include "m2l_indices.hpp"
17 #include "p2p.hpp"
18 #include "unit_sphere.h"
19 
20 #include "library/helmholtz_3d.hpp"
21 
22 #include <boost/math/constants/constants.hpp>
23 #include <boost/math/special_functions/hankel.hpp>
24 #include <boost/math/special_functions/legendre.hpp>
25 
26 #define L2L_SHIFT_FIRST 1
27 
28 #include <Eigen/Dense>
29 #include <complex>
30 
31 namespace NiHu
32 {
33 namespace fmm
34 {
35 
36 class up_shift
37 {
38  using cvector_t = Eigen::Matrix<std::complex<double>, Eigen::Dynamic, 1>;
39 
40 public:
41  up_shift()
42  : m_level_data(nullptr)
43  {
44  }
45 
46  up_shift(cvector_t const &shift, helmholtz_3d_hf_level_data const &ld)
47  : m_shift(shift)
48  , m_level_data(&ld)
49  {
50  }
51 
54  cvector_t operator*(cvector_t const &rhs) const
55  {
56  return m_shift.array() * m_level_data->interp_up(rhs).array();
57  }
58 
59 private:
60  cvector_t m_shift;
61  helmholtz_3d_hf_level_data const *m_level_data;
62 };
63 
64 
66 {
67  using cvector_t = Eigen::Matrix<std::complex<double>, Eigen::Dynamic, 1>;
68 
69 public:
70  down_shift()
71  : m_level_data(nullptr)
72  {
73  }
74 
75  down_shift(cvector_t const &shift, helmholtz_3d_hf_level_data const &ld)
76  : m_shift(shift)
77  , m_level_data(&ld)
78  {
79  }
80 
83  cvector_t operator*(cvector_t const &rhs) const
84  {
85 #if L2L_SHIFT_FIRST
86  return m_level_data->interp_down(m_shift.array() * rhs.array());
87 #else
88  return m_shift.array() * m_level_data->interp_down(rhs).array();
89 #endif
90  }
91 
92 private:
93  cvector_t m_shift;
94  helmholtz_3d_hf_level_data const *m_level_data;
95 };
96 
97 
100 template <class WaveNumber>
102 {
103 public:
105  using wave_number_t = WaveNumber;
107  using cvector_t = Eigen::Matrix<std::complex<double>, Eigen::Dynamic, 1>;
113  using location_t = typename bounding_box_t::location_t;
116 
118 
122  : m_wave_number(k)
123  , m_accuracy(3.0)
124  {
125  }
126 
130  static size_t compute_expansion_length(double drel, double C)
131  {
132  using namespace boost::math::double_constants;
133  auto kd = two_pi * drel;
134  return size_t(std::ceil(kd + C * std::log(kd + pi)));
135  }
136 
140  void set_accuracy(double accuracy)
141  {
142  m_accuracy = accuracy;
143  }
144 
147  void init_level_data(cluster_tree_t const &tree)
148  {
149  using namespace boost::math::double_constants;
150  double lambda = two_pi / std::real(m_wave_number);
151  m_level_data_vector.clear();
152  m_level_data_vector.resize(tree.get_n_levels());
153 
154  // set the expansion length for each level
155  for (size_t i = 0; i < tree.get_n_levels(); ++i)
156  {
157  auto &ld = m_level_data_vector[i];
158  // get the diameter from the first cluster on the level
159  auto idx = tree.level_begin(i);
160  auto d = tree[idx].get_bounding_box().get_diameter();
161  auto L = compute_expansion_length(d / lambda, m_accuracy);
162  ld.set_expansion_length(L);
163  }
164 
165  // compute interpolation matrices
166  for (size_t i = 0; i < tree.get_n_levels(); ++i)
167  {
168  auto &ld = m_level_data_vector[i];
169  auto const &Sto = ld.get_unit_sphere();
170  if (i >= 3)
171  ld.set_interp_dn(interpolator(m_level_data_vector[i - 1].get_unit_sphere(), Sto));
172  if (i < tree.get_n_levels() - 1 && i >= 2)
173  ld.set_interp_up(interpolator(m_level_data_vector[i + 1].get_unit_sphere(), Sto));
174  }
175  } // end of function init_level_data
176 
181  {
182  return m_level_data_vector[idx];
183  }
184 
189  {
190  return m_level_data_vector[idx];
191  }
192 
194  class m2m
195  : public operator_with_wave_number<wave_number_t>
196  , public fmm_operator<m2m_tag>
197  {
198  public:
200  using result_t = up_shift;
202 
203  m2m(wave_number_t const &wave_number)
204  : wn_base_t(wave_number)
205  {
206  }
207 
208  static size_t unique_idx(cluster_t const &to, cluster_t const &from)
209  {
210  return bounding_box_t::dist2idx(
211  from.get_bounding_box().get_center(),
213  }
214 
215  result_t operator()(cluster_t const &to, cluster_t const &from) const
216  {
217  using namespace std::complex_literals;
218  auto const &Sto = to.get_level_data().get_unit_sphere();
220  - from.get_bounding_box().get_center();
221  auto const &k = this->get_wave_number();
222  cvector_t shift = exp((-1.i * k * Sto.get_s().transpose() * D).array());
223  return result_t(shift, to.get_level_data());
224  }
225  };
226 
227 
229  class l2l
230  : public operator_with_wave_number<wave_number_t>
231  , public fmm_operator<l2l_tag>
232  {
233  public:
235  using result_t = down_shift;
237 
238  l2l(wave_number_t const &wave_number)
239  : wn_base_t(wave_number)
240  {
241  }
242 
243  static size_t unique_idx(cluster_t const &to, cluster_t const &from)
244  {
245  return bounding_box_t::dist2idx(
247  from.get_bounding_box().get_center());
248  }
249 
250  result_t operator()(cluster_t const &to, cluster_t const &from) const
251  {
252  using namespace std::complex_literals;
253 #if L2L_SHIFT_FIRST
254  auto const &Sfrom = from.get_level_data().get_unit_sphere();
255 #else
256  auto const &Sto = to.get_level_data().get_unit_sphere();
257 #endif
259  - from.get_bounding_box().get_center();
260  auto const &k = this->get_wave_number();
261 #if L2L_SHIFT_FIRST
262  cvector_t shift = exp((-1.i * k * Sfrom.get_s().transpose() * D).array());
263 #else
264  cvector_t shift = exp((-1.i * k * Sto.get_s().transpose() * D).array());
265 #endif
266  return result_t(shift, to.get_level_data());
267  }
268  };
269 
270 
273  template <int Ny>
274  class p2m
275  : public operator_with_wave_number<wave_number_t>
276  , public fmm_operator<p2m_tag>
277  {
278  public:
280 
281  using test_input_t = cluster_t;
282  using trial_input_t = typename NiHu::normal_derivative_kernel<
284  >::trial_input_t;
285  using result_t = cvector_t;
286 
287  p2m(wave_number_t const &wave_number)
288  : wn_base_t(wave_number)
289  {
290  }
291 
292  size_t rows(test_input_t const &to) const
293  {
294  return to.get_level_data().get_unit_sphere().get_s().cols();
295  }
296 
297  result_t operator()(test_input_t const &to, trial_input_t const &tri) const
298  {
299  return eval(to, tri, std::integral_constant<int, Ny>());
300  }
301 
302  private:
304  result_t eval(test_input_t const &to, trial_input_t const &tri,
305  std::integral_constant<int, 0>) const
306  {
307  using namespace std::complex_literals;
308  auto const &Y = to.get_bounding_box().get_center();
309  auto const &y = tri.get_x();
310  auto const &s = to.get_level_data().get_unit_sphere().get_s();
311  auto const &k = this->get_wave_number();
312  location_t d = Y - y;
313  return Eigen::exp(-1.i * k * (s.transpose() * d).array());
314  }
315 
317  result_t eval(test_input_t const &to, trial_input_t const &tri,
318  std::integral_constant<int, 1>) const
319  {
320  using namespace std::complex_literals;
321  auto const &Y = to.get_bounding_box().get_center();
322  auto const &y = tri.get_x();
323  auto const &s = to.get_level_data().get_unit_sphere().get_s();
324  auto const &k = this->get_wave_number();
325  location_t d = Y - y;
326  return Eigen::exp(-1.i * k * (s.transpose() * d).array())
327  * ((1.i * k) * (s.transpose() * tri.get_unit_normal()).array());
328  }
329  };
330 
333  template <int Ny>
334  class p2l
335  : public operator_with_wave_number<wave_number_t>
336  , public fmm_operator<p2l_tag>
337  {
338  public:
340 
341  using test_input_t = cluster_t;
342  using trial_input_t = typename NiHu::normal_derivative_kernel<
344  >::trial_input_t;
345  using result_t = cvector_t;
346 
347  p2l(wave_number_t const &wave_number)
348  : wn_base_t(wave_number)
349  {
350  }
351 
352  size_t rows(test_input_t const &to) const
353  {
354  return to.get_level_data().get_unit_sphere().get_s().cols();
355  }
356 
357  result_t operator()(test_input_t const &to, trial_input_t const &tri) const
358  {
359  return eval(to, tri, std::integral_constant<int, Ny>());
360  }
361 
362  private:
363  result_t eval(test_input_t const &to, trial_input_t const &tri,
364  std::integral_constant<int, 0>) const
365  {
366  throw std::logic_error("Unimplemented p2l operator");
367  }
368 
369  result_t eval(test_input_t const &to, trial_input_t const &tri,
370  std::integral_constant<int, 1>) const
371  {
372  throw std::logic_error("Unimplemented p2l operator");
373  }
374  };
375 
376 
379  template <int Nx>
380  class l2p
381  : public operator_with_wave_number<wave_number_t>
382  , public fmm_operator<l2p_tag>
383  {
384  public:
386 
387  using trial_input_t = cluster_t;
388  using test_input_t = typename NiHu::normal_derivative_kernel<
390  >::test_input_t;
391  using result_t = Eigen::Matrix<std::complex<double>, 1, Eigen::Dynamic>;
392 
393  l2p(wave_number_t const &wave_number)
394  : wn_base_t(wave_number)
395  {
396  }
397 
398  size_t cols(trial_input_t const &from) const
399  {
400  return from.get_level_data().get_unit_sphere().get_s().cols();
401  }
402 
403  result_t operator()(test_input_t const &tsi, trial_input_t const &from) const
404  {
405  return eval(tsi, from, std::integral_constant<int, Nx>());
406  }
407 
408  private:
409  result_t eval(test_input_t const &tsi, trial_input_t const &from,
410  std::integral_constant<int, 0>) const
411  {
412  using namespace std::complex_literals;
413  auto const &X = from.get_bounding_box().get_center();
414  auto const &x = tsi.get_x();
415  auto const &S = from.get_level_data().get_unit_sphere();
416  auto const &s = S.get_s();
417  auto const &w = S.get_w();
418  auto const &k = this->get_wave_number();
419  location_t d = x - X;
420  return Eigen::exp(-1.i * k * (s.transpose() * d).array()) * w.array();
421  }
422 
423  result_t eval(test_input_t const &tsi, trial_input_t const &from,
424  std::integral_constant<int, 1>) const
425  {
426  using namespace std::complex_literals;
427  auto const &X = from.get_bounding_box().get_center();
428  auto const &x = tsi.get_x();
429  auto const &S = from.get_level_data().get_unit_sphere();
430  auto const &s = S.get_s();
431  auto const &w = S.get_w();
432  auto const &k = this->get_wave_number();
433  location_t d = x - X;
434  return Eigen::exp(-1.i * k * (s.transpose() * d).array())
435  * (-1.i * k) * (s.transpose() * tsi.get_unit_normal()).array()
436  * w.array();
437  }
438  };
439 
440 
443  template <int Nx>
444  class m2p
445  : public operator_with_wave_number<wave_number_t>
446  , public fmm_operator<m2p_tag>
447  {
448  public:
450 
451  using trial_input_t = cluster_t;
452  using test_input_t = typename NiHu::normal_derivative_kernel<
454  >::test_input_t;
455  using result_t = Eigen::Matrix<std::complex<double>, 1, Eigen::Dynamic>;
456 
457  m2p(wave_number_t const &wave_number)
458  : wn_base_t(wave_number)
459  {
460  }
461 
462  size_t cols(trial_input_t const &from) const
463  {
464  return from.get_level_data().get_unit_sphere().get_s().cols();
465  }
466 
467  result_t operator()(test_input_t const &tsi, trial_input_t const &from) const
468  {
469  return eval(tsi, from, std::integral_constant<int, Nx>());
470  }
471 
472  private:
473  result_t eval(test_input_t const &tsi, trial_input_t const &from,
474  std::integral_constant<int, 0>) const
475  {
476  throw std::logic_error("Unimplemented m2p operator");
477  }
478 
479  result_t eval(test_input_t const &tsi, trial_input_t const &from,
480  std::integral_constant<int, 1>) const
481  {
482  throw std::logic_error("Unimplemented m2p operator");
483  }
484  };
485 
487  class m2l
488  : public operator_with_wave_number<wave_number_t>
489  , public fmm_operator<m2l_tag>
490  {
491  public:
493  using result_t = Eigen::DiagonalMatrix<std::complex<double>, Eigen::Dynamic>;
495 
496  m2l(wave_number_t const &wave_number)
497  : wn_base_t(wave_number)
498  {
499  }
500 
501  static size_t unique_idx(cluster_t const &to, cluster_t const &from)
502  {
504  }
505 
506  result_t operator()(cluster_t const &to, cluster_t const &from) const
507  {
508  auto const &k = this->get_wave_number();
509 
510  auto const &X = to.get_bounding_box().get_center();
511  auto const &Y = from.get_bounding_box().get_center();
512  location_t Dvec = X - Y;
513 
514  auto L = to.get_level_data().get_expansion_length();
515  auto const &s = to.get_level_data().get_unit_sphere().get_s();
516 
517  return m2l_matrix_impl(Dvec, s, k, L).asDiagonal();
518  }
519 
520  private:
521  static cvector_t m2l_matrix_impl(location_t const &Dvec,
522  Eigen::Matrix<double, 3, Eigen::Dynamic> const &s,
523  wave_number_t const &k,
524  size_t L)
525  {
526  using namespace boost::math::double_constants;
527  using namespace std::complex_literals;
528 
529  double D = Dvec.norm();
530  location_t Uvec = Dvec / D;
531  auto N = s.cols();
532 
533  Eigen::Matrix<double, 1, Eigen::Dynamic> x = Uvec.transpose() * s;
534  auto z = -k * D;
535 
536  cvector_t M2L = cvector_t::Zero(N, 1);
537 
538  for (size_t l = 0; l <= L; ++l)
539  {
540  auto h = boost::math::sph_hankel_1(l, z);
541  auto c = double(2 * l + 1) * std::pow(1.i, l) * h;
542  for (int i = 0; i < s.cols(); ++i)
543  M2L(i) += c * boost::math::legendre_p(int(l), x(0, i));
544  }
545  M2L *= -1.i * k / (4.0 * pi) / (4.0 * pi);
546 
547  return M2L;
548  }
549  };
550 
553  template <int Ny>
554  using p2m_type = p2m<Ny>;
555 
558  template <int Ny>
559  using p2l_type = p2l<Ny>;
560 
563  template <int Nx>
564  using m2p_type = m2p<Nx>;
565 
568  template <int Nx>
569  using l2p_type = l2p<Nx>;
570 
574  template <int Nx, int Ny>
575  using p2p_type = fmm::p2p<
578  >
579  >;
580 
584  template <int Ny>
586  {
587  return p2m<Ny>(m_wave_number);
588  }
589 
593  template <int Ny>
595  {
596  return p2l<Ny>(m_wave_number);
597  }
598 
602  template <int Nx>
604  {
605  return l2p<Nx>(m_wave_number);
606  }
607 
611  template <int Nx>
613  {
614  return m2p<Nx>(m_wave_number);
615  }
616 
621  template <int Nx, int Ny>
623  {
626  > kernel_t;
627  return p2p_type<Nx, Ny>(kernel_t(m_wave_number));
628  }
629 
632  m2m create_m2m() const
633  {
634  return m2m(m_wave_number);
635  }
636 
639  l2l create_l2l() const
640  {
641  return l2l(m_wave_number);
642  }
643 
646  m2l create_m2l() const
647  {
648  return m2l(m_wave_number);
649  }
650 
651 private:
652  wave_number_t m_wave_number;
653  std::vector<helmholtz_3d_hf_level_data> m_level_data_vector;
654  double m_accuracy; // C
655 };
656 
657 
658 } // end of namespace fmm
659 } // namespace NiHu
660 
661 #endif /* NIHU_HELMHOLTZ_3D_HF_FMM_HPP_INCLUDED */
NiHu::fmm::up_shift
Definition: helmholtz_3d_hf_fmm.hpp:36
NiHu::helmholtz_kernel
Definition: helmholtz_kernel.hpp:44
NiHu::fmm::helmholtz_3d_hf_fmm::m2p
M2P operator of the FMM for the Helmholtz equation in 3D.
Definition: helmholtz_3d_hf_fmm.hpp:444
fmm_operator.hpp
FMM operator types and tags.
unit_sphere.h
Interface of class NiHu::fmm::unit_sphere.
NiHu::fmm::helmholtz_3d_hf_fmm::wave_number_t
WaveNumber wave_number_t
template argument as nested type
Definition: helmholtz_3d_hf_fmm.hpp:105
NiHu::fmm::cluster_base::get_bounding_box
const bounding_box_t & get_bounding_box() const
return cluster's bounding box
Definition: cluster.hpp:111
NiHu::fmm::helmholtz_3d_hf_fmm::create_p2m
p2m_type< Ny > create_p2m() const
factory function for the P2M operator
Definition: helmholtz_3d_hf_fmm.hpp:585
NiHu::fmm::helmholtz_3d_hf_fmm::p2l
P2L operator of the FMM for the Helmholtz equation in 3D.
Definition: helmholtz_3d_hf_fmm.hpp:334
NiHu::fmm::helmholtz_3d_hf_fmm::get_level_data
const helmholtz_3d_hf_level_data & get_level_data(size_t idx) const
return level data for a specific level
Definition: helmholtz_3d_hf_fmm.hpp:180
NiHu::fmm::helmholtz_3d_hf_fmm::create_m2l
m2l create_m2l() const
factory function for the M2L operator
Definition: helmholtz_3d_hf_fmm.hpp:646
operator_with_wave_number.hpp
Implementation of class template NiHu::fmm::operator_with_wave_number.
NiHu::fmm::helmholtz_3d_hf_fmm::m2m
M2M operator of the FMM for the Helmholtz equation in 3D.
Definition: helmholtz_3d_hf_fmm.hpp:194
NiHu::fmm::helmholtz_3d_hf_fmm::get_level_data
helmholtz_3d_hf_level_data & get_level_data(size_t idx)
return level data reference for a specific level
Definition: helmholtz_3d_hf_fmm.hpp:188
NiHu::fmm::helmholtz_3d_hf_fmm::cluster_t
helmholtz_3d_hf_cluster cluster_t
the fmm's cluster type
Definition: helmholtz_3d_hf_fmm.hpp:109
NiHu::fmm::helmholtz_3d_hf_fmm::set_accuracy
void set_accuracy(double accuracy)
set the method's accuracy parameter
Definition: helmholtz_3d_hf_fmm.hpp:140
NiHu::fmm::helmholtz_3d_hf_fmm::compute_expansion_length
static size_t compute_expansion_length(double drel, double C)
compute expansion length based on relative cluster size
Definition: helmholtz_3d_hf_fmm.hpp:130
C
Definition: bbfmm_covariance.cpp:47
NiHu::fmm::helmholtz_3d_hf_fmm::location_t
typename bounding_box_t::location_t location_t
the physical location type
Definition: helmholtz_3d_hf_fmm.hpp:113
NiHu::fmm::helmholtz_3d_hf_fmm::bounding_box_t
typename cluster_t::bounding_box_t bounding_box_t
the bounding box type
Definition: helmholtz_3d_hf_fmm.hpp:111
NiHu::fmm::helmholtz_3d_hf_fmm::create_m2m
m2m create_m2m() const
factory function for the M2M operator
Definition: helmholtz_3d_hf_fmm.hpp:632
NiHu::fmm::helmholtz_3d_hf_fmm
the fmm for the 3D Helmholtz equation
Definition: helmholtz_3d_hf_fmm.hpp:101
NiHu::fmm::helmholtz_3d_hf_cluster::get_level_data
const helmholtz_3d_hf_level_data & get_level_data() const
return the cluster's level data
Definition: helmholtz_3d_hf_cluster.cpp:32
NiHu::fmm::helmholtz_3d_hf_cluster
cluster type of the Helmholtz 3D High frequency FMM
Definition: helmholtz_3d_hf_cluster.h:32
NiHu::fmm::down_shift::operator*
cvector_t operator*(cvector_t const &rhs) const
multiply the updownshift matrix with a multipole / local
Definition: helmholtz_3d_hf_fmm.hpp:83
NiHu::fmm::cluster_base< helmholtz_3d_hf_cluster >::bounding_box_t
bounding_box< dimension, double > bounding_box_t
Bounding box type.
Definition: cluster.hpp:50
NiHu::exponential_covariance_kernel
Definition: covariance_kernel.hpp:42
NiHu::fmm::helmholtz_3d_hf_fmm::create_p2l
p2l_type< Ny > create_p2l() const
factory function for the P2L operator
Definition: helmholtz_3d_hf_fmm.hpp:594
NiHu::fmm::helmholtz_3d_hf_level_data::interp_up
const cvector_t & interp_up(cvector_t const &x) const
interpolate a function on the unit sphere up to this level
Definition: helmholtz_3d_hf_level_data.cpp:38
NiHu::fmm::cluster_tree< cluster_t >
p2p.hpp
P2P operator.
NiHu::fmm::helmholtz_3d_hf_fmm::init_level_data
void init_level_data(cluster_tree_t const &tree)
initialize the level data of the fmm method
Definition: helmholtz_3d_hf_fmm.hpp:147
m2l_indices.hpp
Implementation of class template Nihu::fmm::m2l_indices.
NiHu::fmm::down_shift
Definition: helmholtz_3d_hf_fmm.hpp:65
NiHu::fmm::helmholtz_3d_hf_fmm::helmholtz_3d_hf_fmm
helmholtz_3d_hf_fmm(wave_number_t const &k)
constructor
Definition: helmholtz_3d_hf_fmm.hpp:121
NiHu::fmm::interpolator
class interpolating over the unit sphere
Definition: unit_sphere_interpolator.h:25
cluster_tree.hpp
Implementation of class NiHu::fmm::cluster_tree.
NiHu::fmm::cluster_tree::get_n_levels
size_t get_n_levels() const
return number of levels
Definition: cluster_tree.hpp:253
NiHu::fmm::helmholtz_3d_hf_fmm::cvector_t
Eigen::Matrix< std::complex< double >, Eigen::Dynamic, 1 > cvector_t
complex dynamic vector
Definition: helmholtz_3d_hf_fmm.hpp:107
NiHu::fmm::helmholtz_3d_hf_level_data
level data of the helmholtz 3d hf fmm
Definition: helmholtz_3d_hf_level_data.h:23
NiHu::fmm::fmm_operator
Operator defining its tag type.
Definition: fmm_operator.hpp:85
NiHu::fmm::cluster_tree::level_begin
size_t level_begin(size_t idx) const
Begin iterator to idx-th level clusters.
Definition: cluster_tree.hpp:264
NiHu::fmm::helmholtz_3d_hf_fmm::create_l2p
l2p_type< Nx > create_l2p() const
factory function for the L2P operator
Definition: helmholtz_3d_hf_fmm.hpp:603
NiHu::fmm::helmholtz_3d_hf_fmm::create_m2p
m2p_type< Nx > create_m2p() const
factory function for the M2P operator
Definition: helmholtz_3d_hf_fmm.hpp:612
NiHu::fmm::unit_sphere::get_s
const Eigen::Matrix< double, 3, Eigen::Dynamic > & get_s(void) const
return Cartesian quadrature points
Definition: unit_sphere.h:86
NiHu::fmm::helmholtz_3d_hf_fmm::p2m
P2M operator of the FMM for the Helmholtz equation in 3D.
Definition: helmholtz_3d_hf_fmm.hpp:274
NiHu::fmm::bounding_box::get_center
const location_t & get_center(void) const
return center
Definition: bounding_box.hpp:75
NiHu::fmm::helmholtz_3d_hf_level_data::get_expansion_length
size_t get_expansion_length() const
return the expansion length
Definition: helmholtz_3d_hf_level_data.cpp:26
NiHu::normal_derivative_kernel
Normal derivative of a distance dependent kernel.
Definition: normal_derivative_kernel.hpp:26
NiHu::fmm::up_shift::operator*
cvector_t operator*(cvector_t const &rhs) const
multiply the updownshift matrix with a multipole / local
Definition: helmholtz_3d_hf_fmm.hpp:54
helmholtz_3d_hf_level_data.h
level data of the the helmholtz 3d high frequency fmm
cluster.hpp
implementation of class NiHu::fmm::cluster_base
NiHu::fmm::helmholtz_3d_hf_level_data::interp_down
const cvector_t & interp_down(cvector_t const &x) const
interpolate a function on the unit sphere down to this level
Definition: helmholtz_3d_hf_level_data.cpp:45
NiHu::fmm::operator_with_wave_number
class storing a wave number
Definition: operator_with_wave_number.hpp:17
NiHu::fmm::helmholtz_3d_hf_level_data::get_unit_sphere
const unit_sphere & get_unit_sphere() const
return the stored unit sphere
Definition: helmholtz_3d_hf_level_data.cpp:21
NiHu::fmm::helmholtz_3d_hf_fmm::m2l
M2L operator of the FMM for the Helmholtz equation in 3D.
Definition: helmholtz_3d_hf_fmm.hpp:487
NiHu::fmm::helmholtz_3d_hf_fmm::create_l2l
l2l create_l2l() const
factory function for the L2L operator
Definition: helmholtz_3d_hf_fmm.hpp:639
NiHu::fmm::m2l_indices
Class assigning indices to M2L distances.
Definition: m2l_indices.hpp:21
NiHu::fmm::helmholtz_3d_hf_fmm::create_p2p
p2p_type< Nx, Ny > create_p2p() const
factory function for the P2P operator
Definition: helmholtz_3d_hf_fmm.hpp:622
helmholtz_3d_hf_cluster.h
Interface of class fmm::helmholtz_3d_hf_cluster.
NiHu::fmm::p2p
Definition: p2p.hpp:20
NiHu::bessel::Y
std::complex< double > Y(std::complex< double > const &z)
Bessel function Y_nu(z)
Definition: math_functions.hpp:315
NiHu::fmm::helmholtz_3d_hf_fmm::l2p
L2P operator of the FMM for the Helmholtz equation in 3D.
Definition: helmholtz_3d_hf_fmm.hpp:380
NiHu::fmm::helmholtz_3d_hf_fmm::l2l
L2L operator of the FMM for the Helmholtz equation in 3D.
Definition: helmholtz_3d_hf_fmm.hpp:229