TRIQS/triqs_tprf 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
chi_retime.cpp
1/*******************************************************************************
2 *
3 * TRIQS: a Toolbox for Research in Interacting Quantum Systems
4 *
5 * Copyright (C) 2022, H. U.R. Strand
6 *
7 * TRIQS is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later
10 * version.
11 *
12 * TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * TRIQS. If not, see <http://www.gnu.org/licenses/>.
19 *
20 ******************************************************************************/
21
22#include <nda/linalg.hpp>
23
24#include "common.hpp"
25#include "../mpi.hpp"
26#include "chi_retime.hpp"
27
28#include "../fourier/fourier.hpp"
29#include "fourier.hpp"
30
31namespace triqs_tprf {
32
33 namespace {
34 using namespace fourier;
35 }
36
37// ----------------------------------------------------
38// helper functions
39
40double fermi_scalar(double e) {
41 if( e < 0 ) {
42 return 1. / (exp(e) + 1.);
43 } else {
44 double exp_me = exp(-e);
45 return exp_me / (1 + exp_me);
46 }
47}
48
49auto fermi_nda = nda::map([](double e) { return fermi_scalar(e); });
50
51// ----------------------------------------------------
52// g0_Tk_les, g0_Tk_gtr in real time
53
54std::tuple<g_Tk_t, g_Tk_t> g0_Tk_les_gtr_from_e_k(e_k_cvt e_k, mesh::retime Tmesh, double beta) {
55
56 auto I = std::complex(0.,1.);
57 auto kmesh = e_k.mesh();
58
59 g_Tk_t g0_Tk_les({Tmesh, kmesh}, e_k.target_shape());
60 g_Tk_t g0_Tk_gtr({Tmesh, kmesh}, e_k.target_shape());
61
62 auto arr = mpi_view(kmesh);
63
64#pragma omp parallel for
65 for (unsigned int idx = 0; idx < arr.size(); idx++) {
66 auto &k = arr[idx];
67
68 matrix<std::complex<double>> e_k_mat(e_k[k]);
69 auto [ek, Uk] = linalg::eigh(e_k_mat);
70
71 auto occ = fermi_nda(beta*ek);
72
73 for (auto T : Tmesh) {
74 auto exp_T = exp(-I * ek * double(T));
75 auto occ_exp_les = +I * occ * exp_T;
76 auto occ_exp_gtr = -I * (1. - occ) * exp_T;
77
78 for (auto [a, b] : g0_Tk_les.target_indices())
79 for (auto c : range(ek.size())) {
80 g0_Tk_les[T, k](a, b) += Uk(a, c) * occ_exp_les(c) * dagger(Uk)(c, b);
81 g0_Tk_gtr[T, k](a, b) += Uk(a, c) * occ_exp_gtr(c) * dagger(Uk)(c, b);
82 }
83 }
84 }
85
86 g0_Tk_les = mpi::all_reduce(g0_Tk_les);
87 g0_Tk_gtr = mpi::all_reduce(g0_Tk_gtr);
88
89 return {g0_Tk_les, g0_Tk_gtr};
90}
91
92// ----------------------------------------------------
93// chi0 bubble in real time
94
95chi_Tr_t chi0_Tr_from_g_Tr_PH(g_Tr_cvt g_Tr_les, g_Tr_cvt g_Tr_gtr) {
96
97 auto I = std::complex(0.,1.);
98
99 auto Tmesh = std::get<0>(g_Tr_les.mesh());
100 auto rmesh = std::get<1>(g_Tr_les.mesh());
101
102 int nb = g_Tr_les.target().shape()[0];
103
104 chi_Tr_t chi0_Tr{{Tmesh, rmesh}, {nb, nb, nb, nb}};
105
106 //for (auto r : rmesh) {
107
108 auto arr = mpi_view(Tmesh);
109
110#pragma omp parallel for
111 for (unsigned int idx = 0; idx < arr.size(); idx++) {
112 auto &T = arr[idx];
113
114 for (auto r : rmesh)
115 for (auto [a, b, c, d] : chi0_Tr.target_indices())
116 chi0_Tr[T, r](a, b, c, d) = +I * g_Tr_les[T, r](d, a) * conj(g_Tr_gtr(T.index(), -r)(b, c)) - I * g_Tr_gtr[T, r](d, a) * conj(g_Tr_les(T.index(), -r)(b, c));
117 }
118
119 chi0_Tr = mpi::all_reduce(chi0_Tr);
120
121 return chi0_Tr;
122}
123
124} // namespace triqs_tprf
125