TRIQS/triqs_ctint 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
M3ph_iw.cpp
1// Copyright (c) 2017--present, The Simons Foundation
2// This file is part of TRIQS/ctint 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 "./M3ph_iw.hpp"
7
8namespace triqs_ctint::measures {
9
10 M3ph_iw::M3ph_iw(params_t const &params_, qmc_config_t const &qmc_config_, container_set *results, g_tau_cv_t G0_tau_)
11 : params(params_),
12 qmc_config(qmc_config_),
13 buf_arrarr(params_.n_blocks()),
14 buf_arrarr_GM(params_.n_blocks()),
15 buf_arrarr_MG(params_.n_blocks()),
16 G0_tau(std::move(G0_tau_)) {
17
18 // Construct Matsubara mesh
19 mesh::imfreq iW_mesh{params.beta, Boson, params.n_iW_M3};
20 mesh::imfreq iw_mesh{params.beta, Fermion, params.n_iw_M3};
21 mesh::prod<imfreq, imfreq> M3ph_iw_mesh{iW_mesh, iw_mesh};
22
23 // Init measurement container and capture view
24 results->M3ph_iw_nfft = make_block2_gf(M3ph_iw_mesh, params.gf_struct);
25 M3ph_iw_.rebind(results->M3ph_iw_nfft.value());
26 M3ph_iw_() = 0;
27
28 // Initialize intermediate scattering matrix
29 mesh::imfreq iw_mesh_large{params.beta, Fermion, params.n_iw_M3 + params.n_iW_M3};
30 M = block_gf{mesh::prod<imfreq, imfreq>{iw_mesh_large, iw_mesh}, params.gf_struct};
31 GM = block_gf{iw_mesh, params.gf_struct};
32 MG = block_gf{iw_mesh_large, params.gf_struct};
33
34 auto init_target_func = [&](int bl) {
35 int bl_size = GM[bl].target_shape()[0];
36 return array<dcomplex, 2>(bl_size, bl_size);
37 };
38 GMG = array_adapter{make_shape(params.n_blocks()), init_target_func};
39
40 // Create nfft buffers
41 for (int bl : range(params.n_blocks())) {
42 // M
43 auto init_func_M = [&](int i, int j) { return nfft_buf_t<2>{slice_target_to_scalar(M[bl], i, j).data(), params.nfft_buf_size, params.beta}; };
44 buf_arrarr(bl) = array_adapter{M[bl].target_shape(), init_func_M};
45
46 // GM
47 auto init_func_GM = [&](int i, int j) { return nfft_buf_t<1>{slice_target_to_scalar(GM[bl], i, j).data(), params.nfft_buf_size, params.beta}; };
48 buf_arrarr_GM(bl) = array_adapter{GM[bl].target_shape(), init_func_GM};
49
50 // MG
51 auto init_func_MG = [&](int i, int j) { return nfft_buf_t<1>{slice_target_to_scalar(MG[bl], i, j).data(), params.nfft_buf_size, params.beta}; };
52 buf_arrarr_MG(bl) = array_adapter{MG[bl].target_shape(), init_func_MG};
53 }
54 }
55
56 void M3ph_iw::accumulate(mc_weight_t sign) {
57 // Accumulate sign
58 Z += sign;
59
60 // Reset intermediate scattering matrices
61 for (auto &i : GMG) { i() = 0; }
62 GM() = 0;
63 MG() = 0;
64 M() = 0;
65
66 double beta = params.beta;
67
68 // Init intermediate scattering matrices
69 for (int bl : range(params.n_blocks())) {
70 int bl_size = GM[bl].target_shape()[0];
71
72 //for (auto &[c_i, cdag_j, Ginv1] : qmc_config.dets[b1]) // FIXME c++17
73 foreach (qmc_config.dets[bl], [&](c_t const &c_i, cdag_t const &cdag_j, auto const &Ginv_ji) {
74 auto tau_i = double(c_i.tau);
75 auto tau_j = double(cdag_j.tau);
76
77 // Fill M, Note: Minus sign from the shift of -tau_i
78 buf_arrarr(bl)(cdag_j.u, c_i.u).push_back({tau_j, beta - tau_i}, -Ginv_ji);
79
80 //Fill GMG, GM, MG
81 for (int abar_u : range(bl_size)) {
82 auto G0_ia = G0_tau[bl][closest_mesh_pt(tau_i)](c_i.u, abar_u);
83 for (int b_u : range(bl_size)) {
84 // Note: Minus sign from the shift of -tau_j
85 auto G0_bj = -G0_tau[bl][closest_mesh_pt(beta - tau_j)](b_u, cdag_j.u);
86 GMG(bl)(abar_u, b_u) += G0_bj * Ginv_ji * G0_ia;
87 // Note: Minus sign from the shift of -tau_i
88 buf_arrarr_GM(bl)(b_u, c_i.u).push_back({beta - tau_i}, -G0_bj * Ginv_ji);
89 buf_arrarr_MG(bl)(b_u, c_i.u).push_back({tau_j}, Ginv_ji * G0_ia);
90 }
91 }
92 });
93 }
94
95 // Flush remaining points from all buffers
96 for (auto &buf_arr : buf_arrarr)
97 for (auto &buf : buf_arr) buf.flush();
98 for (auto &buf_arr : buf_arrarr_GM)
99 for (auto &buf : buf_arr) buf.flush();
100 for (auto &buf_arr : buf_arrarr_MG)
101 for (auto &buf : buf_arr) buf.flush();
102
103 auto [iW_mesh, iw_mesh] = M3ph_iw_(0, 0).mesh();
104
105 for (int bl1 : range(params.n_blocks())) // FIXME c++17 Loops
106 for (int bl2 : range(params.n_blocks())) {
107
108 int bl1_size = M[bl1].target_shape()[0];
109 int bl2_size = M[bl2].target_shape()[0];
110 auto const &M1 = M[bl1];
111 auto const &GMG2 = GMG(bl2);
112 auto const &GM1 = GM[bl1];
113 auto const &MG2 = MG(bl2);
114 auto &M3ph_iw = M3ph_iw_(bl1, bl2);
115
116 for (auto iW : iW_mesh)
117 for (auto iw : iw_mesh)
118 for (int i : range(bl1_size))
119 for (int j : range(bl1_size))
120 for (int k : range(bl2_size))
121 for (int l : range(bl2_size)) {
122 M3ph_iw[iW, iw](i, j, k, l) += sign * M1[iW + iw, iw.value()](j, i) * GMG2(l, k);
123 if (bl1 == bl2) { M3ph_iw[iW, iw](i, j, k, l) -= sign * GM1[iw.value()](l, i) * MG2[iW + iw](j, k); }
124 }
125 }
126 }
127
128 void M3ph_iw::collect_results(mpi::communicator const &comm) {
129 // Collect results and normalize
130 Z = mpi::all_reduce(Z, comm);
131 M3ph_iw_ = mpi::all_reduce(M3ph_iw_, comm);
132 M3ph_iw_ = M3ph_iw_ / Z;
133 }
134
135} // namespace triqs_ctint::measures
int u
The orbital (or non-block) index.
Definition dets.hpp:29
void collect_results(mpi::communicator const &comm)
Collect results and normalize.
Definition M3ph_iw.cpp:128
void accumulate(mc_weight_t sign)
Accumulate M_tau using binning.
Definition M3ph_iw.cpp:56