NiHu  2.0
helmholtz_2d_wb_fmm.hpp
Go to the documentation of this file.
1 
7 #ifndef NIHU_HELMHOLTZ_2D_WB_FMM_HPP_INCLUDED
8 #define NIHU_HELMHOLTZ_2D_WB_FMM_HPP_INCLUDED
9 
10 #include "cluster.hpp"
11 #include "cluster_tree.hpp"
12 #include "fmm_operator.hpp"
16 #include "m2l_indices.hpp"
18 #include "p2p.hpp"
19 
20 #include "library/helmholtz_2d.hpp"
21 
22 #include <boost/math/special_functions/hankel.hpp>
23 #include <boost/math/special_functions/bessel.hpp>
24 #include <boost/math/special_functions/bessel_prime.hpp>
25 #include <boost/math/constants/constants.hpp>
26 
27 #include <Eigen/Dense>
28 
29 #include <algorithm>
30 #include <complex>
31 #include <iostream>
32 
33 namespace NiHu
34 {
35 namespace fmm
36 {
37 
41 template <class WaveNumber>
43 {
44 public:
46  typedef WaveNumber wave_number_t;
52  typedef Eigen::Matrix<std::complex<double>, Eigen::Dynamic, 1> cvector_t;
54  static size_t const dimension = cluster_t::dimension;
59 
60 private:
62 
63 private:
68  static void cart2pol(location_t const& d, double& r, double& theta)
69  {
70  r = d.norm();
71  theta = std::atan2(d(1), d(0));
72  }
73 
74 public:
76  class m2m
77  : public operator_with_wave_number<wave_number_t>
78  , public fmm_operator<m2m_tag>
79  {
80  private:
82 
83  public:
88 
91  m2m(wave_number_t const& wave_number)
92  : base_t(wave_number)
93  {
94  }
95 
100  static size_t unique_idx(cluster_t const& to, cluster_t const& from)
101  {
103  from.get_bounding_box().get_center(),
105  }
106 
107  public:
108 
113  result_t operator()(cluster_t const& to, cluster_t const& from) const
114  {
115  using boost::math::cyl_bessel_j;
116  using namespace std::complex_literals;
117 
118  location_t const& X = to.get_bounding_box().get_center();
119  location_t const& Y = from.get_bounding_box().get_center();
120  double r, theta;
121  cart2pol(X - Y, r, theta);
122  auto z = this->get_wave_number() * r;
123  int Lto = int(to.get_level_data().get_expansion_length());
124  int Lfrom = int(from.get_level_data().get_expansion_length());
125  int L = std::max(Lto, Lfrom);
126  cvector_t diag_coeffs(2 * L + 1, 1);
127  for (int nu = -L; nu <= L; ++nu)
128  diag_coeffs(-nu + L) = std::exp(-1.0i * (nu * theta))
129  * cyl_bessel_j(nu, z);
130 
131  return result_t(to.get_level_data(), from.get_level_data(),
132  diag_coeffs);
133  }
134  };
135 
136 
138  class l2l
139  : public operator_with_wave_number<wave_number_t>
140  , public fmm_operator<l2l_tag>
141  {
142  private:
144 
145  public:
150 
153  l2l(wave_number_t const& wave_number)
154  : base_t(wave_number)
155  {
156  }
157 
162  static size_t unique_idx(cluster_t const& to, cluster_t const& from)
163  {
166  from.get_bounding_box().get_center());
167  }
168 
173  result_t operator()(cluster_t const& to, cluster_t const& from) const
174  {
175  using boost::math::cyl_bessel_j;
176  using namespace boost::math::double_constants;
177  using namespace std::complex_literals;
178 
179  location_t const& X = to.get_bounding_box().get_center();
180  location_t const& Y = from.get_bounding_box().get_center();
181  double r, theta;
182  cart2pol(X - Y, r, theta);
183  auto z = this->get_wave_number() * r;
184  int Lto = int(to.get_level_data().get_expansion_length());
185  int Lfrom = int(from.get_level_data().get_expansion_length());
186  int L = std::max(Lto, Lfrom);
187  cvector_t diag_coeffs(2 * L + 1, 1);
188  for (int nu = -L; nu <= L; ++nu)
189  diag_coeffs(nu + L) = std::exp(1.0i * (nu * (pi + theta)))
190  * cyl_bessel_j(nu, z);
191  return result_t(to.get_level_data(), from.get_level_data(),
192  diag_coeffs);
193  }
194  };
195 
196 
198  class m2l
199  : public operator_with_wave_number<wave_number_t>
200  , public fmm_operator<m2l_tag>
201  {
202  private:
204 
205  public:
210 
213  m2l(wave_number_t const& wave_number)
214  : base_t(wave_number)
215  {
216  }
217 
222  static size_t unique_idx(cluster_t const& to, cluster_t const& from)
223  {
225  }
226 
231  result_t operator()(cluster_t const& to, cluster_t const& from) const
232  {
233  using boost::math::cyl_hankel_2;
234  using namespace boost::math::double_constants;
235  using namespace std::complex_literals;
236 
237  size_t L = to.get_level_data().get_expansion_length();
238  location_t const& X = to.get_bounding_box().get_center();
239  location_t const& Y = from.get_bounding_box().get_center();
240  double r, theta;
241  cart2pol(X - Y, r, theta);
242  auto z = this->get_wave_number() * r;
243  cvector_t diag_coeffs(2 * L + 1);
244  for (int nu = -int(L); nu <= int(L); ++nu)
245  diag_coeffs(nu + L) = std::exp(1.0i * (nu * (pi + theta)))
246  * cyl_hankel_2(nu, z);
247  return result_t(to.get_level_data(), diag_coeffs);
248  }
249  };
250 
251 
255  template <unsigned int Ny>
256  class p2m
257  : public operator_with_wave_number<wave_number_t>
258  , public fmm_operator<p2m_tag>
259  {
260  public:
265  typedef typename NiHu::normal_derivative_kernel<
270 
273  p2m(wave_number_t const& wave_number)
274  : base_t(wave_number)
275  {
276  }
277 
281  size_t rows(test_input_t const& to) const
282  {
283  return to.get_level_data().get_data_size();
284  }
285 
290  result_t operator()(test_input_t const& to, trial_input_t const& y) const
291  {
292  result_t res = eval(to, y, std::integral_constant<int, Ny>());
293  if (to.get_level_data().is_high_freq())
294  return to.get_level_data().dft(res);
295  return res;
296  }
297 
298  private:
299  result_t eval(test_input_t const& to, trial_input_t const& tri,
300  std::integral_constant<int, 0>) const
301  {
302  using boost::math::cyl_bessel_j;
303  using namespace std::complex_literals;
304  using namespace std::complex_literals;
305 
306  int L = int(to.get_level_data().get_expansion_length());
307  location_t const& Y = to.get_bounding_box().get_center();
308  location_t const& y = tri.get_x();
309  double r, theta;
310  cart2pol(Y - y, r, theta);
311  result_t res(2 * L + 1, 1);
312  auto z = this->get_wave_number() * r;
313  for (int nu = -L; nu <= L; ++nu)
314  res(-nu + L, 0) = std::exp(-1.0i * (nu * theta)) *
315  cyl_bessel_j(nu, z);
316  return res * -.25i;
317  }
318 
319  result_t eval(test_input_t const& to, trial_input_t const& tri,
320  std::integral_constant<int, 1>) const
321  {
322  using boost::math::cyl_bessel_j;
323  using boost::math::cyl_bessel_j_prime;
324  using namespace std::complex_literals;
325 
326  int L = int(to.get_level_data().get_expansion_length());
327  location_t const& Y = to.get_bounding_box().get_center();
328  location_t const& y = tri.get_x();
329  location_t d = Y - y;
330  double r, theta;
331  cart2pol(d, r, theta);
332  double rdny = -d.dot(tri.get_unit_normal()) / r;
333  location_t Td(d(1), -d(0));
334  double thetadny = Td.dot(tri.get_unit_normal()) / (r * r);
335  result_t res(2 * L + 1, 1);
336  auto const& k = this->get_wave_number();
337  auto z = k * r;
338  for (int nu = -L; nu <= L; ++nu)
339  res(-nu + L, 0) = std::exp(-1.0i * (nu * theta)) *
340  (
341  cyl_bessel_j_prime(nu, z) * k * rdny
342  - 1.0i * (nu * thetadny) * cyl_bessel_j(nu, z)
343  );
344  return res * -.25i;
345  }
346  };
347 
351  template <unsigned int Ny>
352  class p2l
353  : public operator_with_wave_number<wave_number_t>
354  , public fmm_operator<p2l_tag>
355  {
356  private:
358 
359  public:
361  typedef typename NiHu::normal_derivative_kernel<
363  >::trial_input_t trial_input_t;
364  typedef cvector_t result_t;
365 
368  p2l(wave_number_t const& wave_number)
369  : base_t(wave_number)
370  {
371  }
372 
376  size_t rows(test_input_t const& to) const
377  {
378  return to.get_level_data().get_data_size();
379  }
380 
385  result_t operator()(test_input_t const& to, trial_input_t const& y) const
386  {
387  result_t res = eval(to, y, std::integral_constant<int, Ny>());
388  if (to.get_level_data().is_high_freq())
389  return to.get_level_data().dft(res);
390  return res;
391  }
392 
393  private:
394  result_t eval(test_input_t const& to, trial_input_t const& tri,
395  std::integral_constant<int, 0>) const
396  {
397  using boost::math::cyl_hankel_2;
398  using namespace boost::math::double_constants;
399  using namespace std::complex_literals;
400 
401  int L = int(to.get_level_data().get_expansion_length());
402  location_t const& X = to.get_bounding_box().get_center();
403  location_t const& y = tri.get_x();
404  double r, theta;
405  cart2pol(X - y, r, theta);
406  result_t res(2 * L + 1, 1);
407  auto z = this->get_wave_number() * r;
408  for (int nu = -L; nu <= L; ++nu)
409  res(nu + L, 0) = std::exp(1.0i * (nu * (pi + theta))) *
410  cyl_hankel_2(nu, z);
411  return res * -.25i;
412  }
413 
414  result_t eval(test_input_t const& to, trial_input_t const& tri,
415  std::integral_constant<int, 1>) const
416  {
417  using boost::math::cyl_bessel_j_prime;
418  using boost::math::cyl_neumann_prime;
419  using boost::math::cyl_hankel_2;
420  using namespace boost::math::double_constants;
421  using namespace std::complex_literals;
422 
423  int L = int(to.get_level_data().get_expansion_length());
424  location_t const& X = to.get_bounding_box().get_center();
425  location_t const& y = tri.get_x();
426  location_t d = X - y;
427  double r, theta;
428  cart2pol(X - y, r, theta);
429  double rdny = -d.dot(tri.get_unit_normal()) / r;
430  location_t Td(d(1), -d(0));
431  double thetadny = Td.dot(tri.get_unit_normal()) / (r * r);
432  result_t res(2 * L + 1, 1);
433  auto const& k = this->get_wave_number();
434  auto z = k * r;
435  for (int nu = -L; nu <= L; ++nu)
436  res(nu + L, 0) =
437  std::exp(1.0i * (nu * (pi + theta))) *
438  (
439  (cyl_bessel_j_prime(nu, z) - 1.0i * cyl_neumann_prime(nu, z)) * k * rdny +
440  cyl_hankel_2(nu, z) * 1.0i * (nu * thetadny)
441  );
442  return res * -.25i;
443  }
444  };
445 
449  template <unsigned int Nx>
450  class l2p
451  : public operator_with_wave_number<wave_number_t>
452  , public fmm_operator<l2p_tag>
453 
454  {
455  private:
457 
458  public:
460  typedef typename NiHu::normal_derivative_kernel<
462  >::test_input_t test_input_t;
463  typedef Eigen::Matrix<std::complex<double>, 1, Eigen::Dynamic> result_t;
464 
467  l2p(wave_number_t const& wave_number)
468  : base_t(wave_number)
469  {
470  }
471 
475  size_t cols(trial_input_t const& from) const
476  {
477  return from.get_level_data().get_data_size();
478  }
479 
484  result_t operator()(test_input_t const& x, trial_input_t const& from) const
485  {
486  result_t res = eval(x, from, std::integral_constant<int, Nx>());
487  if (from.get_level_data().is_high_freq())
488  return from.get_level_data().dft(res.conjugate().transpose()).conjugate().transpose() / double(cols(from));
489  return res;
490  }
491 
492  private:
493  result_t eval(test_input_t const& tsi, trial_input_t const& from,
494  std::integral_constant<int, 0>) const
495  {
496  using boost::math::cyl_bessel_j;
497  using namespace std::complex_literals;
498 
499  int L = int(from.get_level_data().get_expansion_length());
500  location_t const& X = from.get_bounding_box().get_center();
501  location_t x = tsi.get_x();
502  double r, theta;
503  cart2pol(x - X, r, theta);
504  auto z = this->get_wave_number() * r;
505  result_t res(1, 2 * L + 1);
506  for (int nu = -L; nu <= L; ++nu)
507  res(0, nu + L) = std::exp(-1.0i * (nu * theta)) *
508  cyl_bessel_j(nu, z);
509  return res;
510  }
511 
512  result_t eval(test_input_t const& tsi, trial_input_t const& from,
513  std::integral_constant<int, 1>) const
514  {
515  using boost::math::cyl_bessel_j;
516  using boost::math::cyl_bessel_j_prime;
517  using namespace std::complex_literals;
518 
519  location_t const& X = from.get_bounding_box().get_center();
520  location_t const& x = tsi.get_x();
521  location_t d = x - X;
522  double r, theta;
523  cart2pol(d, r, theta);
524  double rdnx = d.dot(tsi.get_unit_normal()) / r;
525  location_t Td(d(1), -d(0));
526  double thetadnx = -Td.dot(tsi.get_unit_normal()) / (r * r);
527 
528  int L = int(from.get_level_data().get_expansion_length());
529  result_t res(1, 2 * L + 1);
530 
531  auto const& k = this->get_wave_number();
532  auto z = k * r;
533  for (int nu = -L; nu <= L; ++nu)
534  res(0, nu + L) = std::exp(-1.0i * (nu * theta)) *
535  (
536  cyl_bessel_j_prime(nu, z) * k * rdnx
537  - cyl_bessel_j(nu, z) * 1.0i * (nu * thetadnx)
538  );
539  return res;
540  }
541  };
542 
546  template <unsigned int Nx>
547  class m2p
548  : public operator_with_wave_number<wave_number_t>
549  , public fmm_operator<m2p_tag>
550  {
551  private:
553 
554  public:
556  typedef typename NiHu::normal_derivative_kernel<
558  >::test_input_t test_input_t;
559  typedef Eigen::Matrix<std::complex<double>, 1, Eigen::Dynamic> result_t;
560 
563  m2p(wave_number_t const& wave_number)
564  : base_t(wave_number)
565  {
566  }
567 
571  size_t cols(trial_input_t const& from) const
572  {
573  return from.get_level_data().get_data_size();
574  }
575 
580  result_t operator()(test_input_t const& x, trial_input_t const& from) const
581  {
582  result_t res = eval(x, from, std::integral_constant<int, Nx>());
583  if (from.get_level_data().is_high_freq())
584  return from.get_level_data().dft(res.conjugate().transpose()).conjugate().transpose() / double(cols(from));
585  return res;
586  }
587 
588  private:
589  result_t eval(test_input_t const& tsi, trial_input_t const& from,
590  std::integral_constant<int, 0>) const
591  {
592  using boost::math::cyl_hankel_2;
593  using namespace boost::math::double_constants;
594  using namespace std::complex_literals;
595 
596  int L = int(from.get_level_data().get_expansion_length());
597  location_t const& Y = from.get_bounding_box().get_center();
598  location_t const& x = tsi.get_x();
599  auto d = x - Y;
600  double r, theta;
601  cart2pol(d, r, theta);
602  auto z = this->get_wave_number() * r;
603  result_t res(1, 2 * L + 1);
604  for (int nu = -L; nu <= L; ++nu)
605  res(0, -nu + L) = std::exp(1.0i * (nu * (pi + theta))) *
606  cyl_hankel_2(nu, z);
607  return res;
608  }
609 
610  result_t eval(test_input_t const& tsi, trial_input_t const& from,
611  std::integral_constant<int, 1>) const
612  {
613  using boost::math::cyl_bessel_j_prime;
614  using boost::math::cyl_neumann_prime;
615  using boost::math::cyl_hankel_2;
616  using namespace boost::math::double_constants;
617  using namespace std::complex_literals;
618 
619  location_t const& Y = from.get_bounding_box().get_center();
620  location_t const& x = tsi.get_x();
621  location_t d = x - Y;
622  double r, theta;
623  cart2pol(d, r, theta);
624  double rdnx = d.dot(tsi.get_unit_normal()) / r;
625  location_t Td(d(1), -d(0));
626  double thetadnx = -Td.dot(tsi.get_unit_normal()) / (r * r);
627 
628  int L = int(from.get_level_data().get_expansion_length());
629  result_t res(1, 2 * L + 1);
630 
631  auto const& k = this->get_wave_number();
632  auto z = k * r;
633  for (int nu = -L; nu <= L; ++nu)
634  res(0, -nu + L) = std::exp(1.0i * (nu * (pi + theta))) *
635  (
636  (cyl_bessel_j_prime(nu, z) - 1.0i * cyl_neumann_prime(nu, z)) * k * rdnx
637  + cyl_hankel_2(nu, z) * (1.0i * (nu * thetadnx)));
638  return res;
639  }
640  };
641 
645  helmholtz_2d_wb_fmm(wave_number_t const& wave_number)
646  : m_wave_number(wave_number)
647  {
648  }
649 
650  template <int Nx, int Ny>
651  struct p2p_type
652  {
655  > > type;
656  };
657 
658  template <int Ny>
659  struct p2m_type
660  {
661  typedef p2m<Ny> type;
662  };
663 
664  template <int Nx>
665  struct m2p_type
666  {
667  typedef m2p<Nx> type;
668  };
669 
670  template <int Ny>
671  struct p2l_type
672  {
673  typedef p2l<Ny> type;
674  };
675 
676  template <int Nx>
677  struct l2p_type
678  {
679  typedef l2p<Nx> type;
680  };
681 
682  template <int Nx, int Ny>
685  > >
686  create_p2p() const
687  {
690  return fmm::p2p<kernel_t>(kernel_t(m_wave_number));
691  }
692 
693  template <int Ny>
694  p2m<Ny> create_p2m() const
695  {
696  return p2m<Ny>(this->get_wave_number());
697  }
698 
699  template <int Ny>
700  p2l<Ny> create_p2l() const
701  {
702  return p2l<Ny>(this->get_wave_number());
703  }
704 
705  template <int Nx>
706  m2p<Nx> create_m2p() const
707  {
708  return m2p<Nx>(this->get_wave_number());
709  }
710 
711  template <int Nx>
712  l2p<Nx> create_l2p() const
713  {
714  return l2p<Nx>(this->get_wave_number());
715  }
716 
717  m2m create_m2m() const
718  {
719  return m2m(this->get_wave_number());
720  }
721 
722  l2l create_l2l() const
723  {
724  return l2l(this->get_wave_number());
725  }
726 
727  m2l create_m2l() const
728  {
729  return m2l(this->get_wave_number());
730  }
731 
732  wave_number_t const& get_wave_number() const
733  {
734  return m_wave_number;
735  }
736 
738  void set_accuracy(double)
739  {
740  }
741 
744  void init_level_data(cluster_tree_t const& tree)
745  {
746  using namespace boost::math::double_constants;
747 
748  double lambda = two_pi / std::real(m_wave_number);
749  m_level_data_vector.clear();
750  m_level_data_vector.resize(tree.get_n_levels());
751 
752  // initialize level data for each level where anything happens
753  for (size_t i = 2; i < tree.get_n_levels(); ++i)
754  {
755  // index of first cluster at the level
756  size_t idx = tree.level_begin(i);
757  double D = tree[idx].get_bounding_box().get_diameter();
758  m_level_data_vector[i].init(D / lambda);
759  }
760 
761  // check that the highest level leaf cluster is in the low frequency domain
762  size_t idx;
763  for (idx = 0; idx < tree.get_n_clusters(); ++idx)
764  if (tree[idx].is_leaf() && m_level_data_vector[tree[idx].get_level()].is_high_freq())
765  throw std::runtime_error("Leaf level cluster (" + std::to_string(idx) + ") has been found in the high frequency domain.");
766 
767  // initialize upward interpolation for each m2m receiver level
768  for (size_t i = 2; i < tree.get_n_levels() - 1; ++i)
769  {
770  size_t L_from = m_level_data_vector[i + 1].get_expansion_length();
771  m_level_data_vector[i].set_interp_up(L_from);
772  }
773 
774  // initialize downward interpolation for each l2l receiver level
775  for (size_t i = 3; i < tree.get_n_levels(); ++i)
776  {
777  size_t L_from = m_level_data_vector[i - 1].get_expansion_length();
778  m_level_data_vector[i].set_interp_dn(L_from);
779  }
780  }
781 
786  {
787  return m_level_data_vector[idx];
788  }
789 
794  {
795  return m_level_data_vector[idx];
796  }
797 
800  void print_level_data(std::ostream& os = std::cout) const
801  {
802  for (size_t i = 2; i < m_level_data_vector.size(); ++i)
803  {
804  auto const& ld = m_level_data_vector[i];
805  os << "level: " << i << " " << ld.get_expansion_length() << ' ' << ld.is_high_freq() << std::endl;
806  }
807  }
808 
809 private:
810  wave_number_t m_wave_number;
811  std::vector<helmholtz_2d_wb_level_data> m_level_data_vector;
812 };
813 
814 } // end of namespace fmm
815 } // namespace NiHu
816 
817 #endif /* NIHU_HELMHOLTZ_2D_WB_FMM_HPP_INCLUDED */
NiHu::helmholtz_kernel
Definition: helmholtz_kernel.hpp:44
NiHu::fmm::helmholtz_2d_wb_fmm::l2l
the l2l operator
Definition: helmholtz_2d_wb_fmm.hpp:138
fmm_operator.hpp
FMM operator types and tags.
NiHu::fmm::helmholtz_2d_wb_fmm::m2l::operator()
result_t operator()(cluster_t const &to, cluster_t const &from) const
evaluate the operator for a source and receiver cluster
Definition: helmholtz_2d_wb_fmm.hpp:231
NiHu::fmm::helmholtz_2d_wb_level_data::get_data_size
size_t get_data_size() const
return the size of the multipole / local data
Definition: helmholtz_2d_wb_level_data.cpp:100
helmholtz_2d_wb_x2x_matrix.h
Interface of M2M, L2L, and M2L operations for the 2D wide band Helmholtz FMM.
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_2d_wb_fmm::location_t
bounding_box_t::location_t location_t
the physical location type
Definition: helmholtz_2d_wb_fmm.hpp:58
NiHu::fmm::helmholtz_2d_wb_fmm
the 2d wide band helmholetz fmm
Definition: helmholtz_2d_wb_fmm.hpp:42
NiHu::fmm::helmholtz_2d_wb_m2m_matrix
m2m matrix of the wide band 2d helmholtz fmm
Definition: helmholtz_2d_wb_x2x_matrix.h:19
operator_with_wave_number.hpp
Implementation of class template NiHu::fmm::operator_with_wave_number.
NiHu::fmm::helmholtz_2d_wb_fmm::cvector_t
Eigen::Matrix< std::complex< double >, Eigen::Dynamic, 1 > cvector_t
a complex vector type
Definition: helmholtz_2d_wb_fmm.hpp:52
NiHu::fmm::helmholtz_2d_wb_fmm::m2p::operator()
result_t operator()(test_input_t const &x, trial_input_t const &from) const
evaluate the operator for a source and receiver
Definition: helmholtz_2d_wb_fmm.hpp:580
NiHu::fmm::helmholtz_2d_wb_fmm::m2m::result_t
helmholtz_2d_wb_m2m_matrix result_t
the evaluated operator type
Definition: helmholtz_2d_wb_fmm.hpp:87
NiHu::fmm::helmholtz_2d_wb_fmm::p2m::operator()
result_t operator()(test_input_t const &to, trial_input_t const &y) const
evaluate the operator for a source and receiver
Definition: helmholtz_2d_wb_fmm.hpp:290
NiHu::fmm::cluster_tree::get_n_clusters
size_t get_n_clusters() const
return number of clusters
Definition: cluster_tree.hpp:282
NiHu::fmm::cluster_base< helmholtz_2d_wb_cluster >::dimension
static const size_t dimension
Space dimension.
Definition: cluster.hpp:47
NiHu::fmm::helmholtz_2d_wb_fmm::p2l::operator()
result_t operator()(test_input_t const &to, trial_input_t const &y) const
evaluate the operator for a source and receiver
Definition: helmholtz_2d_wb_fmm.hpp:385
NiHu::fmm::helmholtz_2d_wb_fmm::m2p::m2p
m2p(wave_number_t const &wave_number)
constructor of the operator
Definition: helmholtz_2d_wb_fmm.hpp:563
NiHu::fmm::helmholtz_2d_wb_fmm::helmholtz_2d_wb_fmm
helmholtz_2d_wb_fmm(wave_number_t const &wave_number)
constructor
Definition: helmholtz_2d_wb_fmm.hpp:645
NiHu::fmm::helmholtz_2d_wb_fmm::p2m_type
Definition: helmholtz_2d_wb_fmm.hpp:659
NiHu::fmm::helmholtz_2d_wb_fmm::l2l::operator()
result_t operator()(cluster_t const &to, cluster_t const &from) const
evaluate the operator for a source and receiver cluster
Definition: helmholtz_2d_wb_fmm.hpp:173
NiHu::fmm::helmholtz_2d_wb_fmm::l2p::cols
size_t cols(trial_input_t const &from) const
number of columns of the operator
Definition: helmholtz_2d_wb_fmm.hpp:475
NiHu::fmm::helmholtz_2d_wb_fmm::p2m::trial_input_t
NiHu::normal_derivative_kernel< distance_dependent_kernel_t, 0, Ny >::trial_input_t trial_input_t
the trial input type
Definition: helmholtz_2d_wb_fmm.hpp:267
NiHu::fmm::helmholtz_2d_wb_fmm::dimension
static const size_t dimension
the space dimension
Definition: helmholtz_2d_wb_fmm.hpp:54
NiHu::fmm::helmholtz_2d_wb_fmm::p2m::p2m
p2m(wave_number_t const &wave_number)
constructor of the operator
Definition: helmholtz_2d_wb_fmm.hpp:273
NiHu::fmm::helmholtz_2d_wb_fmm::m2l::unique_idx
static size_t unique_idx(cluster_t const &to, cluster_t const &from)
assign a unique index to source and receiver clusters
Definition: helmholtz_2d_wb_fmm.hpp:222
NiHu::fmm::helmholtz_2d_wb_fmm::l2l::unique_idx
static size_t unique_idx(cluster_t const &to, cluster_t const &from)
return a unique index for a source and receiver cluster
Definition: helmholtz_2d_wb_fmm.hpp:162
NiHu::fmm::bounding_box< dimension, double >::location_t
Eigen::Matrix< scalar_t, dimension, 1 > location_t
the location type in the bounding box
Definition: bounding_box.hpp:38
NiHu::fmm::helmholtz_2d_wb_fmm::print_level_data
void print_level_data(std::ostream &os=std::cout) const
print debug information
Definition: helmholtz_2d_wb_fmm.hpp:800
NiHu::fmm::helmholtz_2d_wb_fmm::m2l::m2l
m2l(wave_number_t const &wave_number)
constructor
Definition: helmholtz_2d_wb_fmm.hpp:213
NiHu::fmm::helmholtz_2d_wb_cluster::get_level_data
const helmholtz_2d_wb_level_data & get_level_data() const
return the level data
Definition: helmholtz_2d_wb_cluster.cpp:20
NiHu::fmm::helmholtz_2d_wb_fmm::wave_number_t
WaveNumber wave_number_t
template parameter as nested type
Definition: helmholtz_2d_wb_fmm.hpp:46
NiHu::fmm::helmholtz_2d_wb_level_data::dft
const cvector_t & dft(cvector_t const &multi) const
perform dft on this level
Definition: helmholtz_2d_wb_level_data.cpp:120
NiHu::fmm::helmholtz_2d_wb_fmm::bounding_box_t
cluster_t::bounding_box_t bounding_box_t
the cluster's bounding box type
Definition: helmholtz_2d_wb_fmm.hpp:56
NiHu::fmm::helmholtz_2d_wb_level_data::is_high_freq
bool is_high_freq() const
return true if the level is in hgh frequency
Definition: helmholtz_2d_wb_level_data.cpp:114
NiHu::fmm::helmholtz_2d_wb_fmm::get_level_data
helmholtz_2d_wb_level_data & get_level_data(size_t idx)
return level data reference at a specified level
Definition: helmholtz_2d_wb_fmm.hpp:793
NiHu::exponential_covariance_kernel
Definition: covariance_kernel.hpp:42
NiHu::fmm::helmholtz_2d_wb_m2l_matrix
m2l matrix of the wide band 2d helmholtz fmm
Definition: helmholtz_2d_wb_x2x_matrix.h:87
NiHu::fmm::cluster_tree< cluster_t >
NiHu::fmm::helmholtz_2d_wb_level_data
class containing the level data of the helmholtz 2d wide band fmm
Definition: helmholtz_2d_wb_level_data.h:24
p2p.hpp
P2P operator.
NiHu::fmm::helmholtz_2d_wb_fmm::m2l::cluster_t
helmholtz_2d_wb_fmm::cluster_t cluster_t
the cluster type
Definition: helmholtz_2d_wb_fmm.hpp:207
NiHu::fmm::helmholtz_2d_wb_fmm::get_level_data
helmholtz_2d_wb_level_data const & get_level_data(size_t idx) const
return level data at a specified level
Definition: helmholtz_2d_wb_fmm.hpp:785
m2l_indices.hpp
Implementation of class template Nihu::fmm::m2l_indices.
NiHu::fmm::helmholtz_2d_wb_fmm::p2m::test_input_t
helmholtz_2d_wb_fmm::cluster_t test_input_t
the test input type
Definition: helmholtz_2d_wb_fmm.hpp:263
NiHu::fmm::helmholtz_2d_wb_fmm::m2m::m2m
m2m(wave_number_t const &wave_number)
constructor of the operator
Definition: helmholtz_2d_wb_fmm.hpp:91
NiHu::fmm::helmholtz_2d_wb_fmm::init_level_data
void init_level_data(cluster_tree_t const &tree)
initialize level data for a specified cluster tree
Definition: helmholtz_2d_wb_fmm.hpp:744
NiHu::fmm::helmholtz_2d_wb_fmm::p2l_type
Definition: helmholtz_2d_wb_fmm.hpp:671
NiHu::fmm::helmholtz_2d_wb_fmm::p2m::result_t
cvector_t result_t
the evaluated operator's type
Definition: helmholtz_2d_wb_fmm.hpp:269
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_2d_wb_fmm::m2m::operator()
result_t operator()(cluster_t const &to, cluster_t const &from) const
evaluate the operator for a source and receiver cluster
Definition: helmholtz_2d_wb_fmm.hpp:113
NiHu::fmm::helmholtz_2d_wb_l2l_matrix
l2l matrix of the wide band 2d helmholtz fmm
Definition: helmholtz_2d_wb_x2x_matrix.h:53
NiHu::fmm::helmholtz_2d_wb_fmm::l2p_type
Definition: helmholtz_2d_wb_fmm.hpp:677
NiHu::fmm::helmholtz_2d_wb_fmm::l2p::operator()
result_t operator()(test_input_t const &x, trial_input_t const &from) const
evaluate the operator for a source and receiver
Definition: helmholtz_2d_wb_fmm.hpp:484
NiHu::fmm::helmholtz_2d_wb_fmm::l2p::l2p
l2p(wave_number_t const &wave_number)
constructor of the operator
Definition: helmholtz_2d_wb_fmm.hpp:467
NiHu::fmm::helmholtz_2d_wb_fmm::p2m
the p2m operator
Definition: helmholtz_2d_wb_fmm.hpp:256
NiHu::fmm::fmm_operator
Operator defining its tag type.
Definition: fmm_operator.hpp:85
NiHu::fmm::helmholtz_2d_wb_fmm::p2l::p2l
p2l(wave_number_t const &wave_number)
constructor of the operator
Definition: helmholtz_2d_wb_fmm.hpp:368
NiHu::fmm::helmholtz_2d_wb_fmm::m2p_type
Definition: helmholtz_2d_wb_fmm.hpp:665
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_2d_wb_fmm::cluster_t
helmholtz_2d_wb_cluster cluster_t
the cluster type of the FMM
Definition: helmholtz_2d_wb_fmm.hpp:48
NiHu::fmm::helmholtz_2d_wb_fmm::l2l::cluster_t
helmholtz_2d_wb_fmm::cluster_t cluster_t
the cluster type
Definition: helmholtz_2d_wb_fmm.hpp:147
NiHu::fmm::helmholtz_2d_wb_fmm::m2l::result_t
helmholtz_2d_wb_m2l_matrix result_t
\the evaluated operator's type
Definition: helmholtz_2d_wb_fmm.hpp:209
NiHu::fmm::helmholtz_2d_wb_cluster
the cluster type of the helmholtz 2d wide band fmm
Definition: helmholtz_2d_wb_cluster.h:35
NiHu::fmm::helmholtz_2d_wb_fmm::l2l::l2l
l2l(wave_number_t const &wave_number)
constructor
Definition: helmholtz_2d_wb_fmm.hpp:153
NiHu::fmm::helmholtz_2d_wb_fmm::m2m::cluster_t
helmholtz_2d_wb_fmm::cluster_t cluster_t
the cluster type
Definition: helmholtz_2d_wb_fmm.hpp:85
NiHu::fmm::helmholtz_2d_wb_level_data::get_expansion_length
size_t get_expansion_length() const
return the expansion length
Definition: helmholtz_2d_wb_level_data.cpp:95
NiHu::fmm::bounding_box::get_center
const location_t & get_center(void) const
return center
Definition: bounding_box.hpp:75
NiHu::fmm::helmholtz_2d_wb_fmm::p2m::rows
size_t rows(test_input_t const &to) const
number of rows of the operator
Definition: helmholtz_2d_wb_fmm.hpp:281
NiHu::fmm::helmholtz_2d_wb_fmm::p2l::rows
size_t rows(test_input_t const &to) const
number of rows of the operator
Definition: helmholtz_2d_wb_fmm.hpp:376
NiHu::fmm::bounding_box< dimension, double >
NiHu::fmm::helmholtz_2d_wb_fmm::p2p_type
Definition: helmholtz_2d_wb_fmm.hpp:651
helmholtz_2d_wb_cluster.h
Interface of class helmholtz_2d_wb_cluster.
NiHu::fmm::helmholtz_2d_wb_fmm::m2p::cols
size_t cols(trial_input_t const &from) const
number of columns of the operator
Definition: helmholtz_2d_wb_fmm.hpp:571
NiHu::normal_derivative_kernel
Normal derivative of a distance dependent kernel.
Definition: normal_derivative_kernel.hpp:26
NiHu::fmm::bounding_box< dimension, double >::dist2idx
static unsigned dist2idx(location_t const &child, location_t const &parent)
convert parent-to-child direction to child index
Definition: bounding_box.hpp:139
cluster.hpp
implementation of class NiHu::fmm::cluster_base
NiHu::fmm::helmholtz_2d_wb_fmm::l2p
the l2p operator
Definition: helmholtz_2d_wb_fmm.hpp:450
NiHu::fmm::operator_with_wave_number
class storing a wave number
Definition: operator_with_wave_number.hpp:17
NiHu::fmm::helmholtz_2d_wb_fmm::m2l
the m2l operator
Definition: helmholtz_2d_wb_fmm.hpp:198
NiHu::fmm::m2l_indices
Class assigning indices to M2L distances.
Definition: m2l_indices.hpp:21
NiHu::fmm::helmholtz_2d_wb_fmm::l2l::result_t
helmholtz_2d_wb_l2l_matrix result_t
the evaluated operator's type
Definition: helmholtz_2d_wb_fmm.hpp:149
NiHu::fmm::helmholtz_2d_wb_fmm::m2p
the m2p operator
Definition: helmholtz_2d_wb_fmm.hpp:547
NiHu::fmm::p2p
Definition: p2p.hpp:20
helmholtz_2d_wb_level_data.h
declaration of class helmholtz_2d_wb_level_data
NiHu::fmm::helmholtz_2d_wb_fmm::m2m::unique_idx
static size_t unique_idx(cluster_t const &to, cluster_t const &from)
return a unique index for a source and receiver cluster
Definition: helmholtz_2d_wb_fmm.hpp:100
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_2d_wb_fmm::m2m
the m2m operator
Definition: helmholtz_2d_wb_fmm.hpp:76
NiHu::fmm::helmholtz_2d_wb_fmm::cluster_tree_t
cluster_tree< cluster_t > cluster_tree_t
the cluster tree type
Definition: helmholtz_2d_wb_fmm.hpp:50
NiHu::fmm::helmholtz_2d_wb_fmm::set_accuracy
void set_accuracy(double)
set the method's prescribed accuracy
Definition: helmholtz_2d_wb_fmm.hpp:738
NiHu::fmm::helmholtz_2d_wb_fmm::p2l
the p2l operator
Definition: helmholtz_2d_wb_fmm.hpp:352