1 #ifndef CNTR_DYSON_OMP_IMPL_H 2 #define CNTR_DYSON_OMP_IMPL_H 36 template <
typename T,
class GG,
int SIZE1>
37 void dyson_timestep_ret_omp(
int omp_num_threads,
int n, GG &G, T mu, std::complex<T> *H,
39 typedef std::complex<T>
cplx;
40 int k =
I.get_k(), k1 = k + 1;
42 int size1 = G.size1();
43 int sg = G.element_size();
46 assert(n<= Sigma.nt());
48 assert(G.sig()== Sigma.sig());
53 cplx *gret = G.retptr(n, 0);
54 int n1 = (n + 1) * sg, i;
55 for (i = 0; i < n1; i++)
60 element_set<T, SIZE1>(size1, G.retptr(n, n), -cplx_i);
77 element_set<T, SIZE1>(size1, one, 1);
78 for (i = 0; i < k * k * sg; i++)
80 for (i = 0; i < k * sg; i++)
82 for (j = 1; j <= k; j++) {
85 for (l = 0; l <= k; l++) {
86 cweight = cplx_i / h *
I.poly_differentiation(j, l);
88 element_incr<T, SIZE1>(size1, qq + p * sg, -cweight, G.retptr(n, n));
91 element_incr<T, SIZE1>(size1, mm + sg * (p * k + q), cweight);
95 element_set<T, SIZE1>(size1, gtemp, H + (n - j) * sg);
96 element_smul<T, SIZE1>(size1, gtemp, -1);
97 for (i = 0; i < sg; i++)
98 gtemp[i] += mu * one[i];
99 element_incr<T, SIZE1>(size1, mm + sg * (p + k * p), gtemp);
101 for (l = 0; l <= k; l++) {
102 weight = h *
I.gregory_weights(j, l);
103 if (n - l >= n - j) {
104 element_set<T, SIZE1>(
106 Sigma.retptr(n - l, n - j));
108 element_set<T, SIZE1>(size1, stemp, Sigma.retptr(n - j, n - l));
109 element_conj<T, SIZE1>(size1, stemp);
113 element_incr<T, SIZE1>(size1, qq + p * sg, weight, G.retptr(n, n),
117 element_incr<T, SIZE1>(size1, mm + sg * (p * k + q), -weight, stemp);
121 element_linsolve_left<T, SIZE1>(size1, k, gtemp, mm, qq);
122 for (j = 1; j <= k; j++)
123 element_set<T, SIZE1>(size1, G.retptr(n, n - j), gtemp + (j - 1) * sg);
136 #pragma omp parallel num_threads(omp_num_threads) 140 int nomp = omp_get_num_threads();
141 int tid = omp_get_thread_num();
142 std::vector<bool> mask_ret(n + 1,
false);
143 cplx w0 = h *
I.gregory_omega(0);
147 for (i = 0; i < n - k; i++)
150 incr_convolution_ret<T, GG, SIZE1>(n, mask_ret,
cplx(1.0, 0.0), G, Sigma, Sigma,
152 for (p = 0; p <= k1; p++)
153 diffw[p] =
I.bd_weights(p) * cplx_i / h;
154 for (j = 0; j < n - k; j++) {
156 element_set<T, SIZE1>(size1, qq, G.retptr(n, j));
158 for (p = 1; p <= k1; p++)
159 element_incr<T, SIZE1>(size1, qq, -diffw[p], G.retptr(n - p, j));
160 element_set<T, SIZE1>(size1, mm, diffw[0] + mu);
161 element_incr<T, SIZE1>(size1, mm, -w0, Sigma.retptr(j, j));
162 element_incr<T, SIZE1>(size1, mm,
cplx(-1.0, 0.0), H + n * sg);
163 element_linsolve_right<T, SIZE1>(size1, G.retptr(n, j), mm, qq);
178 template <
typename T,
class GG,
int SIZE1>
179 void dyson_timestep_tv_omp(
int omp_num_threads,
int n, GG &G, T mu, std::complex<T> *Hn,
181 typedef std::complex<T>
cplx;
182 int size1 = G.size1();
183 int k =
I.get_k(), k1 = k + 1;
184 int sg = G.element_size();
188 assert(n<= Sigma.nt());
190 assert(G.sig()== Sigma.sig());
192 for (
int j = 0; j <= ntau; j++)
193 element_set_zero<T, SIZE1>(size1, G.tvptr(n, j));
194 #pragma omp parallel num_threads(omp_num_threads) 198 int nomp = omp_get_num_threads();
199 int tid = omp_get_thread_num();
200 std::vector<bool> mask(ntau + 1,
false);
205 for (i = 0; i <= ntau; i++)
208 incr_convolution_tv<T, GG, SIZE1>(n, mask,
cplx(1.0, 0.0), G, Sigma, Sigma, NULL,
209 NULL, G, G,
I, beta, h);
213 element_set<T, SIZE1>(size1, mm, ih *
I.bd_weights(0) + mu);
214 element_incr<T, SIZE1>(size1, mm,
cplx(-1.0, 0.0), Hn);
215 cweight = -h *
I.gregory_weights(n, 0);
216 element_incr<T, SIZE1>(size1, mm, cweight, Sigma.retptr(n, n));
218 for (p = 0; p <= k1; p++)
219 diffw[p] = ih *
I.bd_weights(p);
220 for (j = 0; j <= ntau; j++) {
222 element_set<T, SIZE1>(size1, qq, G.tvptr(n, j));
223 for (p = 1; p <= k1; p++)
224 element_incr<T, SIZE1>(size1, qq, -diffw[p], G.tvptr(n - p, j));
225 element_linsolve_right<T, SIZE1>(size1, G.tvptr(n, j), mm, qq);
236 template <
typename T,
class GG,
int SIZE1>
237 void pseudodyson_timestep_tv_omp(
int omp_num_threads,
int n, GG &G, T mu,
238 std::complex<T> *Hn, GG &Sigma,
240 typedef std::complex<T>
cplx;
241 int size1 = G.size1();
242 int k =
I.get_k(), k1 = k + 1;
243 int sg = G.element_size();
247 assert(n<= Sigma.nt());
249 assert(G.sig()== Sigma.sig());
251 for (
int j = 0; j <= ntau; j++)
252 element_set_zero<T, SIZE1>(size1, G.tvptr(n, j));
253 #pragma omp parallel num_threads(omp_num_threads) 257 int nomp = omp_get_num_threads();
258 int tid = omp_get_thread_num();
259 std::vector<bool> mask(ntau + 1,
false);
264 for (i = 0; i <= ntau; i++)
267 incr_pseudo_convolution_tv<T, GG, SIZE1>(n, mask,
cplx(1.0, 0.0), G, Sigma, Sigma,
268 NULL, NULL, G, G,
I, beta, h);
272 element_set<T, SIZE1>(size1, mm, ih *
I.bd_weights(0) + mu);
273 element_incr<T, SIZE1>(size1, mm,
cplx(-1.0, 0.0), Hn);
274 cweight = -h *
I.gregory_weights(n, 0);
275 element_incr<T, SIZE1>(size1, mm, cweight, Sigma.retptr(n, n));
277 for (p = 0; p <= k1; p++)
278 diffw[p] = ih *
I.bd_weights(p);
279 for (j = 0; j <= ntau; j++) {
281 element_set<T, SIZE1>(size1, qq, G.tvptr(n, j));
282 for (p = 1; p <= k1; p++)
283 element_incr<T, SIZE1>(size1, qq, -diffw[p], G.tvptr(n - p, j));
284 element_linsolve_right<T, SIZE1>(size1, G.tvptr(n, j), mm, qq);
297 template <
typename T,
class GG,
int SIZE1>
298 void dyson_timestep_les_omp(
int omp_num_threads,
int n, GG &G, T mu, std::complex<T> *H,
300 typedef std::complex<T>
cplx;
302 int k =
I.get_k(), k1 = k + 1;
303 int size1 = G.size1();
304 int sg = G.element_size();
305 int n1 = (n > k ? n : k);
309 assert(G.ntau()<= Sigma.ntau());
310 assert(n1<= Sigma.nt());
312 assert(G.sig()== Sigma.sig());
315 return dyson_timestep_les<T, GG, SIZE1>(n, G, mu, H, Sigma,
I, beta, h);
317 for (
int j = 0; j <= n; j++)
318 element_set_zero<T, SIZE1>(size1, G.lesptr(j, n));
321 #pragma omp parallel num_threads(omp_num_threads) 324 int nomp = omp_get_num_threads();
325 int tid = omp_get_thread_num();
326 std::vector<bool> mask_les(n + 1,
false);
327 cplx w0 = h *
I.gregory_omega(0);
333 for (i = 0; i < n - k; i++)
336 incr_convolution_les<T, GG, SIZE1>(n, mask_les,
cplx(1.0, 0.0), G, G, G, NULL, NULL,
337 Sigma, Sigma,
I, beta, h);
338 for (p = 0; p <= k1; p++)
339 diffw[p] =
I.bd_weights(p) * cplx_i / h;
340 for (j = 0; j < n - k; j++) {
342 element_set<T, SIZE1>(size1, qq, G.lesptr(j, n));
344 for (p = 1; p <= k1; p++)
345 element_incr<T, SIZE1>(size1, qq, diffw[p], G.lesptr(j, n - p));
346 element_set<T, SIZE1>(size1, mm, -diffw[0] + mu);
347 element_conj<T, SIZE1>(size1, stemp, Sigma.retptr(j, j));
348 element_incr<T, SIZE1>(size1, mm, -w0, stemp);
349 element_incr<T, SIZE1>(size1, mm,
cplx(-1.0, 0.0), H + n * sg);
350 element_linsolve_left<T, SIZE1>(size1, G.lesptr(j, n), mm, qq);
363 cplx *gles =
new cplx[(n + 1) * sg];
370 #pragma omp parallel num_threads(omp_num_threads) 373 int nomp = omp_get_num_threads();
374 int tid = omp_get_thread_num();
375 for (j1 = n - k; j1 <= n; j1++) {
376 if ((n - j1) % nomp == tid) {
377 element_set_zero<T, SIZE1>(size1, gles + j1 * sg);
378 convolution_timestep_les_tvvt<T, GG, SIZE1>(n, j1, j1, gles, G, Sigma,
379 Sigma, G, G,
I, beta, h);
380 convolution_timestep_les_lesadv<T, GG, SIZE1>(n, j1, j1, gles, G, Sigma,
381 Sigma, G, G,
I, beta, h);
385 for (j = n - k; j <= n; j++) {
387 element_set<T, SIZE1>(size1, qq, gles + j * sg);
389 for (p = 1; p <= k1; p++) {
390 cweight = -cplx_i / h *
I.bd_weights(p);
391 element_incr<T, SIZE1>(size1, qq, cweight, G.lesptr(j - p, n));
393 element_set<T, SIZE1>(size1, mm, cplx_i / h *
I.bd_weights(0) + mu);
394 element_incr<T, SIZE1>(size1, mm,
cplx(-1.0, 0.0), H + sg * j);
395 cweight = -h *
I.gregory_weights(j, j);
396 element_incr<T, SIZE1>(size1, mm, cweight, Sigma.retptr(j, j));
397 for (m = 0; m < j; m++) {
398 cweight = h *
I.gregory_weights(j, m);
399 element_incr<T, SIZE1>(size1, qq, cweight, Sigma.retptr(j, m),
402 element_linsolve_right<T, SIZE1>(size1, G.lesptr(j, n), mm, qq);
416 template <
typename T>
417 void pseudodyson_timestep_omp(
int omp_num_threads,
int n, herm_pseudo<T> &G, T lam0,
418 function<T> &H, herm_pseudo<T> &Sigma,
420 int size1 = G.size1(), k =
I.k();
421 int omp_num_threads1 = (omp_num_threads == -1 ? omp_get_max_threads() : omp_num_threads);
423 assert(n<= Sigma.nt());
426 assert(G.sig()== Sigma.sig());
427 assert(G.size1()== Sigma.size1());
428 assert(G.size1()== H.size1());
429 assert(G.ntau()== Sigma.ntau());
431 dyson_timestep_ret_omp<T, herm_pseudo<T>, 1>(omp_num_threads1, n, G, lam0, H.ptr(0),
433 pseudodyson_timestep_tv_omp<T, herm_pseudo<T>, 1>(omp_num_threads1, n, G, lam0,
434 H.ptr(n), Sigma,
I, beta, h);
435 dyson_timestep_les_omp<T, herm_pseudo<T>, 1>(omp_num_threads1, n, G, lam0, H.ptr(0),
438 dyson_timestep_ret_omp<T, herm_pseudo<T>, LARGESIZE>(omp_num_threads1, n, G, lam0,
439 H.ptr(0), Sigma,
I, h);
440 pseudodyson_timestep_tv_omp<T, herm_pseudo<T>, LARGESIZE>(
441 omp_num_threads1, n, G, lam0, H.ptr(n), Sigma,
I, beta, h);
442 dyson_timestep_les_omp<T, herm_pseudo<T>, LARGESIZE>(omp_num_threads1, n, G, lam0,
443 H.ptr(0), Sigma,
I, beta, h);
448 template <
typename T>
449 void pseudodyson_timestep_omp(
int omp_num_threads,
int n, herm_pseudo<T> &G, T lam0,
450 std::complex<T> *Ht, herm_pseudo<T> &Sigma,
452 int size1 = G.size1(), k =
I.k();
453 int omp_num_threads1 = (omp_num_threads == -1 ? omp_get_max_threads() : omp_num_threads);
455 assert(n<= Sigma.nt());
457 assert(G.sig()== Sigma.sig());
458 assert(G.size1()== Sigma.size1());
459 assert(G.ntau()== Sigma.ntau());
461 dyson_timestep_ret_omp<T, herm_pseudo<T>, 1>(omp_num_threads1, n, G, lam0, Ht, Sigma,
463 pseudodyson_timestep_tv_omp<T, herm_pseudo<T>, 1>(
464 omp_num_threads1, n, G, lam0, Ht + n * size1 * size1, Sigma,
I, beta, h);
465 dyson_timestep_les_omp<T, herm_pseudo<T>, 1>(omp_num_threads1, n, G, lam0, Ht, Sigma,
468 dyson_timestep_ret_omp<T, herm_pseudo<T>, LARGESIZE>(omp_num_threads1, n, G, lam0,
470 pseudodyson_timestep_tv_omp<T, herm_pseudo<T>, LARGESIZE>(
471 omp_num_threads1, n, G, lam0, Ht + n * size1 * size1, Sigma,
I, beta, h);
472 dyson_timestep_les_omp<T, herm_pseudo<T>, LARGESIZE>(omp_num_threads1, n, G, lam0,
473 Ht, Sigma,
I, beta, h);
478 template <
typename T>
479 void pseudodyson_timestep_omp(
int omp_num_threads,
int n, herm_pseudo<T> &G, T lam0,
480 std::vector<std::complex<T>> &Ht, herm_pseudo<T> &Sigma,
482 int size1 = G.size1(), k =
I.k();
483 std::complex<T> *hh =
new std::complex<T>[n + 1];
484 int omp_num_threads1 = (omp_num_threads == -1 ? omp_get_max_threads() : omp_num_threads);
487 assert(n<= Sigma.nt());
489 assert(G.sig()== Sigma.sig());
490 assert(G.size1()== Sigma.size1());
491 assert(G.ntau()== Sigma.ntau());
492 assert(n + 1<= (
int)Ht.size());
493 for (
int j = 0; j <= n; j++)
495 dyson_timestep_ret_omp<T, herm_pseudo<T>, 1>(omp_num_threads1, n, G, lam0, hh, Sigma,
I,
497 pseudodyson_timestep_tv_omp<T, herm_pseudo<T>, 1>(
498 omp_num_threads1, n, G, lam0, hh + n * size1 * size1, Sigma,
I, beta, h);
499 dyson_timestep_les_omp<T, herm_pseudo<T>, 1>(omp_num_threads1, n, G, lam0, hh, Sigma,
I,
505 template <
typename T>
506 void dyson_timestep_omp(
int omp_num_threads,
int n, herm_matrix<T> &G, T lam0,
509 int size1 = G.size1(), k =
I.k();
510 int omp_num_threads1 = (omp_num_threads == -1 ? omp_get_max_threads() : omp_num_threads);
512 assert(n<= Sigma.nt());
515 assert(G.sig()== Sigma.sig());
516 assert(G.size1()== Sigma.size1());
517 assert(G.size1()== H.size1());
518 assert(G.ntau()== Sigma.ntau());
520 dyson_timestep_ret_omp<T, herm_matrix<T>, 1>(omp_num_threads1, n, G, lam0, H.ptr(0),
522 dyson_timestep_tv_omp<T, herm_matrix<T>, 1>(omp_num_threads1, n, G, lam0, H.ptr(n),
524 dyson_timestep_les_omp<T, herm_matrix<T>, 1>(omp_num_threads1, n, G, lam0, H.ptr(0),
527 dyson_timestep_ret_omp<T, herm_matrix<T>, LARGESIZE>(omp_num_threads1, n, G, lam0,
528 H.ptr(0), Sigma,
I, h);
529 dyson_timestep_tv_omp<T, herm_matrix<T>, LARGESIZE>(omp_num_threads1, n, G, lam0,
530 H.ptr(n), Sigma,
I, beta, h);
531 dyson_timestep_les_omp<T, herm_matrix<T>, LARGESIZE>(omp_num_threads1, n, G, lam0,
532 H.ptr(0), Sigma,
I, beta, h);
576 template <
typename T>
579 T beta, T h,
int SolveOrder) {
580 int size1 = G.
size1();
581 int omp_num_threads1 = (omp_num_threads == -1 ? omp_get_max_threads() : omp_num_threads);
582 assert(SolveOrder + 1<= n);
583 assert(n<= Sigma.
nt());
586 assert(G.
sig()== Sigma.
sig());
591 dyson_timestep_ret_omp<T, herm_matrix<T>, 1>(omp_num_threads1, n, G, lam0, H.
ptr(0),
592 Sigma, integration::I<T>(SolveOrder), h);
593 dyson_timestep_tv_omp<T, herm_matrix<T>, 1>(omp_num_threads1, n, G, lam0, H.
ptr(n),
594 Sigma, integration::I<T>(SolveOrder), beta, h);
595 dyson_timestep_les_omp<T, herm_matrix<T>, 1>(omp_num_threads1, n, G, lam0, H.
ptr(0),
596 Sigma, integration::I<T>(SolveOrder), beta, h);
598 dyson_timestep_ret_omp<T, herm_matrix<T>, LARGESIZE>(omp_num_threads1, n, G, lam0,
599 H.
ptr(0), Sigma, integration::I<T>(SolveOrder), h);
600 dyson_timestep_tv_omp<T, herm_matrix<T>, LARGESIZE>(omp_num_threads1, n, G, lam0,
601 H.
ptr(n), Sigma, integration::I<T>(SolveOrder), beta, h);
602 dyson_timestep_les_omp<T, herm_matrix<T>, LARGESIZE>(omp_num_threads1, n, G, lam0,
603 H.
ptr(0), Sigma, integration::I<T>(SolveOrder), beta, h);
607 #endif // CNTR_USE_OMP 611 #endif // CNTR_DYSON_OMP_IMPL_H Class Integrator contains all kinds of weights for integration and differentiation of a function at ...
std::complex< double > cplx
Integrator< T > & I(int k)
Class function for objects with time on real axis.
Class herm_matrix for two-time contour objects with hermitian symmetry.