TRIQS/triqs_tprf 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
gf.cpp
1 /*******************************************************************************
2 *
3 * TRIQS: a Toolbox for Research in Interacting Quantum Systems
4 *
5 * Copyright (C) 2017, 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 "gf.hpp"
25
26#include <omp.h>
27#include "../mpi.hpp"
28#include "fourier.hpp"
29
30namespace triqs_tprf {
31
32 namespace {
33 using namespace fourier;
34 }
35
36
37// ----------------------------------------------------
38// g
39
40template<typename g_t, typename mesh_t>
41g_t lattice_dyson_g0_Xk(double mu, e_k_cvt e_k, mesh_t mesh) {
42
43 auto I = nda::eye<ek_vt::scalar_t>(e_k.target_shape()[0]);
44 g_t g0_wk({mesh, e_k.mesh()}, e_k.target_shape());
45 g0_wk() = 0.0;
46
47 auto arr = mpi_view(g0_wk.mesh());
48
49#pragma omp parallel for
50 for (unsigned int idx = 0; idx < arr.size(); idx++) {
51 auto &[w, k] = arr[idx];
52 g0_wk[w, k] = nda::linalg::inv((w + mu)*I - e_k[k]);
53 }
54
55 g0_wk = mpi::all_reduce(g0_wk);
56 return g0_wk;
57}
58
59g_wk_t lattice_dyson_g0_wk(double mu, e_k_cvt e_k, mesh::imfreq mesh) {
60 return lattice_dyson_g0_Xk<g_wk_t, mesh::imfreq>(mu, e_k, mesh);
61}
62
63g_Dwk_t lattice_dyson_g0_wk(double mu, e_k_cvt e_k, mesh::dlr_imfreq mesh) {
64 return lattice_dyson_g0_Xk<g_Dwk_t, mesh::dlr_imfreq>(mu, e_k, mesh);
65}
66
67// ----------------------------------------------------
68// g0 real frequencies
69
70g_fk_t lattice_dyson_g0_fk(double mu, e_k_cvt e_k, mesh::refreq mesh, double delta) {
71
72 auto I = nda::eye<ek_vt::scalar_t>(e_k.target_shape()[0]);
73 g_fk_t g0_fk({mesh, e_k.mesh()}, e_k.target_shape());
74 g0_fk() = 0.0;
75 std::complex<double> idelta(0.0, delta);
76
77 auto arr = mpi_view(g0_fk.mesh());
78#pragma omp parallel for
79 for (int idx = 0; idx < arr.size(); idx++) {
80 auto &[f, k] = arr[idx];
81 g0_fk[f, k] = nda::linalg::inv((f + idelta + mu) * I - e_k[k]);
82 }
83
84 g0_fk = mpi::all_reduce(g0_fk);
85 return g0_fk;
86}
87
88// ----------------------------------------------------
89
90template<typename g_t, typename sigma_t>
91g_t lattice_dyson_g_Xk(double mu, e_k_cvt e_k, sigma_t sigma, double delta=0.){
92
93 auto const &freqmesh = [&sigma]() -> auto & {
94 if constexpr (sigma_t::arity == 1)
95 return sigma.mesh();
96 else
97 return std::get<0>(sigma.mesh());
98 }();
99
100 using scalar_t = e_k_cvt::scalar_t;
101 auto I = nda::eye<scalar_t>(e_k.target_shape()[0]);
102
103 std::complex<double> idelta(0.0, delta);
104
105 g_t g_wk({freqmesh, e_k.mesh()}, e_k.target_shape());
106 g_wk() = 0.0;
107
108 auto arr = mpi_view(g_wk.mesh());
109#pragma omp parallel for
110 for (unsigned int idx = 0; idx < arr.size(); idx++) {
111 auto &[w, k] = arr[idx];
112
113 array<scalar_t, 2> sigmaterm;
114 if constexpr (sigma_t::arity == 1) sigmaterm = sigma[w];
115 else sigmaterm = sigma[w, k];
116
117 g_wk[w, k] = nda::linalg::inv((w + idelta + mu)*I - e_k[k] - sigmaterm);
118 }
119
120 g_wk = mpi::all_reduce(g_wk);
121 return g_wk;
122}
123
124
125g_wk_t lattice_dyson_g_wk(double mu, e_k_cvt e_k, g_wk_cvt sigma_wk) {
126 return lattice_dyson_g_Xk<g_wk_t, g_wk_cvt>(mu, e_k, sigma_wk);
127}
128
129g_wk_t lattice_dyson_g_wk(double mu, e_k_cvt e_k, g_w_cvt sigma_w) {
130 return lattice_dyson_g_Xk<g_wk_t, g_w_cvt>(mu, e_k, sigma_w);
131}
132
133g_Dwk_t lattice_dyson_g_wk(double mu, e_k_cvt e_k, g_Dwk_cvt sigma_wk) {
134 return lattice_dyson_g_Xk<g_Dwk_t, g_Dwk_cvt>(mu, e_k, sigma_wk);
135}
136
137g_Dwk_t lattice_dyson_g_wk(double mu, e_k_cvt e_k, g_Dw_cvt sigma_w) {
138 return lattice_dyson_g_Xk<g_Dwk_t, g_Dw_cvt>(mu, e_k, sigma_w);
139}
140
141g_fk_t lattice_dyson_g_fk(double mu, e_k_cvt e_k, g_fk_cvt sigma_fk, double delta) {
142 return lattice_dyson_g_Xk<g_fk_t, g_fk_cvt>(mu, e_k, sigma_fk, delta);
143}
144
145g_fk_t lattice_dyson_g_fk(double mu, e_k_cvt e_k, g_f_cvt sigma_f, double delta) {
146 return lattice_dyson_g_Xk<g_fk_t, g_f_cvt>(mu, e_k, sigma_f, delta);
147}
148
149// ----------------------------------------------------
150
151template<typename g_t, typename g_kt, typename sigma_t>
152g_t lattice_dyson_g_X(double mu, e_k_cvt e_k, sigma_t sigma, double delta=0.){
153
154 auto const &freqmesh = [&sigma]() -> auto & {
155 if constexpr (sigma_t::arity == 1)
156 return sigma.mesh();
157 else
158 return std::get<0>(sigma.mesh());
159 }();
160
161 using scalar_t = e_k_cvt::scalar_t;
162 auto I = nda::eye<scalar_t>(e_k.target_shape()[0]);
163
164 std::complex<double> idelta(0.0, delta);
165
166 g_t g_w(freqmesh, e_k.target_shape());
167 g_w() = 0.0;
168
169 // No threading over momentum (k) in order avoid a
170 // race condition in the accumulation to g_w[w] += ...
171
172 auto arr = mpi_view(e_k.mesh());
173 for (unsigned int idx = 0; idx < arr.size(); idx++) {
174 auto &k = arr[idx];
175
176#pragma omp parallel for
177 for (unsigned int widx = 0; widx < freqmesh.size(); widx++) {
178 auto w = *std::next(freqmesh.begin(), widx);
179
180 array<scalar_t, 2> sigmaterm;
181 if constexpr (sigma_t::arity == 1) sigmaterm = sigma[w];
182 else sigmaterm = sigma[w, k];
183
184 g_w[w] += nda::linalg::inv((w + idelta + mu)*I - e_k[k] - sigmaterm);
185 }
186 }
187
188 g_w = mpi::all_reduce(g_w);
189 g_w /= e_k.mesh().size();
190 return g_w;
191}
192
193g_w_t lattice_dyson_g_w(double mu, e_k_cvt e_k, g_w_cvt sigma_w) {
194 return lattice_dyson_g_X<g_w_t, g_wk_t, g_w_cvt>(mu, e_k, sigma_w);
195}
196
197g_Dw_t lattice_dyson_g_w(double mu, e_k_cvt e_k, g_Dw_cvt sigma_w) {
198 return lattice_dyson_g_X<g_Dw_t, g_Dwk_t, g_Dw_cvt>(mu, e_k, sigma_w);
199}
200
201g_f_t lattice_dyson_g_f(double mu, e_k_cvt e_k, g_f_cvt sigma_f, double delta) {
202 return lattice_dyson_g_X<g_f_t, g_fk_t, g_f_cvt>(mu, e_k, sigma_f, delta);
203}
204
205// ----------------------------------------------------
206// Transformations: real space <-> reciprocal space
207
208g_wr_t fourier_wk_to_wr(g_wk_cvt g_wk) {
209 auto g_wr = fourier_wk_to_wr_general_target(g_wk);
210 return g_wr;
211}
212
213g_wk_t fourier_wr_to_wk(g_wr_cvt g_wr) {
214 auto g_wk = fourier_wr_to_wk_general_target(g_wr);
215 return g_wk;
216}
217
218g_Dwr_t fourier_wk_to_wr(g_Dwk_cvt g_wk) {
219 auto g_wr = fourier_wk_to_wr_general_target(g_wk);
220 return g_wr;
221}
222
223g_Dwk_t fourier_wr_to_wk(g_Dwr_cvt g_wr) {
224 auto g_wk = fourier_wr_to_wk_general_target(g_wr);
225 return g_wk;
226}
227
228g_fr_t fourier_fk_to_fr(g_fk_cvt g_fk) {
229 auto g_fr = fourier_wk_to_wr_general_target(g_fk);
230 return g_fr;
231}
232
233g_fk_t fourier_fr_to_fk(g_fr_cvt g_fr) {
234 auto g_fk = fourier_wr_to_wk_general_target(g_fr);
235 return g_fk;
236}
237
238g_Tr_t fourier_Tk_to_Tr(g_Tk_cvt g_Tk) {
239 auto g_Tr = fourier_wk_to_wr_general_target(g_Tk);
240 return g_Tr;
241}
242
243g_Tk_t fourier_Tr_to_Tk(g_Tr_cvt g_Tr) {
244 auto g_Tk = fourier_wr_to_wk_general_target(g_Tr);
245 return g_Tk;
246}
247
248chi_wk_t fourier_wr_to_wk(chi_wr_cvt chi_wr) {
249 auto chi_wk = fourier_wr_to_wk_general_target(chi_wr);
250 return chi_wk;
251}
252
253chi_wr_t fourier_wk_to_wr(chi_wk_cvt chi_wk) {
254 auto chi_wr = fourier_wk_to_wr_general_target(chi_wk);
255 return chi_wr;
256}
257
258chi_Dwk_t fourier_wr_to_wk(chi_Dwr_cvt chi_Dwr) {
259 auto chi_Dwk = fourier_wr_to_wk_general_target(chi_Dwr);
260 return chi_Dwk;
261}
262
263chi_Dwr_t fourier_wk_to_wr(chi_Dwk_cvt chi_Dwk) {
264 auto chi_Dwr = fourier_wk_to_wr_general_target(chi_Dwk);
265 return chi_Dwr;
266}
267
268chi_Tr_t fourier_Tr_to_Tk(chi_Tk_cvt chi_Tk) {
269 auto chi_Tr = fourier_wk_to_wr_general_target(chi_Tk);
270 return chi_Tr;
271}
272
273 chi_Tk_t fourier_Tr_to_Tk(chi_Tr_cvt chi_Tr) {
274 auto chi_Tk = fourier_wr_to_wk_general_target(chi_Tr);
275 return chi_Tk;
276}
277
278// ----------------------------------------------------
279// Transformations: Matsubara frequency <-> imaginary time
280
281g_wr_t fourier_tr_to_wr(g_tr_cvt g_tr, int nw) {
282 auto g_wr = fourier_tr_to_wr_general_target(g_tr, nw);
283 return g_wr;
284}
285
286g_tr_t fourier_wr_to_tr(g_wr_cvt g_wr, int nt) {
287 auto g_tr = fourier_wr_to_tr_general_target(g_wr, nt);
288 return g_tr;
289}
290
291g_Dwr_t fourier_tr_to_wr(g_Dtr_cvt g_tr, int /* nw */) {
292 auto g_wr = fourier_Dtr_to_Dwr_general_target(g_tr);
293 return g_wr;
294}
295
296g_Dtr_t fourier_wr_to_tr(g_Dwr_cvt g_wr, int /* nt */) {
297 auto g_tr = fourier_Dwr_to_Dtr_general_target(g_wr);
298 return g_tr;
299}
300
301chi_wr_t fourier_tr_to_wr(chi_tr_cvt chi_tr, int nw) {
302 auto chi_wr = fourier_tr_to_wr_general_target(chi_tr, nw);
303 return chi_wr;
304}
305
306chi_tr_t fourier_wr_to_tr(chi_wr_cvt chi_wr, int nt) {
307 auto chi_tr = fourier_wr_to_tr_general_target(chi_wr, nt);
308 return chi_tr;
309}
310
311chi_Dwr_t fourier_tr_to_wr(chi_Dtr_cvt chi_Dtr, int /* nw */) {
312 auto chi_Dwr = fourier_Dtr_to_Dwr_general_target(chi_Dtr);
313 return chi_Dwr;
314}
315
316chi_Dtr_t fourier_wr_to_tr(chi_Dwr_cvt chi_Dwr, int /* nt */) {
317 auto chi_Dtr = fourier_Dwr_to_Dtr_general_target(chi_Dwr);
318 return chi_Dtr;
319}
320
321} // namespace triqs_tprf