TRIQS/triqs_ctseg 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
G_F_tau.cpp
1// Copyright (c) 2022--present, The Simons Foundation
2// Copyright (c) 2022--present, Max Planck Institute for Polymer Research, Mainz, Germany
3// This file is part of TRIQS/ctseg and is licensed under the terms of GPLv3 or later.
4// SPDX-License-Identifier: GPL-3.0-or-later
5// See LICENSE in the root of this distribution for details.
6
7#include "./G_F_tau.hpp"
8#include "../logs.hpp"
9
10namespace triqs_ctseg::measures {
11
12 G_F_tau::G_F_tau(params_t const &p, work_data_t const &wdata, configuration_t const &config, results_t &results)
13 : wdata{wdata}, config{config}, results{results} {
14
15 beta = p.beta;
16 measure_F_tau = p.measure_F_tau and wdata.rot_inv;
17 gf_struct = p.gf_struct;
18
19 G_tau = block_gf<imtime>{triqs::mesh::imtime{beta, Fermion, p.n_tau_G}, p.gf_struct};
20 F_tau = block_gf<imtime>{triqs::mesh::imtime{beta, Fermion, p.n_tau_G}, p.gf_struct};
21 G_tau() = 0;
22 F_tau() = 0;
23 Z = 0;
24 }
25
26 // -------------------------------------
27
28 void G_F_tau::accumulate(double s) {
29
30 LOG("\n =================== MEASURE G(tau) ================ \n");
31
32 Z += s;
33
34 for (auto [bl_idx, det] : itertools::enumerate(wdata.dets)) {
35 long N = det.size();
36 auto &g = G_tau[bl_idx];
37 auto &f = F_tau[bl_idx];
38 for (long id_y : range(N)) {
39 auto y = det.get_y(id_y);
40 double f_fact = 0;
41 if (measure_F_tau) f_fact = fprefactor(bl_idx, y);
42 for (long id_x : range(N)) {
43 auto x = det.get_x(id_x);
44 auto Minv = det.inverse_matrix(id_y, id_x);
45 // beta-periodicity is implicit in the argument, just fix the sign properly
46 auto val = (y.first >= x.first ? s : -s) * Minv;
47 auto dtau = double(y.first - x.first);
48 g[closest_mesh_pt(dtau)](y.second, x.second) += val;
49 if (measure_F_tau) f[closest_mesh_pt(dtau)](y.second, x.second) += val * f_fact;
50 }
51 }
52 }
53 }
54
55 // -------------------------------------
56
57 void G_F_tau::collect_results(mpi::communicator const &c) {
58
59 Z = mpi::all_reduce(Z, c);
60
61 G_tau = mpi::all_reduce(G_tau, c);
62 G_tau = G_tau / (-beta * Z * G_tau[0].mesh().delta());
63
64 // Fix the point at zero and beta, for each block
65 for (auto &g : G_tau) {
66 g[0] *= 2;
67 g[g.mesh().size() - 1] *= 2;
68 }
69 // store the result (not reused later, hence we can move it).
70 results.G_tau = std::move(G_tau);
71
72 if (measure_F_tau) {
73 F_tau = mpi::all_reduce(F_tau, c);
74 F_tau = F_tau / (-beta * Z * F_tau[0].mesh().delta());
75
76 for (auto &f : F_tau) {
77 f[0] *= 2;
78 f[f.mesh().size() - 1] *= 2;
79 }
80 results.F_tau = std::move(F_tau);
81 }
82 }
83
84 // -------------------------------------
85
86 double G_F_tau::fprefactor(long const &block, std::pair<tau_t, long> const &y) {
87 int color = wdata.block_to_color(block, y.second);
88 double I_tau = 0;
89 for (auto const &[c, sl] : itertools::enumerate(config.seglists)) {
90 auto ntau = n_tau(y.first, sl); // Density to the right of y.first in sl
91 if (c != color) I_tau += wdata.U(c, color) * ntau;
92 if (wdata.has_Dt) {
93 I_tau -= K_overlap(sl, y.first, false, wdata.Kprime, c, color);
94 if (c == color) I_tau -= 2 * real(wdata.Kprime(0)(c, c));
95 }
96 if (wdata.has_Jperp) {
97 I_tau -= 4 * real(wdata.Kprime_spin(0)(c, color)) * ntau;
98 I_tau -= 2 * K_overlap(sl, y.first, false, wdata.Kprime_spin, c, color);
99 }
100 }
101 return I_tau;
102 }
103
104} // namespace triqs_ctseg::measures