/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/physics/loop_integrals.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/physics/loop_integrals.hh Source File
DiFfRG
loop_integrals.hh
Go to the documentation of this file.
1#pragma once
2
3// standard library
4#include <cmath>
5
6// external libraries
7#include <deal.II/base/quadrature_lib.h>
8#include <tbb/tbb.h>
9
10// DiFfRG
12
13namespace DiFfRG
14{
15 using namespace dealii;
16
17 namespace LoopIntegrals
18 {
34 template <typename NT, int d, typename FUN>
35 NT integrate(const FUN &fun, const QGauss<1> &x_quadrature, const double x_extent, const double k)
36 {
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();
40
41 static_assert(d > 0, "Dimension must be greater than zero");
42 // Dimension of the spatial integral
43 const double S_d = 2. * std::pow(M_PI, d / 2.) / std::tgammal(d / 2.);
44 // Prefactor for the spatial integral
45 const double prefactor = S_d // angular integral
46 * powr<-d>(2. * M_PI); // fourier factors
47
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;
55 const double q2 = powr<2>(q);
56
57 running_total += q_weight * prefactor * std::pow(q, d - 1) // integral over q in d dimensions
58 * fun(q2); // integrand
59 }
60 return running_total;
61 },
62 [](const NT a, const NT b) { return a + b; });
63 return result;
64 }
65
82 template <typename NT, int d, typename FUN>
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)
85 {
86 static_assert(d > 1, "Dimension must be greater than one, otherwise the angular integral not defined.");
87
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();
94
95 static_assert(d > 1, "Dimension must be greater than one");
96 // Area of unit sphere in d dimensions
97 const double S_d = 2. * std::pow(M_PI, d / 2.) / std::tgamma(d / 2.);
98 // Prefactor for the spatial integral
99 const double prefactor = S_d // angular integral
100 * powr<-d>(2. * M_PI); // fourier factors
101
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;
109 const double q2 = powr<2>(q);
110
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.;
114
115 running_total +=
116 q_weight * prefactor * std::pow(q, d - 1) // integral over q in d dimensions
117 * 0.5 * cos_weight // integral over cos(theta), 0.5 removes the factor from the angular integral
118 * fun(q2, cos); // integrand
119 }
120 }
121 return running_total;
122 },
123 [](const NT a, const NT b) { return a + b; });
124 return result;
125 }
126
143 template <typename NT, int d, typename FUN>
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)
146 {
147 static_assert(d > 2, "Dimension must be greater than 2, otherwise the angular integral not defined.");
148
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();
158
159 static_assert(d > 1, "Dimension must be greater than one");
160 // Area of unit sphere in d dimensions
161 const double S_d = 2. * std::pow(M_PI, d / 2.) / std::tgamma(d / 2.);
162 // Prefactor for the spatial integral
163 const double prefactor = S_d // angular integral
164 * powr<-d>(2. * M_PI); // fourier factors
165
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;
173 const double q2 = powr<2>(q);
174
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.;
178
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;
182
183 running_total +=
184 q_weight * prefactor * std::pow(q, d - 1) // integral over q in d dimensions
185 * 0.5 * cos_weight // integral over cos(theta), 0.5 removes the factor from the angular integral
186 * phi_weight / (2. * M_PI) // integral over phi, 2pi removes the factor from the angular integral
187 * fun(q2, cos, phi); // integrand
188 }
189 }
190 }
191 return running_total;
192 },
193 [](const NT a, const NT b) { return a + b; });
194 return result;
195 }
196
213 template <typename NT, int d, typename FUN>
214 NT three_angle_integrate(const FUN &fun, const QGauss<1> &x_quadrature, const double x_extent, const double k,
215 const QGauss<1> &cos_quadrature)
216 {
217 static_assert(d > 3, "Dimension must be greater than 3, otherwise the angular integral not defined.");
218
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();
228
229 static_assert(d > 1, "Dimension must be greater than one");
230 // Area of unit sphere in d dimensions
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.);
233 // Prefactor for the spatial integral
234 const double prefactor = S_d // angular integral
235 * powr<-d>(2. * M_PI); // fourier factors
236
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;
244 const double q2 = powr<2>(q);
245
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)); // integration jacobian
250
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.;
254
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;
258
259 running_total += q_weight * prefactor * std::pow(q, d - 1) // integral over q in d dimensions
260 * cos1_weight // integral over cos(theta1)
261 * cos2_weight // integral over cos(theta2)
262 * phi_weight /
263 S_4 // integral over phi, S_3 = 2 pi^2 removes the factor from the angular integral
264 * fun(q2, cos1, cos2, phi); // integrand
265 }
266 }
267 }
268 }
269 return running_total;
270 },
271 [](const NT a, const NT b) { return a + b; });
272 return result;
273 }
274
293 template <typename NT, int d, typename FUN>
294 NT spatial_integrate_and_integrate(const FUN &fun, const QGauss<1> &x_quadrature, const double x_extent,
295 const double k, const QGauss<1> &m_quadrature, const double m_extent)
296 {
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();
303
304 static_assert(d > 0, "Dimension must be greater than zero");
305 // Dimension of the spatial integral
306 constexpr int ds = d - 1;
307 // Area of unit sphere in ds=d-1 dimensions
308 const double S_ds = 2. * std::pow(M_PI, ds / 2.) / std::tgamma(ds / 2.);
309 // Prefactor for the spatial integral
310 const double prefactor = S_ds // angular integral
311 * powr<-ds>(2. * M_PI); // fourier factors
312
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;
320 const double q2 = powr<2>(q);
321
322 // Do a "matsubara" (rather p0)-integral
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;
326
327 running_total += (m_weight / (2. * M_PI)) // Matsubara integral weight
328 * q_weight * prefactor * std::pow(q, ds - 1) // integral over q
329 * (fun(q2, q0) + fun(q2, -q0)); // integrand
330 }
331 }
332 return running_total;
333 },
334 [](const NT a, const NT b) { return a + b; });
335 return result;
336 }
337
357 template <typename NT, int d, typename FUN>
358 NT spatial_angle_integrate_and_integrate(const FUN &fun, const QGauss<1> &x_quadrature, const double x_extent,
359 const double k, const QGauss<1> &cos_quadrature,
360 const QGauss<1> &m_quadrature, const double m_extent)
361 {
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();
371
372 static_assert(d > 0, "Dimension must be greater than zero");
373 // Dimension of the spatial integral
374 constexpr int ds = d - 1;
375 // Area of unit sphere in ds=d-1 dimensions
376 const double S_ds = 2. * std::pow(M_PI, ds / 2.) / std::tgamma(ds / 2.);
377 // Prefactor for the spatial integral
378 const double prefactor = S_ds // angular integral
379 * powr<-ds>(2. * M_PI); // fourier factors
380
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;
388 const double q2 = powr<2>(q);
389
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.;
393
394 // Do a "matsubara" (rather q0)-integral
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;
398
399 running_total +=
400 (m_weight / (2. * M_PI)) // Matsubara integral weight
401 * q_weight * prefactor * std::pow(q, ds - 1) // integral over q
402 * 0.5 * cos_weight // integral over cos(theta), 0.5 removes the factor from the angular integral
403 * (fun(q2, cos, q0) + fun(q2, cos, -q0)); // integrand
404 }
405 }
406 }
407 return running_total;
408 },
409 [](const NT a, const NT b) { return a + b; });
410 return result;
411 }
412
433 template <typename NT, int d, typename FUN>
434 NT spatial_integrate_and_sum(const FUN &fun, const QGauss<1> &x_quadrature, const double x_extent, const double k,
435 const int m_order, const QGauss<1> &m_quadrature, const double m_extent,
436 const double T)
437 {
438 if (is_close(T, 0.))
439 return spatial_integrate_and_integrate<NT, d, FUN>(fun, x_quadrature, x_extent, k, m_quadrature, m_extent);
440
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();
447
448 static_assert(d > 0, "Dimension must be greater than zero");
449 // Dimension of the spatial integral
450 constexpr int ds = d - 1;
451 // Area of unit sphere in ds=d-1 dimensions
452 const double S_ds = 2. * std::pow(M_PI, ds / 2.) / std::tgamma(ds / 2.);
453 // Prefactor for the spatial integral
454 const double prefactor = S_ds // angular integral
455 * powr<-ds>(2. * M_PI); // fourier factors
456
457 // Do a matsubara sum for the first m_order summands
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;
465 const double q2 = powr<2>(q);
466
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;
469
470 running_total += T // Matsubara sum weight
471 * q_weight * prefactor * std::pow(q, ds - 1) // integral over q
472 * fun(q2, q0); // integrand
473 }
474 }
475 return running_total;
476 },
477 [](const NT a, const NT b) { return a + b; });
478
479 // Approximate the rest of the sum by an integral
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;
487 const double q2 = powr<2>(q);
488
489 for (int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
490 const double q0 =
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);
493
494 running_total += (1. * m_weight / (2. * M_PI)) // Matsubara integral weight
495 * q_weight * prefactor * std::pow(q, ds - 1) // integral over q
496 * (fun(q2, q0) + fun(q2, -q0)); // integrand
497 }
498 }
499 return running_total;
500 },
501 [](const NT a, const NT b) { return a + b; });
502 return result_sum + result_integral;
503 } // namespace LoopIntegrals
504
526 template <typename NT, int d, typename FUN>
527 NT spatial_angle_integrate_and_sum(const FUN &fun, const QGauss<1> &x_quadrature, const double x_extent,
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)
530 {
531 if (is_close(T, 0.))
532 return spatial_angle_integrate_and_integrate<NT, d, FUN>(fun, x_quadrature, x_extent, k, cos_quadrature,
533 m_quadrature, m_extent);
534
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();
544
545 static_assert(d > 0, "Dimension must be greater than zero");
546 // Dimension of the spatial integral
547 constexpr int ds = d - 1;
548 // Area of unit sphere in ds=d-1 dimensions
549 const double S_ds = 2. * std::pow(M_PI, ds / 2.) / std::tgamma(ds / 2.);
550 // Prefactor for the spatial integral
551 const double prefactor = S_ds // angular integral
552 * powr<-ds>(2. * M_PI); // fourier factors
553
554 // Do a matsubara sum for the first m_order summands
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;
562 const double q2 = powr<2>(q);
563
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.;
567
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;
570
571 running_total +=
572 T // Matsubara sum weight
573 * q_weight * prefactor * std::pow(q, ds - 1) // integral over q
574 * 0.5 * cos_weight // integral over cos(theta), 0.5 removes the factor from the angular integral
575 * fun(q2, cos, q0); // integrand
576 }
577 }
578 }
579 return running_total;
580 },
581 [](const NT a, const NT b) { return a + b; });
582
583 // Approximate the rest of the sum by an integral
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;
591 const double q2 = powr<2>(q);
592
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.;
596
597 for (int q0_it = r.cols().begin(); q0_it < r.cols().end(); q0_it++) {
598 const double q0 =
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);
601
602 running_total +=
603 (1. * m_weight / (2. * M_PI)) // Matsubara integral weight
604 * q_weight * prefactor * std::pow(q, ds - 1) // integral over q
605 * 0.5 * cos_weight // integral over cos(theta), 0.5 removes the factor from the angular integral
606 * (fun(q2, cos, q0) + fun(q2, cos, -q0)); // integrand
607 }
608 }
609 }
610 return running_total;
611 },
612 [](const NT a, const NT b) { return a + b; });
613 return result_sum + result_integral;
614 }
615
616 template <typename NT, typename FUN>
617 NT sum(const FUN &fun, const int m_order, const QGauss<1> &m_quadrature, const double m_extent, const double T)
618 {
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();
622
623 // Do a matsubara sum for the first m_order summands
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);
631 }
632 return running_total;
633 },
634 [](const NT a, const NT b) { return a + b; });
635
636 // Approximate the rest of the sum by an integral
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++) {
641 const double q0 =
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);
644
645 running_total += (1. * m_weight / (2. * M_PI)) // Matsubara integral weight
646 * (fun(q0) + fun(-q0)); // integrand
647 }
648 return running_total;
649 },
650 [](const NT a, const NT b) { return a + b; });
651
652 return result_sum + result_integral;
653 }
654 } // namespace LoopIntegrals
655} // namespace DiFfRG
NT spatial_angle_integrate_and_sum(const FUN &fun, const QGauss< 1 > &x_quadrature, const double x_extent, const double k, const QGauss< 1 > &cos_quadrature, const int m_order, const QGauss< 1 > &m_quadrature, const double m_extent, const double T)
Performs the integral.
Definition loop_integrals.hh:527
NT two_angle_integrate(const FUN &fun, const QGauss< 1 > &x_quadrature, const double x_extent, const double k, const QGauss< 1 > &cos_quadrature)
Performs the integral.
Definition loop_integrals.hh:144
NT spatial_integrate_and_integrate(const FUN &fun, const QGauss< 1 > &x_quadrature, const double x_extent, const double k, const QGauss< 1 > &m_quadrature, const double m_extent)
Performs the integral.
Definition loop_integrals.hh:294
NT spatial_angle_integrate_and_integrate(const FUN &fun, const QGauss< 1 > &x_quadrature, const double x_extent, const double k, const QGauss< 1 > &cos_quadrature, const QGauss< 1 > &m_quadrature, const double m_extent)
Performs the integral.
Definition loop_integrals.hh:358
NT angle_integrate(const FUN &fun, const QGauss< 1 > &x_quadrature, const double x_extent, const double k, const QGauss< 1 > &cos_quadrature)
Performs the integral.
Definition loop_integrals.hh:83
NT three_angle_integrate(const FUN &fun, const QGauss< 1 > &x_quadrature, const double x_extent, const double k, const QGauss< 1 > &cos_quadrature)
Performs the integral.
Definition loop_integrals.hh:214
NT integrate(const FUN &fun, const QGauss< 1 > &x_quadrature, const double x_extent, const double k)
Performs the integral.
Definition loop_integrals.hh:35
NT sum(const FUN &fun, const int m_order, const QGauss< 1 > &m_quadrature, const double m_extent, const double T)
Definition loop_integrals.hh:617
NT spatial_integrate_and_sum(const FUN &fun, const QGauss< 1 > &x_quadrature, const double x_extent, const double k, const int m_order, const QGauss< 1 > &m_quadrature, const double m_extent, const double T)
Performs the integral.
Definition loop_integrals.hh:434
Definition complex_math.hh:10
constexpr KOKKOS_INLINE_FUNCTION double S_d(NT d)
Surface of a d-dimensional sphere.
Definition math.hh:99
bool KOKKOS_INLINE_FUNCTION is_close(T1 a, T2 b, T3 eps_)
Function to evaluate whether two floats are equal to numerical precision. Tests for both relative and...
Definition math.hh:168
constexpr KOKKOS_INLINE_FUNCTION NumberType powr(const NumberType x)
A compile-time evaluatable power function for whole number exponents.
Definition math.hh:41