7 #ifndef NIHU_BLACK_BOX_FMM_HPP_INCLUDED
8 #define NIHU_BLACK_BOX_FMM_HPP_INCLUDED
24 #include <type_traits>
32 template <
class Kernel>
41 static int const nx = 0;
42 static int const ny = 0;
45 template <
class DistanceDependentKernel,
int Nx,
int Ny>
51 static int const nx = Nx;
52 static int const ny = Ny;
60 template <
class Kernel>
72 static int const Nx = derivative_traits_t::nx;
73 static int const Ny = derivative_traits_t::ny;
96 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>,
102 return cluster_t::bounding_box_t::dist2idx(
103 from.get_bounding_box().get_center(),
104 to.get_bounding_box().get_center());
109 return result_t(chebanterp<double, space_dimension>(
111 to.get_bounding_box(),
125 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>,
131 return cluster_t::bounding_box_t::dist2idx(
132 to.get_bounding_box().get_center(),
133 from.get_bounding_box().get_center());
138 return result_t(chebanterp<double, space_dimension>(
140 from.get_bounding_box(),
153 typedef Eigen::Matrix<kernel_scalar_t, Eigen::Dynamic, Eigen::Dynamic> result_t;
156 : m_kernel_00(kernel)
170 for (
size_t i = 0; i < N; ++i)
171 for (
size_t j = 0; j < M; ++j)
175 * Eigen::Matrix<kernel_scalar_t, field_dimension, field_dimension>::Identity();
180 kernel_00_t m_kernel_00;
191 typedef typename std::conditional<
195 >::type trial_input_t;
197 typedef Eigen::Matrix<double, Eigen::Dynamic, field_dimension> result_t;
204 size_t cols(trial_input_t
const &)
const
209 result_t operator()(
test_input_t const &to, trial_input_t
const &from)
const
211 return eval(to, from, std::integral_constant<int, Ny>());
215 result_t eval(
test_input_t const &to, trial_input_t
const &from, std::integral_constant<int, 0>)
const
217 Eigen::Matrix<double, Eigen::Dynamic, 1> res0 = chebanterp<double, space_dimension>(
219 to.get_bounding_box(), from.get_x());
220 result_t res(rows(to), cols(from));
221 for (Eigen::Index i = 0; i < res0.rows(); ++i)
222 for (Eigen::Index j = 0; j < res0.cols(); ++j)
224 res0(i, j) * Eigen::Matrix<double, field_dimension, field_dimension>::Identity();
228 result_t eval(
test_input_t const &to, trial_input_t
const &from, std::integral_constant<int, 1>)
const
230 Eigen::Matrix<double, Eigen::Dynamic, 1> res0 = chebanterp_dny<double, space_dimension>(
232 to.get_bounding_box(),
234 from.get_unit_normal());
235 result_t res(rows(to), cols(from));
236 for (Eigen::Index i = 0; i < res0.rows(); ++i)
237 for (Eigen::Index j = 0; j < res0.cols(); ++j)
239 res0(i, j) * Eigen::Matrix<double, field_dimension, field_dimension>::Identity();
250 typedef typename std::conditional<
254 >::type test_input_t;
258 typedef Eigen::Matrix<double, field_dimension, Eigen::Dynamic> result_t;
260 size_t rows(test_input_t
const &)
const
270 result_t operator()(test_input_t
const &to,
trial_input_t const &from)
const
272 return eval(to, from, std::integral_constant<int, Nx>());
276 result_t eval(test_input_t
const &to,
trial_input_t const &from, std::integral_constant<int, 0>)
const
278 Eigen::Matrix<double, 1, Eigen::Dynamic> res0 = chebanterp<double, space_dimension>(
280 from.get_bounding_box(),
281 to.get_x()).transpose();
283 result_t res(rows(to), cols(from));
284 for (Eigen::Index i = 0; i < res0.rows(); ++i)
285 for (Eigen::Index j = 0; j < res0.cols(); ++j)
287 res0(i, j) * Eigen::Matrix<double, field_dimension, field_dimension>::Identity();
291 result_t eval(test_input_t
const &to,
trial_input_t const &from, std::integral_constant<int, 1>)
const
293 Eigen::Matrix<double, 1, Eigen::Dynamic> res0 = chebanterp_dny<double, space_dimension>(
295 from.get_bounding_box(),
300 result_t res(rows(to), cols(from));
301 for (Eigen::Index i = 0; i < res0.rows(); ++i)
302 for (Eigen::Index j = 0; j < res0.cols(); ++j)
304 res0(i, j) * Eigen::Matrix<double, field_dimension, field_dimension>::Identity();
316 typedef typename kernel_ny_t::trial_input_t trial_input_t;
317 typedef Eigen::Matrix<kernel_scalar_t, Eigen::Dynamic, field_dimension> result_t;
320 : m_kernel_ny(kernel)
329 size_t cols(trial_input_t
const &)
const
334 result_t operator()(
test_input_t const &to, trial_input_t
const &from)
const
336 return eval(to, from, std::integral_constant<int, Ny>());
340 result_t eval(
test_input_t const &to, trial_input_t
const &from, std::integral_constant<int, 0>)
const
343 result_t res(rows(to), cols(from));
344 for (
size_t i = 0; i < n; ++i)
347 Eigen::Matrix<kernel_scalar_t, field_dimension, field_dimension>::Identity();
351 result_t eval(
test_input_t const &to, trial_input_t
const &from, std::integral_constant<int, 1>)
const
354 result_t res(rows(to), cols(from));
355 for (
size_t i = 0; i < n; ++i)
358 Eigen::Matrix<kernel_scalar_t, field_dimension, field_dimension>::Identity();
362 kernel_ny_t m_kernel_ny;
372 typedef typename kernel_t::test_input_t test_input_t;
373 typedef Eigen::Matrix<kernel_scalar_t, field_dimension, Eigen::Dynamic> result_t;
376 : m_kernel_nx(kernel)
380 size_t rows(test_input_t
const &)
const
394 result_t res(rows(to), cols(from));
395 for (
size_t i = 0; i < n; ++i)
398 Eigen::Matrix<kernel_scalar_t, field_dimension, field_dimension>::Identity();
405 kernel_nx_t m_kernel_nx;
439 return p2l(m_kernel);
447 return m2p(m_kernel);
479 return m2l(m_kernel);
486 template <
class Kernel>
487 black_box_fmm<Kernel> create_black_box_fmm(Kernel
const &kernel)
489 return black_box_fmm<Kernel>(kernel);