TRIQS/triqs_cthyb 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
O_tau_ins.cpp
1/*******************************************************************************
2 *
3 * TRIQS: a Toolbox for Research in Interacting Quantum Systems
4 *
5 * Copyright (C) 2018, The Simons Foundation
6 * Author: H. U.R. Strand
7 *
8 * TRIQS is free software: you can redistribute it and/or modify it under the
9 * terms of the GNU General Public License as published by the Free Software
10 * Foundation, either version 3 of the License, or (at your option) any later
11 * version.
12 *
13 * TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
14 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * TRIQS. If not, see <http://www.gnu.org/licenses/>.
20 *
21 ******************************************************************************/
22
23#include <triqs/mc_tools.hpp>
24
25#include "./O_tau_ins.hpp"
26
27namespace triqs_cthyb {
28
29 using namespace triqs::gfs;
30 using namespace triqs::mesh;
31
32 measure_O_tau_ins::measure_O_tau_ins(std::optional<gf<imtime, scalar_valued>> &O_tau_opt, qmc_data const &data, int n_tau,
33 many_body_op_t const &op1, many_body_op_t const &op2, int min_ins, mc_tools::random_generator &rng)
34 : data(data), average_sign(0), op1(op1), op2(op2), min_ins(min_ins), rng(rng) {
35 O_tau_opt = gf<imtime, scalar_valued>{{data.config.beta(), Boson, n_tau}};
36 O_tau.rebind(*O_tau_opt);
37 O_tau() = 0.0;
38
39 op1_d = data.imp_trace.attach_aux_operator(op1);
40 op2_d = data.imp_trace.attach_aux_operator(op2);
41 }
42
43 void measure_O_tau_ins::accumulate(mc_weight_t s) {
44 s *= data.atomic_reweighting;
45 average_sign += s;
46
47 int pto = 0;
48 for (const auto &det : data.dets) pto += det.size();
49 int nsamples = pto * pto;
50 if( nsamples < min_ins ) nsamples = min_ins;
51
52 mc_weight_t atomic_weight, atomic_reweighting;
53 auto [bare_atomic_weight, bare_atomic_reweighting] = data.imp_trace.compute();
54 const auto prefactor = s / bare_atomic_weight / bare_atomic_reweighting / double(nsamples);
55
56 for ([[maybe_unused]] int i : range(nsamples)) {
57 auto tau1 = data.tau_seg.get_random_pt(rng);
58 auto tau2 = data.tau_seg.get_random_pt(rng);
59 double dtau = double(tau2 - tau1);
60
61 try {
62 data.imp_trace.try_insert(tau1, op1_d);
63 data.imp_trace.try_insert(tau2, op2_d);
64 std::tie(atomic_weight, atomic_reweighting) = data.imp_trace.compute();
65 } catch (rbt_insert_error const &) { atomic_weight = 0.; }
66
67 data.imp_trace.cancel_insert();
68 O_tau[closest_mesh_pt(dtau)] += prefactor * atomic_weight * atomic_reweighting;
69 }
70 }
71
72 void measure_O_tau_ins::collect_results(mpi::communicator const &c) {
73 O_tau = mpi::all_reduce(O_tau, c);
74 average_sign = mpi::all_reduce(average_sign, c);
75
76 O_tau *= double(O_tau.mesh().size() - 1) / real(average_sign);
77
78 // Assuming commuting operators so that O(0) = O(beta)
79 // use that to counter the half-sized edge bind, by taking the average
80 // on the boundary
81
82 int last = O_tau.mesh().size() - 1;
83 auto average = O_tau[0] + O_tau[last];
84
85 O_tau[0] = average;
86 O_tau[last] = average;
87 }
88} // namespace triqs_cthyb