35 NT
integrate(
const FUN &fun,
const QGauss<1> &x_quadrature,
const double x_extent,
const double k)
37 const auto &x_q_p = x_quadrature.get_points();
38 const auto &x_q_w = x_quadrature.get_weights();
39 const int x_size = x_quadrature.size();
41 static_assert(d > 0,
"Dimension must be greater than zero");
43 const double S_d = 2. * std::pow(M_PI, d / 2.) / std::tgammal(d / 2.);
45 const double prefactor =
S_d
46 *
powr<-d>(2. * M_PI);
48 const NT result = tbb::parallel_reduce(
49 tbb::blocked_range<int>(0, x_size), NT(0),
50 [&](
const tbb::blocked_range<int> &r, NT running_total) -> NT {
51 for (
int x_it = r.begin(); x_it < r.end(); x_it++) {
52 const double x = x_q_p[x_it][0] * x_extent;
53 const double x_weight = x_q_w[x_it] * x_extent;
54 const double q2 = x *
powr<2>(k);
57 x_weight * prefactor *
58 (0.5 *
powr<d>(k) * std::pow(x, (d - 2) / 2.))
63 [](
const NT a,
const NT b) {
return a + b; });
84 NT
angle_integrate(
const FUN &fun,
const QGauss<1> &x_quadrature,
const double x_extent,
const double k,
85 const QGauss<1> &cos_quadrature)
87 static_assert(d > 1,
"Dimension must be greater than one, otherwise the angular integral not defined.");
89 const auto &x_q_p = x_quadrature.get_points();
90 const auto &x_q_w = x_quadrature.get_weights();
91 const int x_size = x_quadrature.size();
92 const auto &cos_q_p = cos_quadrature.get_points();
93 const auto &cos_q_w = cos_quadrature.get_weights();
94 const int cos_size = cos_quadrature.size();
96 static_assert(d > 1,
"Dimension must be greater than one");
98 const double S_d = 2. * std::pow(M_PI, d / 2.) / std::tgamma(d / 2.);
100 const double prefactor =
S_d
101 *
powr<-d>(2. * M_PI);
103 const NT result = tbb::parallel_reduce(
104 tbb::blocked_range2d<int>(0, x_size, 0, cos_size), NT(0),
105 [&](
const tbb::blocked_range2d<int> &r, NT running_total) -> NT {
106 for (
int x_it = r.rows().begin(); x_it < r.rows().end(); x_it++) {
107 const double x = x_q_p[x_it][0] * x_extent;
108 const double x_weight = x_q_w[x_it] * x_extent;
109 const double q2 = x *
powr<2>(k);
111 for (
int cos_it = r.cols().begin(); cos_it < r.cols().end(); cos_it++) {
112 const double cos = (cos_q_p[cos_it][0] - 0.5) * 2.;
113 const double cos_weight = cos_q_w[cos_it] * 2.;
116 x_weight * prefactor *
117 (0.5 *
powr<d>(k) * std::pow(x, (d - 2) / 2.))
122 return running_total;
124 [](
const NT a,
const NT b) {
return a + b; });
145 NT
two_angle_integrate(
const FUN &fun,
const QGauss<1> &x_quadrature,
const double x_extent,
const double k,
146 const QGauss<1> &cos_quadrature)
148 static_assert(d > 2,
"Dimension must be greater than 2, otherwise the angular integral not defined.");
150 const auto &x_q_p = x_quadrature.get_points();
151 const auto &x_q_w = x_quadrature.get_weights();
152 const int x_size = x_quadrature.size();
153 const auto &cos_q_p = cos_quadrature.get_points();
154 const auto &cos_q_w = cos_quadrature.get_weights();
155 const int cos_size = cos_quadrature.size();
156 const auto &phi_q_p = cos_quadrature.get_points();
157 const auto &phi_q_w = cos_quadrature.get_weights();
158 const int phi_size = cos_quadrature.size();
160 static_assert(d > 1,
"Dimension must be greater than one");
162 const double S_d = 2. * std::pow(M_PI, d / 2.) / std::tgamma(d / 2.);
164 const double prefactor =
S_d
165 *
powr<-d>(2. * M_PI);
167 const NT result = tbb::parallel_reduce(
168 tbb::blocked_range3d<int>(0, x_size, 0, cos_size, 0, phi_size), NT(0),
169 [&](
const tbb::blocked_range3d<int> &r, NT running_total) -> NT {
170 for (
int x_it = r.pages().begin(); x_it < r.pages().end(); x_it++) {
171 const double x = x_q_p[x_it][0] * x_extent;
172 const double x_weight = x_q_w[x_it] * x_extent;
173 const double q2 = x *
powr<2>(k);
175 for (
int cos_it = r.rows().begin(); cos_it < r.rows().end(); cos_it++) {
176 const double cos = (cos_q_p[cos_it][0] - 0.5) * 2.;
177 const double cos_weight = cos_q_w[cos_it] * 2.;
179 for (
int phi_it = r.cols().begin(); phi_it < r.cols().end(); phi_it++) {
180 const double phi = phi_q_p[phi_it][0] * 2. * M_PI;
181 const double phi_weight = cos_q_w[cos_it] * 2. * M_PI;
184 x_weight * prefactor *
185 (0.5 *
powr<d>(k) * std::pow(x, (d - 2) / 2.))
187 * phi_weight / (2. * M_PI)
192 return running_total;
194 [](
const NT a,
const NT b) {
return a + b; });
216 const QGauss<1> &cos_quadrature)
218 static_assert(d > 3,
"Dimension must be greater than 3, otherwise the angular integral not defined.");
220 const auto &x_q_p = x_quadrature.get_points();
221 const auto &x_q_w = x_quadrature.get_weights();
222 const int x_size = x_quadrature.size();
223 const auto &cos_q_p = cos_quadrature.get_points();
224 const auto &cos_q_w = cos_quadrature.get_weights();
225 const int cos_size = cos_quadrature.size();
226 const auto &phi_q_p = cos_quadrature.get_points();
227 const auto &phi_q_w = cos_quadrature.get_weights();
228 const int phi_size = cos_quadrature.size();
230 static_assert(d > 1,
"Dimension must be greater than one");
232 const double S_d = 2. * std::pow(M_PI, d / 2.) / std::tgamma(d / 2.);
233 const double S_4 = 2. * std::pow(M_PI, 4. / 2.) / std::tgamma(4. / 2.);
235 const double prefactor =
S_d
236 *
powr<-d>(2. * M_PI);
238 const NT result = tbb::parallel_reduce(
239 tbb::blocked_range3d<int>(0, x_size, 0, cos_size, 0, cos_size), NT(0),
240 [&](
const tbb::blocked_range3d<int> &r, NT running_total) -> NT {
241 for (
int x_it = r.pages().begin(); x_it < r.pages().end(); x_it++) {
242 const double x = x_q_p[x_it][0] * x_extent;
243 const double x_weight = x_q_w[x_it] * x_extent;
244 const double q2 = x *
powr<2>(k);
246 for (
int cos1_it = r.rows().begin(); cos1_it < r.rows().end(); cos1_it++) {
247 const double cos1 = (cos_q_p[cos1_it][0] - 0.5) * 2.;
248 const double cos1_weight =
249 cos_q_w[cos1_it] * 2. * std::sqrt(1. -
powr<2>(cos1));
251 for (
int cos2_it = r.cols().begin(); cos2_it < r.cols().end(); cos2_it++) {
252 const double cos2 = (cos_q_p[cos2_it][0] - 0.5) * 2.;
253 const double cos2_weight = cos_q_w[cos2_it] * 2.;
255 for (
int phi_it = 0; phi_it < phi_size; phi_it++) {
256 const double phi = phi_q_p[phi_it][0] * 2. * M_PI;
257 const double phi_weight = phi_q_w[phi_it] * 2. * M_PI;
260 x_weight * prefactor *
261 (0.5 *
powr<d>(k) * std::pow(x, (d - 2) / 2.))
266 * fun(q2, cos1, cos2, phi);
271 return running_total;
273 [](
const NT a,
const NT b) {
return a + b; });
297 const double k,
const QGauss<1> &m_quadrature,
const double m_extent)
299 const auto &x_q_p = x_quadrature.get_points();
300 const auto &x_q_w = x_quadrature.get_weights();
301 const int x_size = x_quadrature.size();
302 const auto &m_q_p = m_quadrature.get_points();
303 const auto &m_q_w = m_quadrature.get_weights();
304 const int m_size = m_quadrature.size();
306 static_assert(d > 0,
"Dimension must be greater than zero");
308 constexpr int ds = d - 1;
310 const double S_ds = 2. * std::pow(M_PI, ds / 2.) / std::tgamma(ds / 2.);
312 const double prefactor = S_ds
313 *
powr<-ds>(2. * M_PI);
315 const NT result = tbb::parallel_reduce(
316 tbb::blocked_range2d<int>(0, x_size, 0, m_size), NT(0),
317 [&](
const tbb::blocked_range2d<int> &r, NT running_total) -> NT {
318 for (
int x_it = r.rows().begin(); x_it < r.rows().end(); x_it++) {
319 const double x = x_q_p[x_it][0] * x_extent;
320 const double x_weight = x_q_w[x_it] * x_extent;
321 const double q2 = x *
powr<2>(k);
324 for (
int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
325 const double q0 = m_q_p[q0_it][0] * m_extent;
326 const double m_weight = m_q_w[q0_it] * m_extent;
328 running_total += (m_weight / (2. * M_PI))
329 * x_weight * prefactor *
330 (0.5 *
powr<ds>(k) * std::pow(x, (ds - 2) / 2.))
331 * (fun(q2, q0) + fun(q2, -q0));
334 return running_total;
336 [](
const NT a,
const NT b) {
return a + b; });
361 const double k,
const QGauss<1> &cos_quadrature,
362 const QGauss<1> &m_quadrature,
const double m_extent)
364 const auto &x_q_p = x_quadrature.get_points();
365 const auto &x_q_w = x_quadrature.get_weights();
366 const int x_size = x_quadrature.size();
367 const auto &cos_q_p = cos_quadrature.get_points();
368 const auto &cos_q_w = cos_quadrature.get_weights();
369 const int cos_size = cos_quadrature.size();
370 const auto &m_q_p = m_quadrature.get_points();
371 const auto &m_q_w = m_quadrature.get_weights();
372 const int m_size = m_quadrature.size();
374 static_assert(d > 0,
"Dimension must be greater than zero");
376 constexpr int ds = d - 1;
378 const double S_ds = 2. * std::pow(M_PI, ds / 2.) / std::tgamma(ds / 2.);
380 const double prefactor = S_ds
381 *
powr<-ds>(2. * M_PI);
383 const NT result = tbb::parallel_reduce(
384 tbb::blocked_range3d<int>(0, x_size, 0, cos_size, 0, m_size), NT(0),
385 [&](
const tbb::blocked_range3d<int> &r, NT running_total) -> NT {
386 for (
int x_it = r.pages().begin(); x_it < r.pages().end(); x_it++) {
387 const double x = x_q_p[x_it][0] * x_extent;
388 const double x_weight = x_q_w[x_it] * x_extent;
389 const double q2 = x *
powr<2>(k);
391 for (
int cos_it = r.rows().begin(); cos_it < r.rows().end(); cos_it++) {
392 const double cos = (cos_q_p[cos_it][0] - 0.5) * 2.;
393 const double cos_weight = cos_q_w[cos_it] * 2.;
396 for (
int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
397 const double q0 = m_q_p[q0_it][0] * m_extent;
398 const double m_weight = m_q_w[q0_it] * m_extent;
401 (m_weight / (2. * M_PI))
402 * x_weight * prefactor *
403 (0.5 *
powr<ds>(k) * std::pow(x, (ds - 2) / 2.))
405 * (fun(q2, cos, q0) + fun(q2, cos, -q0));
409 return running_total;
411 [](
const NT a,
const NT b) {
return a + b; });
437 const int m_order,
const QGauss<1> &m_quadrature,
const double m_extent,
443 const auto &x_q_p = x_quadrature.get_points();
444 const auto &x_q_w = x_quadrature.get_weights();
445 const int x_size = x_quadrature.size();
446 const auto &m_q_p = m_quadrature.get_points();
447 const auto &m_q_w = m_quadrature.get_weights();
448 const int m_size = m_quadrature.size();
450 static_assert(d > 0,
"Dimension must be greater than zero");
452 constexpr int ds = d - 1;
454 const double S_ds = 2. * std::pow(M_PI, ds / 2.) / std::tgamma(ds / 2.);
456 const double prefactor = S_ds
457 *
powr<-ds>(2. * M_PI);
460 const NT result_sum = tbb::parallel_reduce(
461 tbb::blocked_range2d<int>(0, x_size, -m_order, m_order + 1), NT(0),
462 [&](
const tbb::blocked_range2d<int> &r, NT running_total) -> NT {
463 for (
int x_it = r.rows().begin(); x_it < r.rows().end(); x_it++) {
464 const double x = x_q_p[x_it][0] * x_extent;
465 const double x_weight = x_q_w[x_it] * x_extent;
466 const double q2 = x *
powr<2>(k);
468 for (
int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
469 const double q0 = 2. * M_PI * T * q0_it;
472 * x_weight * prefactor *
473 (0.5 *
powr<ds>(k) * std::pow(x, (ds - 2) / 2.))
477 return running_total;
479 [](
const NT a,
const NT b) {
return a + b; });
482 const NT result_integral = tbb::parallel_reduce(
483 tbb::blocked_range2d<int>(0, x_size, 0, m_size), NT(0),
484 [&](
const tbb::blocked_range2d<int> &r, NT running_total) -> NT {
485 for (
int x_it = r.rows().begin(); x_it < r.rows().end(); x_it++) {
486 const double x = x_q_p[x_it][0] * x_extent;
487 const double x_weight = x_q_w[x_it] * x_extent;
488 const double q2 = x *
powr<2>(k);
490 for (
int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
492 (2. * m_order * M_PI * T) + m_q_p[q0_it][0] * (m_extent - 2. * (m_order + 1) * M_PI * T);
493 const double m_weight = m_q_w[q0_it] * (m_extent - 2. * m_order * M_PI * T);
495 running_total += (1. * m_weight / (2. * M_PI))
496 * x_weight * prefactor *
497 (0.5 *
powr<ds>(k) * std::pow(x, (ds - 2) / 2.))
498 * (fun(q2, q0) + fun(q2, -q0));
501 return running_total;
503 [](
const NT a,
const NT b) {
return a + b; });
504 return result_sum + result_integral;
530 const double k,
const QGauss<1> &cos_quadrature,
const int m_order,
531 const QGauss<1> &m_quadrature,
const double m_extent,
const double T)
535 m_quadrature, m_extent);
537 const auto &x_q_p = x_quadrature.get_points();
538 const auto &x_q_w = x_quadrature.get_weights();
539 const int x_size = x_quadrature.size();
540 const auto &cos_q_p = cos_quadrature.get_points();
541 const auto &cos_q_w = cos_quadrature.get_weights();
542 const int cos_size = cos_quadrature.size();
543 const auto &m_q_p = m_quadrature.get_points();
544 const auto &m_q_w = m_quadrature.get_weights();
545 const int m_size = m_quadrature.size();
547 static_assert(d > 0,
"Dimension must be greater than zero");
549 constexpr int ds = d - 1;
551 const double S_ds = 2. * std::pow(M_PI, ds / 2.) / std::tgamma(ds / 2.);
553 const double prefactor = S_ds
554 *
powr<-ds>(2. * M_PI);
557 const NT result_sum = tbb::parallel_reduce(
558 tbb::blocked_range3d<int>(0, x_size, 0, cos_size, -m_order, m_order + 1), NT(0),
559 [&](
const tbb::blocked_range3d<int> &r, NT running_total) -> NT {
560 for (
int x_it = r.pages().begin(); x_it < r.pages().end(); x_it++) {
561 const double x = x_q_p[x_it][0] * x_extent;
562 const double x_weight = x_q_w[x_it] * x_extent;
563 const double q2 = x *
powr<2>(k);
565 for (
int cos_it = r.rows().begin(); cos_it < r.rows().end(); cos_it++) {
566 const double cos = (cos_q_p[cos_it][0] - 0.5) * 2.;
567 const double cos_weight = cos_q_w[cos_it] * 2.;
569 for (
int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
570 const double q0 = 2. * M_PI * T * q0_it;
574 * x_weight * prefactor *
575 (0.5 *
powr<ds>(k) * std::pow(x, (ds - 2) / 2.))
581 return running_total;
583 [](
const NT a,
const NT b) {
return a + b; });
586 const NT result_integral = tbb::parallel_reduce(
587 tbb::blocked_range3d<int>(0, x_size, 0, cos_size, 0, m_size), NT(0),
588 [&](
const tbb::blocked_range3d<int> &r, NT running_total) -> NT {
589 for (
int x_it = r.pages().begin(); x_it < r.pages().end(); x_it++) {
590 const double x = x_q_p[x_it][0] * x_extent;
591 const double x_weight = x_q_w[x_it] * x_extent;
592 const double q2 = x *
powr<2>(k);
594 for (
int cos_it = r.rows().begin(); cos_it < r.rows().end(); cos_it++) {
595 const double cos = (cos_q_p[cos_it][0] - 0.5) * 2.;
596 const double cos_weight = cos_q_w[cos_it] * 2.;
598 for (
int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
600 (2. * m_order * M_PI * T) + m_q_p[q0_it][0] * (m_extent - 2. * (m_order + 1) * M_PI * T);
601 const double m_weight = m_q_w[q0_it] * (m_extent - 2. * m_order * M_PI * T);
604 (1. * m_weight / (2. * M_PI))
605 * x_weight * prefactor *
606 (0.5 *
powr<ds>(k) * std::pow(x, (ds - 2) / 2.))
608 * (fun(q2, cos, q0) + fun(q2, cos, -q0));
612 return running_total;
614 [](
const NT a,
const NT b) {
return a + b; });
615 return result_sum + result_integral;
619 NT
sum(
const FUN &fun,
const int m_order,
const QGauss<1> &m_quadrature,
const double m_extent,
const double T)
621 const auto &m_q_p = m_quadrature.get_points();
622 const auto &m_q_w = m_quadrature.get_weights();
623 const int m_size = m_quadrature.size();
626 const NT result_sum =
is_close(T, 0.) ? 0.
627 : tbb::parallel_reduce(
628 tbb::blocked_range<int>(-m_order, m_order + 1), NT(0),
629 [&](
const tbb::blocked_range<int> &r, NT running_total) -> NT {
630 for (
int q0_it = r.begin(); q0_it < r.end(); q0_it++) {
631 const double q0 = 2. * M_PI * T * q0_it;
632 running_total += T * fun(q0);
634 return running_total;
636 [](
const NT a,
const NT b) {
return a + b; });
639 const NT result_integral = tbb::parallel_reduce(
640 tbb::blocked_range<int>(0, m_size), NT(0),
641 [&](
const tbb::blocked_range<int> &r, NT running_total) -> NT {
642 for (
int q0_it = r.begin(); q0_it < r.end(); q0_it++) {
644 (2. * m_order * M_PI * T) + m_q_p[q0_it][0] * (m_extent - 2. * (m_order + 1) * M_PI * T);
645 const double m_weight = m_q_w[q0_it] * (m_extent - 2. * m_order * M_PI * T);
647 running_total += (1. * m_weight / (2. * M_PI))
648 * (fun(q0) + fun(-q0));
650 return running_total;
652 [](
const NT a,
const NT b) {
return a + b; });
654 return result_sum + result_integral;