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 const double q_max = std::sqrt(x_extent) * k;
52 for (
int x_it = r.begin(); x_it < r.end(); x_it++) {
53 const double q = x_q_p[x_it][0] * q_max;
54 const double q_weight = x_q_w[x_it] * q_max;
57 running_total += q_weight * prefactor * std::pow(q, d - 1)
62 [](
const NT a,
const NT b) {
return a + b; });
83 NT
angle_integrate(
const FUN &fun,
const QGauss<1> &x_quadrature,
const double x_extent,
const double k,
84 const QGauss<1> &cos_quadrature)
86 static_assert(d > 1,
"Dimension must be greater than one, otherwise the angular integral not defined.");
88 const auto &x_q_p = x_quadrature.get_points();
89 const auto &x_q_w = x_quadrature.get_weights();
90 const int x_size = x_quadrature.size();
91 const auto &cos_q_p = cos_quadrature.get_points();
92 const auto &cos_q_w = cos_quadrature.get_weights();
93 const int cos_size = cos_quadrature.size();
95 static_assert(d > 1,
"Dimension must be greater than one");
97 const double S_d = 2. * std::pow(M_PI, d / 2.) / std::tgamma(d / 2.);
99 const double prefactor =
S_d
100 * powr<-d>(2. * M_PI);
102 const NT result = tbb::parallel_reduce(
103 tbb::blocked_range2d<int>(0, x_size, 0, cos_size), NT(0),
104 [&](
const tbb::blocked_range2d<int> &r, NT running_total) -> NT {
105 const double q_max = std::sqrt(x_extent) * k;
106 for (
int x_it = r.rows().begin(); x_it < r.rows().end(); x_it++) {
107 const double q = x_q_p[x_it][0] * q_max;
108 const double q_weight = x_q_w[x_it] * q_max;
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 q_weight * prefactor * std::pow(q, d - 1)
121 return running_total;
123 [](
const NT a,
const NT b) {
return a + b; });
144 NT
two_angle_integrate(
const FUN &fun,
const QGauss<1> &x_quadrature,
const double x_extent,
const double k,
145 const QGauss<1> &cos_quadrature)
147 static_assert(d > 2,
"Dimension must be greater than 2, otherwise the angular integral not defined.");
149 const auto &x_q_p = x_quadrature.get_points();
150 const auto &x_q_w = x_quadrature.get_weights();
151 const int x_size = x_quadrature.size();
152 const auto &cos_q_p = cos_quadrature.get_points();
153 const auto &cos_q_w = cos_quadrature.get_weights();
154 const int cos_size = cos_quadrature.size();
155 const auto &phi_q_p = cos_quadrature.get_points();
156 const auto &phi_q_w = cos_quadrature.get_weights();
157 const int phi_size = cos_quadrature.size();
159 static_assert(d > 1,
"Dimension must be greater than one");
161 const double S_d = 2. * std::pow(M_PI, d / 2.) / std::tgamma(d / 2.);
163 const double prefactor =
S_d
164 * powr<-d>(2. * M_PI);
166 const NT result = tbb::parallel_reduce(
167 tbb::blocked_range3d<int>(0, x_size, 0, cos_size, 0, phi_size), NT(0),
168 [&](
const tbb::blocked_range3d<int> &r, NT running_total) -> NT {
169 const double q_max = std::sqrt(x_extent) * k;
170 for (
int x_it = r.pages().begin(); x_it < r.pages().end(); x_it++) {
171 const double q = x_q_p[x_it][0] * q_max;
172 const double q_weight = x_q_w[x_it] * q_max;
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 = phi_q_w[cos_it] * 2. * M_PI;
184 q_weight * prefactor * std::pow(q, d - 1)
186 * phi_weight / (2. * M_PI)
191 return running_total;
193 [](
const NT a,
const NT b) {
return a + b; });
215 const QGauss<1> &cos_quadrature)
217 static_assert(d > 3,
"Dimension must be greater than 3, otherwise the angular integral not defined.");
219 const auto &x_q_p = x_quadrature.get_points();
220 const auto &x_q_w = x_quadrature.get_weights();
221 const int x_size = x_quadrature.size();
222 const auto &cos_q_p = cos_quadrature.get_points();
223 const auto &cos_q_w = cos_quadrature.get_weights();
224 const int cos_size = cos_quadrature.size();
225 const auto &phi_q_p = cos_quadrature.get_points();
226 const auto &phi_q_w = cos_quadrature.get_weights();
227 const int phi_size = cos_quadrature.size();
229 static_assert(d > 1,
"Dimension must be greater than one");
231 const double S_d = 2. * std::pow(M_PI, d / 2.) / std::tgamma(d / 2.);
232 const double S_4 = 2. * std::pow(M_PI, 4. / 2.) / std::tgamma(4. / 2.);
234 const double prefactor =
S_d
235 * powr<-d>(2. * M_PI);
237 const NT result = tbb::parallel_reduce(
238 tbb::blocked_range3d<int>(0, x_size, 0, cos_size, 0, cos_size), NT(0),
239 [&](
const tbb::blocked_range3d<int> &r, NT running_total) -> NT {
240 const double q_max = std::sqrt(x_extent) * k;
241 for (
int x_it = r.pages().begin(); x_it < r.pages().end(); x_it++) {
242 const double q = x_q_p[x_it][0] * q_max;
243 const double q_weight = x_q_w[x_it] * q_max;
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;
259 running_total += q_weight * prefactor * std::pow(q, d - 1)
264 * fun(q2, cos1, cos2, phi);
269 return running_total;
271 [](
const NT a,
const NT b) {
return a + b; });
295 const double k,
const QGauss<1> &m_quadrature,
const double m_extent)
297 const auto &x_q_p = x_quadrature.get_points();
298 const auto &x_q_w = x_quadrature.get_weights();
299 const int x_size = x_quadrature.size();
300 const auto &m_q_p = m_quadrature.get_points();
301 const auto &m_q_w = m_quadrature.get_weights();
302 const int m_size = m_quadrature.size();
304 static_assert(d > 0,
"Dimension must be greater than zero");
306 constexpr int ds = d - 1;
308 const double S_ds = 2. * std::pow(M_PI, ds / 2.) / std::tgamma(ds / 2.);
310 const double prefactor = S_ds
311 * powr<-ds>(2. * M_PI);
313 const NT result = tbb::parallel_reduce(
314 tbb::blocked_range2d<int>(0, x_size, 0, m_size), NT(0),
315 [&](
const tbb::blocked_range2d<int> &r, NT running_total) -> NT {
316 const double q_max = std::sqrt(x_extent) * k;
317 for (
int x_it = r.rows().begin(); x_it < r.rows().end(); x_it++) {
318 const double q = x_q_p[x_it][0] * q_max;
319 const double q_weight = x_q_w[x_it] * q_max;
323 for (
int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
324 const double q0 = m_q_p[q0_it][0] * m_extent;
325 const double m_weight = m_q_w[q0_it] * m_extent;
327 running_total += (m_weight / (2. * M_PI))
328 * q_weight * prefactor * std::pow(q, ds - 1)
329 * (fun(q2, q0) + fun(q2, -q0));
332 return running_total;
334 [](
const NT a,
const NT b) {
return a + b; });
359 const double k,
const QGauss<1> &cos_quadrature,
360 const QGauss<1> &m_quadrature,
const double m_extent)
362 const auto &x_q_p = x_quadrature.get_points();
363 const auto &x_q_w = x_quadrature.get_weights();
364 const int x_size = x_quadrature.size();
365 const auto &cos_q_p = cos_quadrature.get_points();
366 const auto &cos_q_w = cos_quadrature.get_weights();
367 const int cos_size = cos_quadrature.size();
368 const auto &m_q_p = m_quadrature.get_points();
369 const auto &m_q_w = m_quadrature.get_weights();
370 const int m_size = m_quadrature.size();
372 static_assert(d > 0,
"Dimension must be greater than zero");
374 constexpr int ds = d - 1;
376 const double S_ds = 2. * std::pow(M_PI, ds / 2.) / std::tgamma(ds / 2.);
378 const double prefactor = S_ds
379 * powr<-ds>(2. * M_PI);
381 const NT result = tbb::parallel_reduce(
382 tbb::blocked_range3d<int>(0, x_size, 0, cos_size, 0, m_size), NT(0),
383 [&](
const tbb::blocked_range3d<int> &r, NT running_total) -> NT {
384 const double q_max = std::sqrt(x_extent) * k;
385 for (
int x_it = r.pages().begin(); x_it < r.pages().end(); x_it++) {
386 const double q = x_q_p[x_it][0] * q_max;
387 const double q_weight = x_q_w[x_it] * q_max;
390 for (
int cos_it = r.rows().begin(); cos_it < r.rows().end(); cos_it++) {
391 const double cos = (cos_q_p[cos_it][0] - 0.5) * 2.;
392 const double cos_weight = cos_q_w[cos_it] * 2.;
395 for (
int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
396 const double q0 = m_q_p[q0_it][0] * m_extent;
397 const double m_weight = m_q_w[q0_it] * m_extent;
400 (m_weight / (2. * M_PI))
401 * q_weight * prefactor * std::pow(q, ds - 1)
403 * (fun(q2, cos, q0) + fun(q2, cos, -q0));
407 return running_total;
409 [](
const NT a,
const NT b) {
return a + b; });
435 const int m_order,
const QGauss<1> &m_quadrature,
const double m_extent,
441 const auto &x_q_p = x_quadrature.get_points();
442 const auto &x_q_w = x_quadrature.get_weights();
443 const int x_size = x_quadrature.size();
444 const auto &m_q_p = m_quadrature.get_points();
445 const auto &m_q_w = m_quadrature.get_weights();
446 const int m_size = m_quadrature.size();
448 static_assert(d > 0,
"Dimension must be greater than zero");
450 constexpr int ds = d - 1;
452 const double S_ds = 2. * std::pow(M_PI, ds / 2.) / std::tgamma(ds / 2.);
454 const double prefactor = S_ds
455 * powr<-ds>(2. * M_PI);
458 const NT result_sum = tbb::parallel_reduce(
459 tbb::blocked_range2d<int>(0, x_size, -m_order, m_order + 1), NT(0),
460 [&](
const tbb::blocked_range2d<int> &r, NT running_total) -> NT {
461 const double q_max = std::sqrt(x_extent) * k;
462 for (
int x_it = r.rows().begin(); x_it < r.rows().end(); x_it++) {
463 const double q = x_q_p[x_it][0] * q_max;
464 const double q_weight = x_q_w[x_it] * q_max;
467 for (
int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
468 const double q0 = 2. * M_PI * T * q0_it;
471 * q_weight * prefactor * std::pow(q, ds - 1)
475 return running_total;
477 [](
const NT a,
const NT b) {
return a + b; });
480 const NT result_integral = tbb::parallel_reduce(
481 tbb::blocked_range2d<int>(0, x_size, 0, m_size), NT(0),
482 [&](
const tbb::blocked_range2d<int> &r, NT running_total) -> NT {
483 const double q_max = std::sqrt(x_extent) * k;
484 for (
int x_it = r.rows().begin(); x_it < r.rows().end(); x_it++) {
485 const double q = x_q_p[x_it][0] * q_max;
486 const double q_weight = x_q_w[x_it] * q_max;
489 for (
int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
491 (2. * m_order * M_PI * T) + m_q_p[q0_it][0] * (m_extent - 2. * (m_order + 1) * M_PI * T);
492 const double m_weight = m_q_w[q0_it] * (m_extent - 2. * m_order * M_PI * T);
494 running_total += (1. * m_weight / (2. * M_PI))
495 * q_weight * prefactor * std::pow(q, ds - 1)
496 * (fun(q2, q0) + fun(q2, -q0));
499 return running_total;
501 [](
const NT a,
const NT b) {
return a + b; });
502 return result_sum + result_integral;
528 const double k,
const QGauss<1> &cos_quadrature,
const int m_order,
529 const QGauss<1> &m_quadrature,
const double m_extent,
const double T)
533 m_quadrature, m_extent);
535 const auto &x_q_p = x_quadrature.get_points();
536 const auto &x_q_w = x_quadrature.get_weights();
537 const int x_size = x_quadrature.size();
538 const auto &cos_q_p = cos_quadrature.get_points();
539 const auto &cos_q_w = cos_quadrature.get_weights();
540 const int cos_size = cos_quadrature.size();
541 const auto &m_q_p = m_quadrature.get_points();
542 const auto &m_q_w = m_quadrature.get_weights();
543 const int m_size = m_quadrature.size();
545 static_assert(d > 0,
"Dimension must be greater than zero");
547 constexpr int ds = d - 1;
549 const double S_ds = 2. * std::pow(M_PI, ds / 2.) / std::tgamma(ds / 2.);
551 const double prefactor = S_ds
552 * powr<-ds>(2. * M_PI);
555 const NT result_sum = tbb::parallel_reduce(
556 tbb::blocked_range3d<int>(0, x_size, 0, cos_size, -m_order, m_order + 1), NT(0),
557 [&](
const tbb::blocked_range3d<int> &r, NT running_total) -> NT {
558 const double q_max = std::sqrt(x_extent) * k;
559 for (
int x_it = r.pages().begin(); x_it < r.pages().end(); x_it++) {
560 const double q = x_q_p[x_it][0] * q_max;
561 const double q_weight = x_q_w[x_it] * q_max;
564 for (
int cos_it = r.rows().begin(); cos_it < r.rows().end(); cos_it++) {
565 const double cos = (cos_q_p[cos_it][0] - 0.5) * 2.;
566 const double cos_weight = cos_q_w[cos_it] * 2.;
568 for (
int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
569 const double q0 = 2. * M_PI * T * q0_it;
573 * q_weight * prefactor * std::pow(q, ds - 1)
579 return running_total;
581 [](
const NT a,
const NT b) {
return a + b; });
584 const NT result_integral = tbb::parallel_reduce(
585 tbb::blocked_range3d<int>(0, x_size, 0, cos_size, 0, m_size), NT(0),
586 [&](
const tbb::blocked_range3d<int> &r, NT running_total) -> NT {
587 const double q_max = std::sqrt(x_extent) * k;
588 for (
int x_it = r.pages().begin(); x_it < r.pages().end(); x_it++) {
589 const double q = x_q_p[x_it][0] * q_max;
590 const double q_weight = x_q_w[x_it] * q_max;
593 for (
int cos_it = r.rows().begin(); cos_it < r.rows().end(); cos_it++) {
594 const double cos = (cos_q_p[cos_it][0] - 0.5) * 2.;
595 const double cos_weight = cos_q_w[cos_it] * 2.;
597 for (
int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
599 (2. * m_order * M_PI * T) + m_q_p[q0_it][0] * (m_extent - 2. * (m_order + 1) * M_PI * T);
600 const double m_weight = m_q_w[q0_it] * (m_extent - 2. * m_order * M_PI * T);
603 (1. * m_weight / (2. * M_PI))
604 * q_weight * prefactor * std::pow(q, ds - 1)
606 * (fun(q2, cos, q0) + fun(q2, cos, -q0));
610 return running_total;
612 [](
const NT a,
const NT b) {
return a + b; });
613 return result_sum + result_integral;
617 NT
sum(
const FUN &fun,
const int m_order,
const QGauss<1> &m_quadrature,
const double m_extent,
const double T)
619 const auto &m_q_p = m_quadrature.get_points();
620 const auto &m_q_w = m_quadrature.get_weights();
621 const int m_size = m_quadrature.size();
624 const NT result_sum =
is_close(T, 0.) ? 0.
625 : tbb::parallel_reduce(
626 tbb::blocked_range<int>(-m_order, m_order + 1), NT(0),
627 [&](
const tbb::blocked_range<int> &r, NT running_total) -> NT {
628 for (
int q0_it = r.begin(); q0_it < r.end(); q0_it++) {
629 const double q0 = 2. * M_PI * T * q0_it;
630 running_total += T * fun(q0);
632 return running_total;
634 [](
const NT a,
const NT b) {
return a + b; });
637 const NT result_integral = tbb::parallel_reduce(
638 tbb::blocked_range<int>(0, m_size), NT(0),
639 [&](
const tbb::blocked_range<int> &r, NT running_total) -> NT {
640 for (
int q0_it = r.begin(); q0_it < r.end(); q0_it++) {
642 (2. * m_order * M_PI * T) + m_q_p[q0_it][0] * (m_extent - 2. * (m_order + 1) * M_PI * T);
643 const double m_weight = m_q_w[q0_it] * (m_extent - 2. * m_order * M_PI * T);
645 running_total += (1. * m_weight / (2. * M_PI))
646 * (fun(q0) + fun(-q0));
648 return running_total;
650 [](
const NT a,
const NT b) {
return a + b; });
652 return result_sum + result_integral;