TRIQS/triqs_tprf 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
chi_imtime.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 "common.hpp"
23#include "../mpi.hpp"
24#include "chi_imtime.hpp"
25
26#include "../fourier/fourier.hpp"
27#include "fourier.hpp"
28
29namespace triqs_tprf {
30
31 namespace {
32 using namespace fourier;
33 }
34
35// ----------------------------------------------------
36// chi0 bubble in DLR imaginary time
37
38chi_Dtr_t chi0_tr_from_grt_PH(g_Dtr_cvt g_tr, g_Dtr_cvt g_bwd_tr) {
39
40 assert( g_tr.mesh() == g_bwd_tr.mesh() );
41 assert( g_tr.target() == g_bwd_tr.target() );
42
43 auto _ = all_t{};
44
45 auto tmesh = std::get<0>(g_tr.mesh());
46 auto rmesh = std::get<1>(g_tr.mesh());
47
48 int nb = g_tr.target().shape()[0];
49 double beta = tmesh.beta();
50
51 dlr_imtime btmesh{beta, Boson, tmesh.w_max(), tmesh.eps(), tmesh.symmetrize()};
52 chi_Dtr_t chi0_tr{{btmesh, rmesh}, {nb, nb, nb, nb}};
53
54 auto g_target = g_tr.target();
55 auto chi_target = chi0_tr.target();
56
57 auto arr = mpi_view(rmesh);
58
59#pragma omp parallel for
60 for (unsigned int idx = 0; idx < arr.size(); idx++) {
61 auto & r = arr[idx];
62
63 auto chi0_t = make_gf<dlr_imtime>(btmesh, chi_target);
64 auto g_pr_t = make_gf<dlr_imtime>(tmesh, g_target);
65 auto g_mr_t = make_gf<dlr_imtime>(tmesh, g_target);
66
67#pragma omp critical
68 {
69 g_pr_t = g_tr[_, r];
70 g_mr_t = g_bwd_tr(_, -r);
71 }
72
73 auto g_pr_c = make_gf_dlr(g_pr_t);
74 auto g_mr_c = make_gf_dlr(g_mr_t);
75
76 for (auto t : tmesh)
77 chi0_t[t](a, b, c, d) << g_pr_c(t)(d, a) * g_mr_c(beta - t)(b, c);
78
79#pragma omp critical
80 chi0_tr[_, r] = chi0_t;
81 }
82
83 chi0_tr = mpi::all_reduce(chi0_tr);
84
85 return chi0_tr;
86}
87
88chi_Dtr_t chi0_tr_from_grt_PH(g_Dtr_cvt g_tr) {
89 return chi0_tr_from_grt_PH(g_tr, g_tr);
90}
91
92// ----------------------------------------------------
93// chi0 bubble in DLR imaginary time
94// -- specialization for w=0 (static bubble susceptibility)
95
96chi_wr_t chi0_w0r_from_grt_PH(g_Dtr_cvt g_tr, g_Dtr_cvt g_bwd_tr) {
97
98 assert( g_tr.mesh() == g_bwd_tr.mesh() );
99 assert( g_tr.target() == g_bwd_tr.target() );
100
101 auto _ = all_t{};
102
103 auto tmesh = std::get<0>(g_tr.mesh());
104 auto rmesh = std::get<1>(g_tr.mesh());
105
106 int nb = g_tr.target().shape()[0];
107 double beta = tmesh.beta();
108
109 dlr_imtime btmesh{beta, Boson, tmesh.w_max(), tmesh.eps(), tmesh.symmetrize()};
110
111 imfreq bmesh{beta, Boson, 1};
112 chi_wr_t chi0_w0r{{bmesh, rmesh}, {nb, nb, nb, nb}};
113
114 auto g_target = g_tr.target();
115 auto chi_target = chi0_w0r.target();
116
117 auto arr = mpi_view(rmesh);
118
119#pragma omp parallel for
120 for (unsigned int idx = 0; idx < arr.size(); idx++) {
121 auto & r = arr[idx];
122
123 auto chi0_t = make_gf<dlr_imtime>(btmesh, chi_target);
124 auto g_pr_t = make_gf<dlr_imtime>(tmesh, g_target);
125 auto g_mr_t = make_gf<dlr_imtime>(tmesh, g_target);
126
127#pragma omp critical
128 {
129 g_pr_t = g_tr[_, r];
130 g_mr_t = g_bwd_tr(_, -r);
131 }
132
133 auto g_pr_c = make_gf_dlr(g_pr_t);
134 auto g_mr_c = make_gf_dlr(g_mr_t);
135
136 for (auto t : tmesh)
137 chi0_t[t](a, b, c, d) << g_pr_c(t)(d, a) * g_mr_c(beta - t)(b, c);
138
139 auto I = integrate_dlr_tau(chi0_t);
140
141#pragma omp critical
142 chi0_w0r[0, r] = I;
143 }
144
145 chi0_w0r = mpi::all_reduce(chi0_w0r);
146
147 return chi0_w0r;
148}
149
150chi_wr_t chi0_w0r_from_grt_PH(g_Dtr_cvt g_tr) {
151 return chi0_w0r_from_grt_PH(g_tr, g_tr);
152}
153
154target_value_t<chi_t_t>::regular_type integrate_dlr_tau(chi_Dt_cvt chi_t) {
155
156 auto chi_x = make_gf_dlr(chi_t);
157
158 auto I = zeros<dcomplex>(chi_x.target_shape());
159 for(int l = 0; l < chi_x.mesh().size(); ++l) {
160 auto w = chi_x.mesh().dlr_freq()[l];
161 auto k0 = cppdlr::k_it(0, w);
162 auto k1 = cppdlr::k_it(1, w);
163 I += chi_x.mesh().beta() * (k0 - k1) / w * chi_x[l];
164 }
165
166 return I;
167}
168
169// ----------------------------------------------------
170// chi0 bubble in imaginary time
171
172chi_tr_t chi0_tr_from_grt_PH(g_tr_cvt g_tr, g_tr_cvt g_bwd_tr) {
173
174 assert( g_tr.mesh() == g_bwd_tr.mesh() );
175 assert( g_tr.target() == g_bwd_tr.target() );
176
177 auto _ = all_t{};
178
179 auto tmesh = std::get<0>(g_tr.mesh());
180 auto rmesh = std::get<1>(g_tr.mesh());
181
182 int nb = g_tr.target().shape()[0];
183 int ntau = tmesh.size();
184 double beta = tmesh.beta();
185
186 chi_tr_t chi0_tr{{{beta, Boson, ntau}, rmesh}, {nb, nb, nb, nb}};
187
188 auto g_target = g_tr.target();
189 auto chi_target = chi0_tr.target();
190
191 // -- This does not work on the boundaries!! The eval wraps to the other
192 // regime!
193 // -- gt(beta) == gt(beta + 0^+)
194 // chi0_tr(tau, r)(a, b, c, d) << g_tr(tau, r)(d, a) * g_tr(-tau, -r)(b, c);
195
196 //for (auto r : rmesh) {
197
198 auto arr = mpi_view(rmesh);
199
200#pragma omp parallel for
201 for (unsigned int idx = 0; idx < arr.size(); idx++) {
202 auto &r = arr[idx];
203
204 auto chi0_t = make_gf<imtime>({beta, Boson, ntau}, chi_target);
205 auto g_pr_t = make_gf<imtime>(tmesh, g_target);
206 auto g_mr_t = make_gf<imtime>(tmesh, g_target);
207
208#pragma omp critical
209 {
210 g_pr_t = g_tr[_, r];
211 g_mr_t = g_bwd_tr(_, -r);
212 }
213
214 for (auto t : tmesh) chi0_t[t](a, b, c, d) << g_pr_t(t)(d, a) * g_mr_t(beta - t)(b, c);
215
216#pragma omp critical
217 chi0_tr[_, r] = chi0_t;
218 }
219
220 chi0_tr = mpi::all_reduce(chi0_tr);
221
222 return chi0_tr;
223}
224
225chi_tr_t chi0_tr_from_grt_PH(g_tr_cvt g_tr) {
226 return chi0_tr_from_grt_PH(g_tr, g_tr);
227}
228
229// -- memory optimized version for smaller nw
230chi_wr_t chi0_wr_from_grt_PH(g_tr_cvt g_tr, g_tr_cvt g_bwd_tr, int nw=1) {
231
232 assert( g_tr.mesh() == g_bwd_tr.mesh() );
233 assert( g_tr.target() == g_bwd_tr.target() );
234
235 auto _ = all_t{};
236
237 auto tmesh = std::get<0>(g_tr.mesh());
238 auto rmesh = std::get<1>(g_tr.mesh());
239
240 int nb = g_tr.target().shape()[0];
241 int ntau = tmesh.size();
242 double beta = tmesh.beta();
243
244 chi_wr_t chi0_wr{{{beta, Boson, nw}, rmesh}, {nb, nb, nb, nb}};
245
246 auto g_target = g_tr.target();
247 auto chi_target = chi0_wr.target();
248
249 auto arr = mpi_view(rmesh);
250
251#pragma omp parallel for
252 for (unsigned int idx = 0; idx < arr.size(); idx++) {
253 auto &r = arr[idx];
254
255 auto chi0_t = make_gf<imtime>({beta, Boson, ntau}, chi_target);
256 auto g_pr_t = make_gf<imtime>(tmesh, g_target);
257 auto g_mr_t = make_gf<imtime>(tmesh, g_target);
258
259#pragma omp critical
260 {
261 g_pr_t = g_tr[_, r];
262 g_mr_t = g_bwd_tr(_, -r);
263 }
264
265 for (auto t : tmesh) chi0_t[t](a, b, c, d) << g_pr_t(t)(d, a) * g_mr_t(beta - t)(b, c);
266
267#pragma omp critical
268 {
269 auto chi0_w = make_gf_from_fourier(chi0_t, nw);
270 chi0_wr[_, r] = chi0_w;
271 }
272 }
273
274 chi0_wr = mpi::all_reduce(chi0_wr);
275 return chi0_wr;
276}
277
278chi_wr_t chi0_wr_from_grt_PH(g_tr_cvt g_tr, int nw=1) {
279 return chi0_wr_from_grt_PH(g_tr, g_tr, nw);
280}
281
282// -- optimized version for w=0
283chi_wr_t chi0_w0r_from_grt_PH(g_tr_cvt g_tr, g_tr_cvt g_bwd_tr) {
284
285 assert( g_tr.mesh() == g_bwd_tr.mesh() );
286 assert( g_tr.target() == g_bwd_tr.target() );
287
288 auto _ = all_t{};
289
290 auto tmesh = std::get<0>(g_tr.mesh());
291 auto rmesh = std::get<1>(g_tr.mesh());
292
293 int nw = 1;
294 int nb = g_tr.target().shape()[0];
295 int ntau = tmesh.size();
296 double beta = tmesh.beta();
297
298 chi_wr_t chi0_wr{{{beta, Boson, nw}, rmesh}, {nb, nb, nb, nb}};
299
300 auto g_target = g_tr.target();
301 auto chi_target = chi0_wr.target();
302
303 auto arr = mpi_view(rmesh);
304
305#pragma omp parallel for
306 for (unsigned int idx = 0; idx < arr.size(); idx++) {
307 auto &r = arr[idx];
308
309 auto chi0_t = make_gf<imtime>({beta, Boson, ntau}, chi_target);
310 auto g_pr_t = make_gf<imtime>(tmesh, g_target);
311 auto g_mr_t = make_gf<imtime>(tmesh, g_target);
312
313#pragma omp critical
314 {
315 g_pr_t = g_tr[_, r];
316 g_mr_t = g_bwd_tr(_, -r);
317 }
318
319 for (auto t : tmesh) chi0_t[t](a, b, c, d) << g_pr_t(t)(d, a) * g_mr_t(beta - t)(b, c);
320
321 auto int_chi0 = chi_trapz_tau(chi0_t);
322
323#pragma omp critical
324 chi0_wr[0, r] = int_chi0;
325 }
326
327 chi0_wr = mpi::all_reduce(chi0_wr);
328 return chi0_wr;
329}
330
331chi_wr_t chi0_w0r_from_grt_PH(g_tr_cvt g_tr) {
332 return chi0_w0r_from_grt_PH(g_tr, g_tr);
333}
334
335target_value_t<chi_t_t>::regular_type chi_trapz_tau(chi_t_cvt chi_t) {
336
337 auto tmesh = chi_t.mesh();
338 int ntau = tmesh.size();
339 double beta = tmesh.beta();
340
341 auto I = zeros<dcomplex>(chi_t.target_shape());
342
343 // -- Trapetzoidal integration
344
345 for (auto t : tmesh) I += chi_t[t];
346
347 I -= 0.5 * chi_t[0];
348 I -= 0.5 * chi_t[ntau - 1];
349
350 I *= beta / (ntau-1);
351 return I;
352}
353
354// -- specialized calc for w=0
355chi_wr_t chi_w0r_from_chi_tr(chi_tr_cvt chi_tr) {
356
357 int nb = chi_tr.target().shape()[0];
358
359 auto tmesh = std::get<0>(chi_tr.mesh());
360 auto rmesh = std::get<1>(chi_tr.mesh());
361
362 int nw = 1;
363 double beta = tmesh.beta();
364
365 chi_wr_t chi_wr{{{beta, Boson, nw}, rmesh}, {nb, nb, nb, nb}};
366
367 auto arr = mpi_view(rmesh);
368
369#pragma omp parallel for
370 for (unsigned int idx = 0; idx < arr.size(); idx++) {
371 auto &r = arr[idx];
372
373 auto _ = all_t{};
374 auto I = chi_trapz_tau(chi_tr[_, r]);
375
376#pragma omp critical
377 chi_wr[0, r] = I;
378 }
379
380 chi_wr = mpi::all_reduce(chi_wr);
381 return chi_wr;
382}
383
384chi_wr_t chi_wr_from_chi_tr(chi_tr_cvt chi_tr, int nw) {
385 auto chi_wr = fourier_tr_to_wr_general_target(chi_tr, nw);
386 return chi_wr;
387}
388
389chi_tr_t chi_tr_from_chi_wr(chi_wr_cvt chi_wr, int ntau) {
390 auto chi_tr = fourier_wr_to_tr_general_target(chi_wr, ntau);
391 return chi_tr;
392}
393
394chi_wk_t chi_wk_from_chi_wr(chi_wr_cvt chi_wr) {
395 auto chi_wk = fourier_wr_to_wk_general_target(chi_wr);
396 return chi_wk;
397}
398
399chi_wr_t chi_wr_from_chi_wk(chi_wk_cvt chi_wk) {
400 auto chi_wr = fourier_wk_to_wr_general_target(chi_wk);
401 return chi_wr;
402}
403
404// DLR
405
406chi_Dwr_t chi_wr_from_chi_tr(chi_Dtr_cvt chi_tr, int /* nw */) {
407 auto chi_wr = fourier_Dtr_to_Dwr_general_target(chi_tr);
408 return chi_wr;
409}
410
411chi_Dtr_t chi_tr_from_chi_wr(chi_Dwr_cvt chi_wr, int /* ntau */) {
412 auto chi_tr = fourier_Dwr_to_Dtr_general_target(chi_wr);
413 return chi_tr;
414}
415
416chi_Dwk_t chi_wk_from_chi_wr(chi_Dwr_cvt chi_wr) {
417 auto chi_wk = fourier_wr_to_wk_general_target(chi_wr);
418 return chi_wk;
419}
420
421chi_Dwr_t chi_wr_from_chi_wk(chi_Dwk_cvt chi_wk) {
422 auto chi_wr = fourier_wk_to_wr_general_target(chi_wk);
423 return chi_wr;
424}
425
426/*
427chi_wk_t chi_wk_from_chi_wr(chi_wr_cvt chi_wr) {
428
429 // auto target = chi_wr.target();
430 int nb = chi_wr.target().shape()[0];
431
432 auto wmesh = std::get<0>(chi_wr.mesh());
433 auto rmesh = std::get<1>(chi_wr.mesh());
434
435 auto kmesh = mesh::brzone{brillouin_zone{rmesh.domain()}, rmesh.periodization_matrix()};
436
437 chi_wk_t chi_wk{{wmesh, kmesh}, {nb, nb, nb, nb}};
438
439 auto _ = all_t{};
440 for (auto w : wmesh)
441 chi_wk[w, _] = triqs::gfs::fourier(chi_wr[w, _]);
442
443 return chi_wk;
444}
445
446chi_wr_t chi_wr_from_chi_wk(chi_wk_cvt chi_wk) {
447
448 int nb = chi_wk.target().shape()[0];
449
450 auto wmesh = std::get<0>(chi_wk.mesh());
451 auto kmesh = std::get<1>(chi_wk.mesh());
452
453 auto rmesh = mesh::cyclat{bravais_lattice{kmesh.domain()}, kmesh.periodization_matrix()};
454
455 chi_wr_t chi_wr{{wmesh, rmesh}, {nb, nb, nb, nb}};
456
457 auto _ = all_t{};
458 for (auto w : wmesh)
459 chi_wr[w, _] = triqs::gfs::fourier(chi_wk[w, _]);
460
461 return chi_wr;
462}
463 */
464
465} // namespace triqs_tprf