NiHu  2.0
laplace_2d_fmm.hpp
Go to the documentation of this file.
1 
7 #ifndef NIHU_LAPLACE_2D_FMM_HPP_INCLUDED
8 #define NIHU_LAPLACE_2D_FMM_HPP_INCLUDED
9 
10 #include "cluster.hpp"
11 #include "m2l_indices.hpp"
12 #include "p2p.hpp"
13 
14 #include "library/laplace_2d.hpp"
15 
16 #include <boost/math/constants/constants.hpp>
17 #include <boost/math/special_functions/binomial.hpp>
18 
19 #include <complex>
20 
21 namespace NiHu
22 {
23 namespace fmm
24 {
25 
27 class laplace_2d_cluster;
28 
30 template <>
32 {
34  static size_t const dimension = 2;
36  typedef Eigen::Matrix<std::complex<double>, Eigen::Dynamic, 1> multipole_t;
38  typedef Eigen::Matrix<std::complex<double>, Eigen::Dynamic, 1> local_t;
39 };
40 
43  : public cluster_base<laplace_2d_cluster>
44 {
46 
47 public:
49  typedef typename base_t::multipole_t multipole_t;
51  typedef typename base_t::local_t local_t;
52 
54  void set_expansion_length(size_t L);
55 
58  size_t get_expansion_length() const;
59 
62 
64  local_t zero_local() const;
65 
66 private:
67  size_t m_expansion_length;
68 };
69 
72 {
73 public:
80 
81 private:
85  static std::complex<double> center2complex(cluster_t const &c);
86 
87 public:
92  template <int Nx, int Ny>
95  > >
96  create_p2p() const
97  {
100  > kernel_t;
101  return fmm::p2p<kernel_t>(kernel_t());
102  }
103 
104 
107  template <unsigned Ny>
108  class p2m
109  {
110  public:
111  typedef cluster_t test_input_t;
112 
113  typedef typename NiHu::normal_derivative_kernel<
115  0, Ny
116  >::trial_input_t trial_input_t;
117 
118  typedef Eigen::Matrix<std::complex<double>, Eigen::Dynamic, 1> result_t;
119 
120  size_t rows(test_input_t const &to) const
121  {
122  return to.get_expansion_length() + 1;
123  }
124 
125  result_t operator()(test_input_t const &to, trial_input_t const & from) const
126  {
127  return eval(to, from, std::integral_constant<unsigned, Ny>());
128  }
129 
130  result_t eval(test_input_t const &to,
131  trial_input_t const &from,
132  std::integral_constant<unsigned, 0>) const
133  {
134  using namespace boost::math::double_constants;
135 
136  auto const& y = from.get_x();
137  std::complex<double> zy(y(0), y(1));
138  zy -= center2complex(to);
139 
140  result_t res(to.get_expansion_length() + 1, 1);
141  res(0) = 1.0;
142  for (size_t k = 1; k <= to.get_expansion_length(); ++k)
143  res(k) = -std::pow(zy, k) / double(k);
144  return -res / two_pi;
145  }
146 
147  result_t eval(test_input_t const &to,
148  trial_input_t const &from,
149  std::integral_constant<unsigned, 1>) const
150  {
151  using namespace boost::math::double_constants;
152 
153  auto const& y = from.get_x();
154  std::complex<double> zy(y(0), y(1));
155  zy -= center2complex(to);
156  std::complex<double> zydny(from.get_unit_normal()(0), from.get_unit_normal()(1));
157  result_t res(to.get_expansion_length() + 1, 1);
158  res(0) = 0.0;
159  for (size_t k = 1; k <= to.get_expansion_length(); ++k)
160  res(k) = -std::pow(zy, k-1);
161  res *= zydny;
162  return -res / two_pi;
163  }
164  };
165 
166 
169  template <unsigned Ny>
170  class p2l
171  {
172  public:
173  typedef cluster_t test_input_t;
174  typedef typename NiHu::normal_derivative_kernel<
176  0, Ny
177  >::trial_input_t trial_input_t;
178  typedef Eigen::Matrix<std::complex<double>, Eigen::Dynamic, 1> result_t;
179 
180  size_t rows(test_input_t const &to) const
181  {
182  return to.get_expansion_length() + 1;
183  }
184 
185  result_t operator()(test_input_t const &to, trial_input_t const &from) const
186  {
187  return eval(to, from, std::integral_constant<unsigned, Ny>());
188  }
189 
190  private:
191  result_t eval(test_input_t const &to, trial_input_t const & from,
192  std::integral_constant<unsigned, 0>) const
193  {
194  using namespace boost::math::double_constants;
195 
196  std::complex<double> z =
197  std::complex<double>(from.get_x()(0), from.get_x()(1))
198  - center2complex(to);
199 
200  result_t res(to.get_expansion_length() + 1, 1);
201  res(0) = std::log(-z);
202  for (size_t k = 1; k <= to.get_expansion_length(); ++k)
203  res(k) = -1. / (double(k) * std::pow(z, k));
204  return -res / two_pi;
205  }
206 
207  result_t eval(test_input_t const &to, trial_input_t const & from,
208  std::integral_constant<unsigned, 1>) const
209  {
210  using namespace boost::math::double_constants;
211 
212  std::complex<double> z =
213  std::complex<double>(from.get_x()(0), from.get_x()(1))
214  - center2complex(to);
215 
216  std::complex<double> zdny(from.get_unit_normal()(0), from.get_unit_normal()(1));
217 
218  result_t res(to.get_expansion_length() + 1, 1);
219  res(0) = 1. / z;
220  for (size_t k = 1; k <= to.get_expansion_length(); ++k)
221  res(k) = 1. / std::pow(z, k + 1);
222  res *= zdny;
223  return -res / two_pi;
224  }
225  };
226 
227 
230  template <unsigned Nx>
231  class l2p
232  {
233  public:
234  typedef typename NiHu::normal_derivative_kernel<
236  Nx, 0
237  >::test_input_t test_input_t;
238 
239  typedef cluster_t trial_input_t;
240  typedef Eigen::Matrix<std::complex<double>, 1, Eigen::Dynamic> complex_result_t;
241  typedef complex_result_t result_t;
242 
243  size_t cols(trial_input_t const &from) const
244  {
245  return from.get_expansion_length() + 1;
246  }
247 
248  result_t operator()(test_input_t const &to, trial_input_t const & from) const
249  {
250  return eval(to, from, std::integral_constant<unsigned, Nx>());
251  }
252 
253  private:
254  result_t eval(test_input_t const &to,
255  trial_input_t const &from,
256  std::integral_constant<unsigned, 0>) const
257  {
258  std::complex<double> z = std::complex<double>(to.get_x()(0), to.get_x()(1)) - center2complex(from);
259  complex_result_t res(1, from.get_expansion_length() + 1);
260  for (size_t k = 0; k <= from.get_expansion_length(); ++k)
261  res(k) = std::pow(z, k);
262  return res;
263  }
264 
265  result_t eval(test_input_t const &to,
266  trial_input_t const &from,
267  std::integral_constant<unsigned, 1>) const
268  {
269  std::complex<double> z = std::complex<double>(to.get_x()(0), to.get_x()(1)) - center2complex(from);
270  std::complex<double> zdnx(to.get_unit_normal()(0), to.get_unit_normal()(1));
271  complex_result_t res(1, from.get_expansion_length() + 1);
272  for (size_t k = 0; k <= from.get_expansion_length(); ++k)
273  res(k) = double(k) * std::pow(z, k-1);
274  res *= zdnx;
275  return res;
276  }
277  };
278 
279 
282  template <unsigned Nx>
283  class m2p
284  {
285  public:
286  typedef typename NiHu::normal_derivative_kernel<
288  Nx, 0
289  >::test_input_t test_input_t;
290  typedef cluster_t trial_input_t;
291  typedef Eigen::Matrix<std::complex<double>, 1, Eigen::Dynamic> complex_result_t;
292  typedef complex_result_t result_t;
293 
294  size_t cols(trial_input_t const &from) const
295  {
296  return from.get_expansion_length() + 1;
297  }
298 
299  result_t operator()(test_input_t const &to, trial_input_t const &from) const
300  {
301  return eval(to, from, std::integral_constant<unsigned, Nx>());
302  }
303 
304  private:
305  result_t eval(test_input_t const &to,
306  trial_input_t const &from,
307  std::integral_constant<unsigned, 0>) const
308  {
309  complex_result_t res(1, from.get_expansion_length() + 1);
310  std::complex<double> z = std::complex<double>(to.get_x()(0), to.get_x()(1)) - center2complex(from);
311  res(0) = std::log(z);
312  for (size_t k = 1; k <= from.get_expansion_length(); ++k)
313  res(k) = 1. / std::pow(z, k);
314  return res;
315  }
316 
317  result_t eval(test_input_t const &to,
318  trial_input_t const &from,
319  std::integral_constant<unsigned, 1>) const
320  {
321  complex_result_t res(1, from.get_expansion_length() + 1);
322  std::complex<double> z = std::complex<double>(to.get_x()(0), to.get_x()(1)) - center2complex(from);
323  std::complex<double> zdnx(to.get_unit_normal()(0), to.get_unit_normal()(1));
324  res(0) = 1. / z;
325  for (size_t k = 1; k <= from.get_expansion_length(); ++k)
326  res(k) = -double(k) / std::pow(z, k + 1);
327  res *= zdnx;
328  return res;
329  }
330  };
331 
332 
334  class m2m
335  {
336  public:
337  typedef Eigen::Matrix<std::complex<double>, Eigen::Dynamic, Eigen::Dynamic> result_t;
339 
340  static size_t unique_idx(cluster_t const &to, cluster_t const &from);
341 
342  result_t operator()(cluster_t to, cluster_t from) const;
343  };
344 
345 
347  class l2l
348  {
349  public:
350  typedef Eigen::Matrix<std::complex<double>, Eigen::Dynamic, Eigen::Dynamic> result_t;
352 
353  static size_t unique_idx(cluster_t const &to, cluster_t const &from);
354 
355  result_t operator()(cluster_t to, cluster_t from) const;
356  };
357 
358 
360  class m2l
361  {
362  public:
363  typedef Eigen::Matrix<std::complex<double>, Eigen::Dynamic, Eigen::Dynamic> result_t;
365 
366  static size_t unique_idx(cluster_t const &to, cluster_t const &from);
367 
368  result_t operator()(cluster_t to, cluster_t from) const;
369  };
370 
371 
375  template <unsigned Ny>
377  {
378  return p2m<Ny>();
379  }
380 
381 
385  template <unsigned Ny>
387  {
388  return p2l<Ny>();
389  }
390 
391 
395  template <unsigned Nx>
397  {
398  return m2p<Nx>();
399  }
400 
401 
405  template <unsigned Nx>
407  {
408  return l2p<Nx>();
409  }
410 
411 
414  m2m create_m2m() const;
415 
416 
419  l2l create_l2l() const;
420 
421 
424  m2l create_m2l() const;
425 };
426 
427 } // end of namespace fmm
428 } // namespace NiHu
429 #endif /* NIHU_LAPLACE_2D_FMM_HPP_INCLUDED */
NiHu::fmm::laplace_2d_fmm
the fmm for the Laplace equation in 2D
Definition: laplace_2d_fmm.hpp:71
NiHu::fmm::laplace_2d_fmm::create_l2p
l2p< Nx > create_l2p() const
return an instance of the L2P operator
Definition: laplace_2d_fmm.hpp:406
NiHu::fmm::cluster_base::local_t
traits_t::local_t local_t
Local type.
Definition: cluster.hpp:60
NiHu::fmm::laplace_2d_fmm::create_p2m
p2m< Ny > create_p2m() const
return an instance of the P2M operator
Definition: laplace_2d_fmm.hpp:376
NiHu::fmm::laplace_2d_fmm::create_m2l
m2l create_m2l() const
return an instance of the M2L operator
Definition: laplace_2d_fmm.cpp:35
NiHu::fmm::laplace_2d_fmm::m2l
M2L operator of the Laplace 2D FMM.
Definition: laplace_2d_fmm.hpp:360
NiHu::fmm::laplace_2d_cluster::set_expansion_length
void set_expansion_length(size_t L)
set the expansion length
Definition: laplace_2d_fmm.cpp:40
NiHu::fmm::laplace_2d_fmm::location_t
cluster_t::location_t location_t
the location type
Definition: laplace_2d_fmm.hpp:79
NiHu::fmm::cluster_traits< laplace_2d_cluster >::local_t
Eigen::Matrix< std::complex< double >, Eigen::Dynamic, 1 > local_t
the local type
Definition: laplace_2d_fmm.hpp:38
NiHu::exponential_covariance_kernel
Definition: covariance_kernel.hpp:42
NiHu::fmm::laplace_2d_fmm::create_l2l
l2l create_l2l() const
return an instance of the L2L operator
Definition: laplace_2d_fmm.cpp:29
p2p.hpp
P2P operator.
m2l_indices.hpp
Implementation of class template Nihu::fmm::m2l_indices.
NiHu::laplace_kernel
Kernel of the Laplace equation in two and three dimensions.
Definition: laplace_kernel.hpp:45
NiHu::fmm::laplace_2d_fmm::create_m2m
m2m create_m2m() const
return an instance of the M2M operator
Definition: laplace_2d_fmm.cpp:23
NiHu::fmm::cluster_traits
CRTP traits structure of a cluster.
Definition: cluster.hpp:33
NiHu::fmm::laplace_2d_cluster::zero_local
local_t zero_local() const
return a cleared local contribution
Definition: laplace_2d_fmm.cpp:55
NiHu::fmm::laplace_2d_cluster::zero_multipole
multipole_t zero_multipole() const
return a cleared multipole contribution
Definition: laplace_2d_fmm.cpp:50
NiHu::fmm::cluster_base
CRTP base class of clusters.
Definition: cluster.hpp:40
NiHu::fmm::cluster_base::multipole_t
traits_t::multipole_t multipole_t
Multipole type.
Definition: cluster.hpp:58
NiHu::fmm::laplace_2d_cluster::multipole_t
base_t::multipole_t multipole_t
the multipole type
Definition: laplace_2d_fmm.hpp:49
NiHu::fmm::laplace_2d_fmm::p2l
P2L operator of the Laplace 2D FMM.
Definition: laplace_2d_fmm.hpp:170
NiHu::fmm::laplace_2d_fmm::create_m2p
m2p< Nx > create_m2p() const
return an instance of the M2P operator
Definition: laplace_2d_fmm.hpp:396
NiHu::fmm::laplace_2d_fmm::cluster_t
laplace_2d_cluster cluster_t
the cluster type
Definition: laplace_2d_fmm.hpp:75
NiHu::fmm::laplace_2d_cluster::get_expansion_length
size_t get_expansion_length() const
get the expansion length
Definition: laplace_2d_fmm.cpp:45
NiHu::fmm::laplace_2d_fmm::bounding_box_t
cluster_t::bounding_box_t bounding_box_t
the bounding box type
Definition: laplace_2d_fmm.hpp:77
NiHu::fmm::laplace_2d_cluster::local_t
base_t::local_t local_t
the local type
Definition: laplace_2d_fmm.hpp:51
NiHu::fmm::bounding_box< dimension, double >
NiHu::fmm::laplace_2d_fmm::l2l
L2L operator of the Laplace 2D FMM.
Definition: laplace_2d_fmm.hpp:347
NiHu::fmm::laplace_2d_fmm::create_p2l
p2l< Ny > create_p2l() const
return an instance of the P2L operator
Definition: laplace_2d_fmm.hpp:386
NiHu::normal_derivative_kernel
Normal derivative of a distance dependent kernel.
Definition: normal_derivative_kernel.hpp:26
NiHu::fmm::cluster_base< laplace_2d_cluster >::location_t
bounding_box_t::location_t location_t
Location type.
Definition: cluster.hpp:52
cluster.hpp
implementation of class NiHu::fmm::cluster_base
NiHu::fmm::laplace_2d_fmm::m2p
M2P operator of the Laplace 2D FMM.
Definition: laplace_2d_fmm.hpp:283
NiHu::fmm::laplace_2d_fmm::p2m
P2M operator of the Laplace 2D FMM.
Definition: laplace_2d_fmm.hpp:108
NiHu::fmm::laplace_2d_fmm::create_p2p
fmm::p2p< NiHu::normal_derivative_kernel< NiHu::laplace_kernel< NiHu::space_2d< double > >, Nx, Ny > > create_p2p() const
return an instance of the P2P operator
Definition: laplace_2d_fmm.hpp:96
NiHu::fmm::laplace_2d_fmm::m2m
M2M operator of the Laplace 2D FMM.
Definition: laplace_2d_fmm.hpp:334
NiHu::fmm::p2p
Definition: p2p.hpp:20
NiHu::fmm::laplace_2d_cluster
cluster type of the Laplace 2D FMM
Definition: laplace_2d_fmm.hpp:42
NiHu::fmm::cluster_traits< laplace_2d_cluster >::multipole_t
Eigen::Matrix< std::complex< double >, Eigen::Dynamic, 1 > multipole_t
the multipole type
Definition: laplace_2d_fmm.hpp:36
NiHu::fmm::laplace_2d_fmm::l2p
L2P operator of the Laplace 2D FMM.
Definition: laplace_2d_fmm.hpp:231