TRIQS/triqs_ctseg 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
nn_nu_dlr.cpp
1// Copyright (c) 2022--present, The Simons Foundation
2// This file is part of TRIQS/ctseg and is licensed under the terms of GPLv3 or later.
3// SPDX-License-Identifier: GPL-3.0-or-later
4// See LICENSE in the root of this distribution for details.
5
6#include "./nn_nu_dlr.hpp"
7#include "../logs.hpp"
8#include <triqs/mesh.hpp>
9
10namespace triqs_ctseg::measures {
11
12 nn_nu_dlr::nn_nu_dlr(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 ntau = p.n_tau_chi2;
17 dtau = p.beta / (ntau - 1);
18 n_color = config.n_color();
19 block_number = wdata.block_number;
20 index_in_block = wdata.index_in_block;
21
22 auto m = dlr_imfreq(p.beta, Boson, p.dlr_omega_max, p.dlr_epsilon);
23 q_nu_block = make_block2_gf<dlr_imfreq>(m, p.gf_struct);
24 q_nu = gf<dlr_imfreq>(m, {n_color, n_color});
25 q_nu() = 0;
26 }
27
28 // -------------------------------------
29
30 void nn_nu_dlr::accumulate(double s) {
31
32 LOG("\n =================== MEASURE n_n(i nu) ================ \n");
33
34 Z += s;
35
36 // Fourier transform of the characteristic function on [a,b], for n!=0
37 auto ksi1 = [&](double a, double b, matsubara_freq const &nu) -> dcomplex {
38 EXPECTS(b > a);
39 if (nu.n == 0) return (b - a);
40 dcomplex inu = nu;
41 return (std::exp(inu * b) - std::exp(inu * a)) / inu;
42 };
43
44 // Fourier transform of the characteristic function on the segment seg = [tau_c, tau_cdag], accounting for cyclicity
45 auto ksi = [&](segment_t const &seg, matsubara_freq const &nu) -> dcomplex {
46 if (not is_cyclic(seg))
47 return ksi1(double(seg.tau_cdag), double(seg.tau_c), nu);
48 else
49 return ksi1(double(seg.tau_cdag), beta, nu) + ksi1(0, double(seg.tau_c), nu);
50 };
51
52 // Compute n_a(nu)
53 auto n_a_nu = [&](long a, matsubara_freq const &nu) -> dcomplex {
54 dcomplex sum = 0.0;
55 for (auto const &seg : config.seglists[a]) sum += ksi(seg, nu);
56 return sum;
57 };
58
59 // <n_a(i nu) n_b(-i nu) >
60 auto R = nda::range(n_color);
61 nda::array<dcomplex, 1> n(n_color);
62 for (auto const &nu : q_nu.mesh()) { // loop over bosonic frequencies
63 for (auto a : R) { n(a) = n_a_nu(a, nu); }
64 for (auto a : R)
65 for (auto b : R) q_nu[nu](a, b) += s * n(a) * std::conj(n(b));
66 }
67 }
68
69 // -------------------------------------
70
71 void nn_nu_dlr::collect_results(mpi::communicator const &c) {
72
73 Z = mpi::all_reduce(Z, c);
74
75 q_nu = mpi::all_reduce(q_nu, c);
76 q_nu = q_nu / Z / beta;
77
78 // store the result
79 for (int c1 : range(n_color)) {
80 for (int c2 : range(n_color)) {
81 q_nu_block(block_number[c1], block_number[c2]).data()(range::all, index_in_block[c1], index_in_block[c2]) =
82 q_nu.data()(range::all, c1, c2);
83 }
84 }
85 results.nn_nu_dlr = std::move(q_nu_block);
86 }
87
88} // namespace triqs_ctseg::measures