TRIQS/triqs_ctint 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
M_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 "./M_iw.hpp"
7
8namespace triqs_ctint::measures {
9
10 using triqs::utility::nfft_type_t;
11
12 M_iw::M_iw(params_t const &params_, qmc_config_t const &qmc_config_, container_set *results)
13 : params(params_), qmc_config(qmc_config_), M_data(params_.n_blocks()) {
14
15 // Construct DLR Matsubara mesh
16 mesh::dlr_imfreq M_iw_mesh{params.beta, Fermion, params.dlr_wmax, params.dlr_eps, true};
17 int64_t n_dlr_pts = M_iw_mesh.size();
18
19 // Init measurement container and capture view
20 results->M_iw_nfft = g_dlr_iw_t{M_iw_mesh, params.gf_struct};
21 M_iw_.rebind(results->M_iw_nfft.value());
22 M_iw_() = 0;
23
24 // Build target matsubara_freq vector
25 target_mf.reserve(n_dlr_pts);
26 for (auto w : M_iw_mesh) target_mf.push_back(w);
27
28 // Initialize M_data arrays and create type 3 NFFT buffers
29 for (int bl : range(params.n_blocks())) {
30 int bl_size = params.gf_struct[bl].second;
31 M_data(bl).resize(n_dlr_pts, bl_size, bl_size);
32 M_data(bl) = 0;
33
34 auto init_func = [&](int i, int j) {
35 return nfft_buf_t<1>{M_data(bl)(nda::range::all, i, j), target_mf, params.nfft_buf_size, nfft_type_t::type3, params.nfft_tol};
36 };
37 buf_vec.emplace_back(array_adapter{std::array{bl_size, bl_size}, init_func});
38 }
39
40 // Initialize M_hartree if not already set (e.g. by M_tau measurement)
41 if (!results->M_hartree) {
42 results->M_hartree = make_block_vector<M_tau_scalar_t>(params.gf_struct);
43 for (auto &m : results->M_hartree.value()) M_hartree_.push_back(m);
44 }
45 }
46
47 void M_iw::accumulate(mc_weight_t sign) {
48 // Accumulate sign
49 Z += sign;
50
51 // Reset intermediate data
52 for (auto &m : M_data) m = 0;
53
54 // Loop over blocks
55 for (int b = 0; b < M_iw_.size(); ++b) {
56 // Loop over every index pair (x,y) in the determinant matrix
57 foreach (qmc_config.dets[b], [&](c_t const &c_i, cdag_t const &cdag_j, auto const &Ginv) {
58 // Handle equal-time case (Hartree term) separately
59 if (c_i.tau == cdag_j.tau) {
60 if (!M_hartree_.empty()) M_hartree_[b](cdag_j.u, c_i.u) += Ginv * sign;
61 } else {
62 // Absolut time-difference tau of the index pair
63 auto [s, dtau] = cyclic_difference(cdag_j.tau, c_i.tau);
64
65 // Push {tau, f(tau)} pair into nfft buffer
66 auto &buf = buf_vec[b](cdag_j.u, c_i.u);
67 buf.push_back({dtau}, Ginv * s * sign);
68 }
69 });
70 }
71
72 // Flush buffers and copy to M_iw_
73 for (auto &buf_arr : buf_vec)
74 for (auto &buf : buf_arr) buf.flush();
75
76 // Copy M_data to M_iw_
77 for (int bl : range(params.n_blocks())) {
78 int bl_size = params.gf_struct[bl].second;
79 auto &M_bl = M_iw_[bl];
80 int64_t idx = 0;
81 for (auto mp : M_bl.mesh()) {
82 for (int i : range(bl_size))
83 for (int j : range(bl_size)) M_bl[mp](i, j) += M_data(bl)(idx, i, j);
84 ++idx;
85 }
86 }
87 }
88
89 void M_iw::collect_results(mpi::communicator const &comm) {
90 // Collect results and normalize
91 Z = mpi::all_reduce(Z, comm);
92 M_iw_ = mpi::all_reduce(M_iw_, comm);
93 M_iw_ = M_iw_ / (-Z * params.beta);
94
95 // Normalize M_hartree (only if M_iw is responsible for it)
96 for (auto &m : M_hartree_) {
97 m = mpi::all_reduce(m, comm);
98 m = m / (-Z * params.beta);
99 }
100 }
101
102} // namespace triqs_ctint::measures
void collect_results(mpi::communicator const &comm)
Collect results and normalize.
Definition M_iw.cpp:89
void accumulate(mc_weight_t sign)
Accumulate M_iw using nfft.
Definition M_iw.cpp:47