TRIQS/triqs_ctint 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
solver_core.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 "./solver_core.hpp"
7#include "./measures.hpp"
8#include "./moves/insert.hpp"
9#include "./moves/remove.hpp"
10#include "./moves/spinflip.hpp"
11#include "./post_process.hpp"
12#include "./qmc_config.hpp"
13#include "./vertex_factories.hpp"
14
15namespace triqs_ctint {
16
18
19 // Set inverse temperature for all $\tau$ points
20 tau_t::beta = p.beta;
21
22 // Allocate essential QMC containers on DLR mesh (symmetrize=true for hermiticity checks)
23 G0_iw = g_iw_t{{p.beta, Fermion, p.dlr_wmax, p.dlr_eps, true}, p.gf_struct};
25 G_iw = G0_iw;
27
28 // Allocate containers for dynamical density-density interaction (DLR bosonic mesh)
29 if (p.use_D) {
30 auto D_mesh = mesh::dlr_imfreq{p.beta, Boson, p.dlr_wmax, p.dlr_eps, true};
31 auto bl_sz = p.gf_struct[0].second;
32 auto bl = p.block_names();
33 auto g0 = gf<mesh::dlr_imfreq, matrix_valued>{D_mesh, make_shape(bl_sz, bl_sz)};
34 D0_iw = block2_gf<mesh::dlr_imfreq, matrix_valued>{{bl, bl}, std::vector(bl.size(), std::vector(bl.size(), g0))};
35 }
36
37 // Allocate containers for dynamical spin-spin interaction (DLR bosonic mesh)
38 if (p.use_Jperp) {
39 auto [bl, bl_size] = p.gf_struct[0];
40 Jperp_iw = gf<mesh::dlr_imfreq, matrix_valued>{{p.beta, Boson, p.dlr_wmax, p.dlr_eps, true}, make_shape(bl_size, bl_size)};
41 }
42 }
43
44 // -------------------------------------------------------------------------------
45
46 void solver_core::solve(solve_params_t const &solve_params) {
47
48 last_solve_params = solve_params;
49
50 // Merge constr_params and solve_params
51 params_t params(constr_params, solve_params);
52
53 // Open new report stream
54 triqs::utility::report_stream report(&std::cout, params.verbosity);
55
56 // http://patorjk.com/software/taag/#p=display&f=Calvin%20S&t=TRIQS%20ctint
57 report(3) << "\n"
58 "╔╦╗╦═╗╦╔═╗ ╔═╗ ┌─┐┌┬┐┬ ┌┐┌┌┬┐\n"
59 " ║ ╠╦╝║║═╬╗╚═╗ │ │ │ │││ │ \n"
60 " ╩ ╩╚═╩╚═╝╚╚═╝ └─┘ ┴ ┴ ┘└┘ ┴ \n";
61
62 // Assert hermiticity of the given Weiss field
63 if (!is_gf_hermitian(G0_iw)) TRIQS_RUNTIME_ERROR << "Please make sure that G0_iw fullfills the hermiticity relation G_ij[iw] = G_ji[-iw]*";
64
65 // Calculate the Weiss field inverse
66 G0_iw_inv = inverse(G0_iw);
67
68 // Prepare shifted non-interacting Green function for QMC
69 prepare_G0_shift_iw(params);
70
71 // --- Calculate G0_shift_tau from G0_shift_iw via DLR
72 auto G0_shift_dlr = make_gf_dlr(G0_shift_iw);
73#ifdef GTAU_IS_COMPLEX
74 G0_shift_tau = make_gf_imtime(G0_shift_dlr, params.n_tau);
75#else
76 G0_shift_tau = real(make_gf_imtime(G0_shift_dlr, params.n_tau));
77#endif
78
79 // Reset the containers
80 container_set::operator=(container_set{});
81
82 // Construct the generic Monte-Carlo solver
83 triqs::mc_tools::mc_generic<mc_weight_t> mc(params.random_name, params.random_seed, params.verbosity);
84
85 // Capture random number generator
86 auto &rng = mc.get_rng();
87
88 // Create Monte-Carlo configuration
89 qmc_config_t qmc_config(params, G0_shift_tau);
90
91 // Build vertex factories
92 const std::vector<vertex_factory_t> vertex_factories = make_vertex_factories(params, rng, D0_iw, Jperp_iw);
93
94 // Eliminate duplicates from the move types
95 if (params.insertion_types.empty()) { params.insertion_types = params.use_double_insertion ? std::vector<int>{1, 2} : std::vector<int>{1}; }
96 std::sort(params.insertion_types.begin(), params.insertion_types.end());
97 std::ignore = std::unique(params.insertion_types.begin(), params.insertion_types.end());
98
99 for (auto &&num_insert : params.insertion_types) {
100 mc.add_move(moves::insert{&qmc_config, vertex_factories, rng, num_insert, params.max_order}, "insert " + std::to_string(num_insert));
101 mc.add_move(moves::remove{&qmc_config, vertex_factories, rng, num_insert, params.max_order}, "remove " + std::to_string(num_insert));
102 }
103 if (params.use_auxiliary_spin_flip) {
104 TRIQS_ASSERT2(params.n_s == 2, "ERROR: Auxiliary spin-flip move requires n_s = 2.");
105 mc.add_move(moves::spinflip{&qmc_config, vertex_factories, rng, /* n_spinflips */ 1, params.max_order}, "auxiliary spin-flip");
106 }
107
108 // Register warmup measurements
109 mc.add_measure(measures::average_sign{params, qmc_config, &result_set()}, "sign measure", /* enable_timer */ true, /* report */ true);
110 mc.add_measure(measures::average_k{params, qmc_config, &result_set()}, "perturbation order measure", /* enable_timer */ true, /* report */ true);
111
112 // Warmup
113 report(3) << "\nWarming up ..." << std::endl;
114 mc.run(params.n_warmup_cycles, params.length_cycle, triqs::utility::clock_callback(params.max_time), /* do_measure */ true);
115 double warmup_time_ = mc.get_accumulation_time();
116
117 // Clear warmup measurements
118 mc.clear_measures();
119 container_set::operator=(container_set{});
120
121 // Register all measurements
122 if (params.measure_average_sign)
123 mc.add_measure(measures::average_sign{params, qmc_config, &result_set()}, "sign measure", /* enable_timer */ true, /* report */ true);
124 if (params.measure_average_k)
125 mc.add_measure(measures::average_k{params, qmc_config, &result_set()}, "perturbation order measure", /* enable_timer */ true,
126 /* report */ true);
127 if (params.measure_auto_corr_time) mc.add_measure(measures::auto_corr_time{params, qmc_config, &result_set()}, "Auto-correlation time");
128 if (params.measure_sign_only) {
129 report(3) << "You selected Sign only mode" << std::endl;
130 } else {
131 if (params.measure_histogram) mc.add_measure(measures::histogram{params, qmc_config, &result_set()}, "perturbation order histogram measure");
132 if (params.measure_density) mc.add_measure(measures::density{params, qmc_config, &result_set()}, "density matrix measure");
133 if (params.measure_M_tau) mc.add_measure(measures::M_tau{params, qmc_config, &result_set()}, "M_tau measure");
134 if (params.measure_M_iw) mc.add_measure(measures::M_iw{params, qmc_config, &result_set()}, "M_iw measure");
135 if (params.measure_M4_iw) mc.add_measure(measures::M4_iw{params, qmc_config, &result_set()}, "M4_iw measure");
136 if (params.measure_M4pp_iw) mc.add_measure(measures::M4pp_iw{params, qmc_config, &result_set()}, "M4pp_iw measure");
137 if (params.measure_M4ph_iw) mc.add_measure(measures::M4ph_iw{params, qmc_config, &result_set()}, "M4ph_iw measure");
138 if (params.measure_M3pp_iw) mc.add_measure(measures::M3pp_iw{params, qmc_config, &result_set(), G0_shift_tau}, "M3pp_iw measure");
139 if (params.measure_M3ph_iw) mc.add_measure(measures::M3ph_iw{params, qmc_config, &result_set(), G0_shift_tau}, "M3ph_iw measure");
140 if (params.measure_M3pp_tau) mc.add_measure(measures::M3pp_tau{params, qmc_config, &result_set(), G0_shift_tau}, "M3pp_tau measure");
141 if (params.measure_M3ph_tau) mc.add_measure(measures::M3ph_tau{params, qmc_config, &result_set(), G0_shift_tau}, "M3ph_tau measure");
142 if (params.measure_M3xph_tau) mc.add_measure(measures::M3xph_tau{params, qmc_config, &result_set(), G0_shift_tau}, "M3xph_tau measure");
143 if (params.measure_chi2pp_tau) mc.add_measure(measures::chi2_tau<Chan_t::PP>{params, qmc_config, &result_set()}, "chi2pp_tau measure");
144 if (params.measure_chi2ph_tau) mc.add_measure(measures::chi2_tau<Chan_t::PH>{params, qmc_config, &result_set()}, "chi2ph_tau measure");
145 if (params.measure_chiAB_tau) mc.add_measure(measures::chiAB_tau{params, qmc_config, &result_set()}, "chiAB_tau measure");
146 }
147
148 // Perform QMC run and collect results
149 report(3) << "\nAccumulating ..." << std::endl;
150 mc.run(params.n_cycles, params.length_cycle, triqs::utility::clock_callback(params.max_time), /* do_measure */ true);
151 double accumulation_time_ = mc.get_accumulation_time();
152 mc.collect_results(world);
153 warmup_time = mpi::all_reduce(warmup_time_, world, MPI_MAX);
154 accumulation_time = mpi::all_reduce(accumulation_time_, world, MPI_MAX);
155
156 if (params.measure_average_sign) report(3) << "Average sign: " << average_sign << "\n";
157 if (params.measure_average_k) report(3) << "Average perturbation order: " << average_k << "\n";
158 if (params.measure_auto_corr_time) report(3) << "Auto-correlation time: " << auto_corr_time << "\n";
159
160 // Post Processing
161 if (params.post_process) { post_process(params); }
162 }
163
164 // -------------------------------------------------------------------------------
165
166 // Prepare shifted non-interacting Green Function G0_shift_iw for Monte Carlo
167 // with renormalization of the chemical potential due to alpha
169
170 // Container that will hold the inverse of the shifted Green function
171 g_iw_t G0_shift_iw_inv = G0_iw_inv;
172
173 // Assert compatibility between alpha tensor and h_int (+ D0 extension)
174 long n_h_int = std::distance(p.h_int.begin(), p.h_int.end());
175 long n_D0_total = 0;
176 if (D0_iw) {
177 long n_bl = p.n_blocks();
178 long R = (*D0_iw)(0, 0).target_shape()[0];
179 n_D0_total = n_bl * n_bl * R * R;
180 }
181 if (p.alpha.shape() != std::array<long, 4>{n_h_int + n_D0_total, 2, 2, p.n_s})
182 TRIQS_RUNTIME_ERROR << "Alpha tensor shape " << p.alpha.shape() << " incompatible with h_int (" << n_h_int << " terms) + D0 (" << n_D0_total
183 << " entries)\n";
184
185 // Loop over static density-density interaction terms
186 for (auto const &[n, term] : enumerate(p.h_int)) {
187 auto &m = term.monomial;
188
189 if (m[0].indices[0] != m[3].indices[0] or m[1].indices[0] != m[2].indices[0])
190 TRIQS_RUNTIME_ERROR << "Interaction term with incompatible block structure: cdag_1 cdag_2 c_2 c_1 required";
191
192 auto [bl_0, idx_cdag_0] = get_int_indices(m[0], p.gf_struct);
193 auto [bl_1, idx_cdag_1] = get_int_indices(m[1], p.gf_struct);
194 auto [bl_c_1, idx_c_1] = get_int_indices(m[2], p.gf_struct);
195 auto [bl_c_0, idx_c_0] = get_int_indices(m[3], p.gf_struct);
196
197 // Shift equal-time Green function components according to alpha-tensor
198 for (long s : range(p.n_s)) {
199 G0_shift_iw_inv[bl_0].data()(range::all, idx_cdag_0, idx_c_0) -= p.alpha(n, 1, 1, s) * U_scalar_t(term.coef) / p.n_s;
200 G0_shift_iw_inv[bl_1].data()(range::all, idx_cdag_1, idx_c_1) -= p.alpha(n, 0, 0, s) * U_scalar_t(term.coef) / p.n_s;
201 if (bl_0 == bl_1) { // Cross terms are only possible for equal blocks
202 G0_shift_iw_inv[bl_0].data()(range::all, idx_cdag_0, idx_c_1) += p.alpha(n, 1, 0, s) * U_scalar_t(term.coef) / p.n_s;
203 G0_shift_iw_inv[bl_1].data()(range::all, idx_cdag_1, idx_c_0) += p.alpha(n, 0, 1, s) * U_scalar_t(term.coef) / p.n_s;
204 }
205 }
206 }
207
208 if (D0_iw) {
209
210 int n_bl = p.n_blocks();
211 int R = (*D0_iw)(0, 0).target_shape()[0];
212
213 // Extract per-orbital density from D0 alpha entries (averaged over aux spin s)
214 // D0 alpha label = n_h_int + sigp * n_bl * R * R + bl2 * R * R + j * R + b
215 // alpha[label, 0, 0, s] = density[sigp][j,j] + delta_shift(s)
216 // Averaging over s cancels the delta shift
217 std::vector<std::vector<double>> block_density(n_bl);
218 for (int sigp : range(n_bl)) {
219 block_density[sigp].resize(R, 0.0);
220 for (int j : range(R)) {
221 long label = n_h_int + sigp * n_bl * R * R + 0 * R * R + j * R + 0;
222 for (int s : range(p.n_s)) block_density[sigp][j] += p.alpha(label, 0, 0, s);
223 block_density[sigp][j] /= p.n_s;
224 }
225 }
226
227 // Precompute D0 at iw=0 (static Hartree contribution) for all block pairs
228 std::vector<std::vector<matrix<dcomplex>>> D0_static(n_bl, std::vector<matrix<dcomplex>>(n_bl));
229 for (int b1 : range(n_bl))
230 for (int b2 : range(n_bl)) D0_static[b1][b2] = make_gf_imfreq(make_gf_dlr((*D0_iw)(b1, b2)), 1)(0);
231
232 for (int sig : range(n_bl)) {
233 for (int i : range(R)) {
234 dcomplex shift = 0.0;
235 for (int sigp : range(n_bl))
236 for (int j : range(R)) shift += (D0_static[sig][sigp](i, j) + D0_static[sigp][sig](j, i)) * block_density[sigp][j];
237 G0_shift_iw_inv[sig].data()(range::all, i, i) -= shift;
238 }
239 }
240 }
241
242 // Invert
243 G0_shift_iw = inverse(G0_shift_iw_inv);
244 }
245
246 // -------------------------------------------------------------------------------
247
248 void solver_core::post_process(params_t const &p) {
249
250 if (world.rank() == 0)
251 std::cout << "\n"
252 "Post-processing ... \n";
253
254 // --- Determine M_iw (M_dyn only, no Hartree) from either NFFT or FT of M_tau
255 if (M_iw_nfft) {
256 M_iw = g_iw_t{M_iw_nfft.value()}; // Direct DLR measurement (M_dyn only)
257 } else if (M_tau) {
258 // DLR fit of M_tau gives M_dyn only (continuous part, no equal-time delta)
259 // Cast from M_tau_target_t (possibly matrix_real_valued) to matrix_valued for DLR fit
260 auto const &mt = *M_tau;
261 std::vector<gf<imtime, matrix_valued>> gf_vec;
262 for (int b = 0; b < mt.size(); ++b) gf_vec.emplace_back(mt[b]);
263 auto M_tau_cast = block_gf<imtime, matrix_valued>{mt.block_names(), std::move(gf_vec)};
264 auto M_dlr = fit_gf_dlr(M_tau_cast, p.dlr_wmax, p.dlr_eps, true);
265 M_iw = g_iw_t{make_gf_dlr_imfreq(M_dlr)};
266 }
267
268 // Helper: build M_full = M_dyn + M_hartree (add constant Hartree term to each DLR point)
269 auto make_M_full = [&]() {
270 g_iw_t M_full = M_iw.value();
271 for (auto [M_bl, M_h_bl] : zip(M_full, M_hartree.value()))
272 for (long d = 0; d < M_bl.mesh().size(); ++d) M_bl.data()(d, ellipsis()) += M_h_bl;
273 return M_full;
274 };
275
276 // --- Calculate G_iw and Sigma decomposition from M_iw
277 if (M_iw) {
278 // Re-initialize G_iw and Sigma_dyn_iw (were reset by container_set::operator=)
279 G_iw = G0_shift_iw;
280 Sigma_dyn_iw = G0_shift_iw;
281
282 auto M_full = make_M_full();
283
284 // G_iw = G0_shift + G0_shift * M_full * G0_shift (Dyson equation at DLR points)
285 for (auto [G_bl, G0_bl, M_bl] : zip(G_iw, G0_shift_iw, M_full))
286 for (auto iw : G_bl.mesh()) G_bl[iw] = G0_bl[iw] + G0_bl[iw] * M_bl[iw] * G0_bl[iw];
287
288 // Sigma_dyn = G0_shift^{-1} - G^{-1} - M_hartree (decays to zero)
289 auto G0_shift_iw_inv = inverse(G0_shift_iw);
290 auto G_iw_inv = inverse(G_iw);
291 for (auto [S_bl, G0s_bl, Gi_bl, M_h_bl] : zip(Sigma_dyn_iw, G0_shift_iw_inv, G_iw_inv, M_hartree.value()))
292 for (auto iw : S_bl.mesh()) S_bl[iw] = G0s_bl[iw] - Gi_bl[iw] - M_h_bl;
293
294 // Sigma_hartree = Sigma_alpha + M_hartree = (G0^{-1} - G0_shift^{-1}) + M_hartree
295 Sigma_hartree = make_block_vector<M_tau_scalar_t>(p.gf_struct);
296 for (int bl : range(p.n_blocks())) {
297 Sigma_hartree.value()[bl] = real(matrix<dcomplex>(G0_iw_inv[bl].data()(0, ellipsis()) - G0_shift_iw_inv[bl].data()(0, ellipsis())))
298 + M_hartree.value()[bl];
299 }
300 }
301
302 // --- Convert DLR quantities to regular imfreq for higher-order post-processing
303 int n_iw_pp = std::max({p.n_iw_M4 + p.n_iW_M4, p.n_iw_M3 + p.n_iW_M3, p.n_iw_chi2}) + 10;
304 g_reg_iw_t G0_shift_iw_reg = make_gf_imfreq(G0_shift_iw, n_iw_pp);
305
306 std::optional<g_reg_iw_t> M_iw_reg;
307 if (M_iw) M_iw_reg = make_gf_imfreq(make_M_full(), n_iw_pp);
308 g_reg_iw_t G_iw_reg = make_gf_imfreq(G_iw, n_iw_pp);
309
310 // Calculate M3_iw from M3_tau
311 if (M3pp_tau) {
312 {
313 auto iW_mesh = mesh::imfreq{p.beta, Boson, p.n_iW_M3};
314 auto iw_mesh = mesh::imfreq{p.beta, Fermion, p.n_iw_M3};
315 auto iw_mesh_large = mesh::imfreq{p.beta, Fermion, p.n_iw_M3 + p.n_iW_M3};
316 auto M3pp_ferm_iw = make_gf_from_fourier<0, 1>(M3pp_tau.value(), iw_mesh, iw_mesh_large);
317 auto M3pp_del_iW = make_gf_from_fourier(M3pp_delta.value(), iW_mesh, make_zero_tail(M3pp_delta.value()));
318 M3pp_iw = make_block2_gf(prod{iW_mesh, iw_mesh}, p.gf_struct);
319
320 // Shift from fermionic to mixed particle-particle frequency notation
321 M3pp_iw.value()(bl1_, bl2_)(iW_, iw_)(i_, j_, k_, l_)
322 << M3pp_ferm_iw(bl1_, bl2_)(iw_, iW_ - iw_)(i_, j_, k_, l_) + M3pp_del_iW(bl1_, bl2_)(iW_)(i_, j_, k_, l_);
323 }
324
325 if (M_iw_reg && density) {
326 chi2pp_conn_tau_from_M3 = chi2_conn_from_M3<Chan_t::PP>(M3pp_tau.value(), M3pp_delta.value(), M_iw_reg.value(), G0_shift_iw_reg, M_tau.value(),
327 M_hartree.value(), G0_shift_tau);
328 chi2pp_tau_from_M3 = chi2_from_chi2_conn<Chan_t::PP>(chi2pp_conn_tau_from_M3.value(), G_iw_reg, density.value());
329 auto iw_mesh = mesh::imfreq{p.beta, Boson, p.n_iw_chi2};
330 chi2pp_iw_from_M3 = make_gf_from_fourier(chi2pp_tau_from_M3.value(), iw_mesh, make_zero_tail(chi2pp_tau_from_M3.value()));
331 }
332 }
333 if (M3ph_tau) {
334 {
335 auto iW_mesh = mesh::imfreq{p.beta, Boson, p.n_iW_M3};
336 auto iw_mesh = mesh::imfreq{p.beta, Fermion, p.n_iw_M3};
337 auto iw_mesh_large = mesh::imfreq{p.beta, Fermion, p.n_iw_M3 + p.n_iW_M3};
338 auto M3ph_ferm_iw = make_gf_from_fourier<0, 1>(M3ph_tau.value(), iw_mesh, iw_mesh_large);
339 auto M3ph_del_iW = make_gf_from_fourier(M3ph_delta.value(), iW_mesh, make_zero_tail(M3ph_delta.value()));
340 M3ph_iw = make_block2_gf(prod{iW_mesh, iw_mesh}, p.gf_struct);
341
342 // Shift from fermionic to mixed particle-hole frequency notation
343 // CAUTION! The first time should be fourier transformed with e^{-iwt}
344 // We correct this with an overall minus sign for the first frequency
345 M3ph_iw.value()(bl1_, bl2_)(iW_, iw_)(i_, j_, k_, l_)
346 << M3ph_ferm_iw(bl1_, bl2_)(-iw_, iW_ + iw_)(i_, j_, k_, l_) + M3ph_del_iW(bl1_, bl2_)(iW_)(i_, j_, k_, l_);
347 }
348
349 if (M_iw_reg && density) {
350 chi2ph_conn_tau_from_M3 = chi2_conn_from_M3<Chan_t::PH>(M3ph_tau.value(), M3ph_delta.value(), M_iw_reg.value(), G0_shift_iw_reg, M_tau.value(),
351 M_hartree.value(), G0_shift_tau);
352 chi2ph_tau_from_M3 = chi2_from_chi2_conn<Chan_t::PH>(chi2ph_conn_tau_from_M3.value(), G_iw_reg, density.value());
353 auto iw_mesh = mesh::imfreq{p.beta, Boson, p.n_iw_chi2};
354 chi2ph_iw_from_M3 = make_gf_from_fourier(chi2ph_tau_from_M3.value(), iw_mesh, make_zero_tail(chi2ph_tau_from_M3.value()));
355 }
356 }
357 if (M3xph_tau) {
358 {
359 auto iw_mesh = mesh::imfreq{p.beta, Fermion, p.n_iw_M3};
360 auto iW_mesh = mesh::imfreq{p.beta, Boson, p.n_iW_M3};
361 auto iw_mesh_large = mesh::imfreq{p.beta, Fermion, p.n_iw_M3 + p.n_iW_M3};
362 auto M3xph_ferm_iw = make_gf_from_fourier<0, 1>(M3xph_tau.value(), iw_mesh, iw_mesh_large);
363 auto M3xph_del_iW = make_gf_from_fourier(M3xph_delta.value(), iW_mesh, make_zero_tail(M3xph_delta.value()));
364 M3xph_iw = make_block2_gf(mesh::prod{iW_mesh, iw_mesh}, p.gf_struct);
365
366 // Shift from fermionic to mixed particle-hole-cross frequency notation
367 // CAUTION! The first time should be fourier transformed with e^{-iwt}
368 // We correct this with an overall minus sign for the first frequency
369 M3xph_iw.value()(bl1_, bl2_)(iW_, iw_)(i_, j_, k_, l_)
370 << M3xph_ferm_iw(bl1_, bl2_)(iW_ + iw_, -iw_)(i_, j_, k_, l_) + M3xph_del_iW(bl1_, bl2_)(iW_)(i_, j_, k_, l_);
371 }
372
373 if (M_iw_reg && density) {
374 chi2xph_conn_tau_from_M3 = chi2_conn_from_M3<Chan_t::XPH>(M3xph_tau.value(), M3xph_delta.value(), M_iw_reg.value(), G0_shift_iw_reg, M_tau.value(),
375 M_hartree.value(), G0_shift_tau);
376 chi2xph_tau_from_M3 = chi2_from_chi2_conn<Chan_t::XPH>(chi2xph_conn_tau_from_M3.value(), G_iw_reg, density.value());
377 auto iw_mesh = mesh::imfreq{p.beta, Boson, p.n_iw_chi2};
378 chi2xph_iw_from_M3 = make_gf_from_fourier(chi2xph_tau_from_M3.value(), iw_mesh, make_zero_tail(chi2xph_tau_from_M3.value()));
379 }
380 }
381
382 // Calculate G2_conn_iw, F_iw and G2_iw from M4_iw and M_iw (using regular imfreq quantities)
383 if (M4_iw and M_iw_reg) G2_conn_iw = G2_conn_from_M4(M4_iw.value(), M_iw_reg.value(), G0_shift_iw_reg);
384 if (M4pp_iw and M_iw_reg) G2pp_conn_iw = G2pp_conn_from_M4pp(M4pp_iw.value(), M_iw_reg.value(), G0_shift_iw_reg);
385 if (M4ph_iw and M_iw_reg) G2ph_conn_iw = G2ph_conn_from_M4ph(M4ph_iw.value(), M_iw_reg.value(), G0_shift_iw_reg);
386
387 if (G2_conn_iw and M_iw_reg) F_iw = F_from_G2c(G2_conn_iw.value(), G_iw_reg);
388 if (G2pp_conn_iw and M_iw_reg) Fpp_iw = Fpp_from_G2pp_conn(G2pp_conn_iw.value(), G_iw_reg);
389 if (G2ph_conn_iw and M_iw_reg) Fph_iw = Fph_from_G2ph_conn(G2ph_conn_iw.value(), G_iw_reg);
390
391 if (G2_conn_iw and M_iw_reg) G2_iw = G2_from_G2c(G2_conn_iw.value(), G_iw_reg);
392 if (G2pp_conn_iw and M_iw_reg) G2pp_iw = G2pp_from_G2pp_conn(G2pp_conn_iw.value(), G_iw_reg);
393 if (G2ph_conn_iw and M_iw_reg) G2ph_iw = G2ph_from_G2ph_conn(G2ph_conn_iw.value(), G_iw_reg);
394
395 // Calculate chi3_iw from M3_iw and M_iw (using regular imfreq quantities)
396 if (M3pp_iw and M_iw_reg and density) chi3pp_iw = chi3_from_M3<Chan_t::PP>(M3pp_iw.value(), M_iw_reg.value(), G0_shift_iw_reg, density.value(), M_hartree.value());
397 if (M3ph_iw and M_iw_reg and density) chi3ph_iw = chi3_from_M3<Chan_t::PH>(M3ph_iw.value(), M_iw_reg.value(), G0_shift_iw_reg, density.value(), M_hartree.value());
398 if (M3xph_iw and M_iw_reg and density) chi3xph_iw = chi3_from_M3<Chan_t::XPH>(M3xph_iw.value(), M_iw_reg.value(), G0_shift_iw_reg, density.value(), M_hartree.value());
399 if (M3pp_iw_nfft and M_iw_reg and density)
400 chi3pp_iw_nfft = chi3_from_M3<Chan_t::PP>(M3pp_iw_nfft.value(), M_iw_reg.value(), G0_shift_iw_reg, density.value(), M_hartree.value());
401 if (M3ph_iw_nfft and M_iw_reg and density)
402 chi3ph_iw_nfft = chi3_from_M3<Chan_t::PH>(M3ph_iw_nfft.value(), M_iw_reg.value(), G0_shift_iw_reg, density.value(), M_hartree.value());
403
404 // Calculate chi2_iw from chi2_tau
405 auto iw_mesh = mesh::imfreq{p.beta, Boson, p.n_iw_chi2};
406 if (chi2pp_tau) chi2pp_iw = make_gf_from_fourier(chi2pp_tau.value(), iw_mesh, make_zero_tail(chi2pp_tau.value()));
407 if (chi2ph_tau) chi2ph_iw = make_gf_from_fourier(chi2ph_tau.value(), iw_mesh, make_zero_tail(chi2ph_tau.value()));
408
409 // Calculate chiAB_iw from chiAB_tau
410 if (chiAB_tau) chiAB_iw = make_gf_from_fourier(chiAB_tau.value(), iw_mesh, make_zero_tail(chiAB_tau.value()));
411 }
412
413} // namespace triqs_ctint
Type of the Monte-Carlo configuration.
g_iw_t G0_iw
Non-interacting Green's function in Matsubara frequencies.
solver_core(constr_params_t const &constr_params_)
Construct a CT-INT solver.
void solve(solve_params_t const &solve_params)
constr_params_t constr_params
Parameters used to construct the solver.
C2PY_IGNORE void prepare_G0_shift_iw(params_t const &params)
Calculate the shifted non-interacting Green's function given .
std::optional< solve_params_t > last_solve_params
Parameters used in the last solve (empty until the solver has been run).
g_iw_t G0_shift_iw
The shifted non-interacting Green's function in Matsubara frequencies.
std::optional< block2_gf< mesh::dlr_imfreq, matrix_valued > > D0_iw
Dynamic density-density interaction in Matsubara frequencies (DLR mesh).
std::optional< gf< mesh::dlr_imfreq, matrix_valued > > Jperp_iw
Dynamic spin-spin interaction in Matsubara frequencies (DLR mesh).
g_tau_t G0_shift_tau
The shifted non-interacting Green's function in imaginary time.
g_iw_t G0_iw_inv
Inverse of the non-interacting Green's function .
Parameters used for constructing the solver class.
Definition params.hpp:13
double dlr_eps
DLR error tolerance for the single-particle quantities.
Definition params.hpp:22
int n_tau
Number of imaginary-time points for the single-particle quantities.
Definition params.hpp:16
int n_blocks() const
Number of blocks of the Green's function.
Definition params.hpp:40
auto block_names() const
Names of the blocks of the Green's function.
Definition params.hpp:43
double beta
Inverse temperature .
Definition params.hpp:25
gf_struct_t gf_struct
Structure of the Green's function (names and sizes of blocks).
Definition params.hpp:28
bool use_D
Use a dynamic density-density interaction?
Definition params.hpp:31
double dlr_wmax
DLR bandwidth cutoff for the single-particle quantities.
Definition params.hpp:19
Container for all (optional) quantities measured and post-processed by the solver.
double accumulation_time
Accumulation time in seconds.
double average_k
Average perturbation order.
g_iw_t Sigma_dyn_iw
Dynamic self-energy in Matsubara frequencies (DLR, decays to zero).
g_iw_t G_iw
Green's function in Matsubara frequencies.
double warmup_time
Warmup time in seconds.
mc_weight_t average_sign
Average Monte-Carlo sign.
double auto_corr_time
Auto-correlation time.
Measurement of the auto-correlation time based on perturbation order and diagonal densities.
Measure of the average perturbation order.
Definition average_k.hpp:14
Measure of the average sign.
The move that inserts one or multiple vertices into the configuration.
Definition insert.hpp:15
The move that removes one or multiple vertices from the configuration.
Definition remove.hpp:15
The move that spinflips one or multiple vertices from the configuration.
Definition spinflip.hpp:10
A struct combining both constr_params_t and solve_params_t.
Definition params.hpp:210
Parameters passed to the solve method of the solver class.
Definition params.hpp:57
int n_iw_chi2
Number of positive Matsubara frequencies in .
Definition params.hpp:169
std::string random_name
Name of the random number generator.
Definition params.hpp:85
bool measure_density
Measure the density by operator insertion?
Definition params.hpp:126
int n_iw_M3
Number of positive fermionic Matsubara frequencies in .
Definition params.hpp:150
bool measure_chiAB_tau
Measure by insertion?
Definition params.hpp:172
bool measure_M_tau
Measure ?
Definition params.hpp:129
int max_order
Maximum perturbation order accepted during insertion and removal moves (use -1 for unlimited).
Definition params.hpp:100
bool measure_chi2ph_tau
Measure by insertion?
Definition params.hpp:165
int length_cycle
Length of a single QMC cycle.
Definition params.hpp:76
bool post_process
Perform post-processing?
Definition params.hpp:185
bool use_auxiliary_spin_flip
Use auxiliary spin-flip insertion (requires )?
Definition params.hpp:94
int n_iW_M4
Number of positive bosonic Matsubara frequencies in .
Definition params.hpp:141
bool measure_M_iw
Measure using NFFT?
Definition params.hpp:132
int max_time
Maximum runtime in seconds, use -1 to set infinite.
Definition params.hpp:97
bool measure_auto_corr_time
Measure the auto-correlation time?
Definition params.hpp:120
bool measure_M3xph_tau
Measure ?
Definition params.hpp:158
int n_s
Number of auxiliary spins.
Definition params.hpp:67
bool measure_histogram
Measure the perturbation-order distribution?
Definition params.hpp:123
std::vector< int > insertion_types
Types of insertions to use.
Definition params.hpp:91
int n_cycles
Number of QMC cycles.
Definition params.hpp:73
bool measure_chi2pp_tau
Measure by insertion?
Definition params.hpp:163
bool measure_M3ph_tau
Measure ?
Definition params.hpp:156
bool measure_M4pp_iw
Measure using NFFT?
Definition params.hpp:137
int verbosity
Verbosity level.
Definition params.hpp:103
int n_iW_M3
Number of positive bosonic Matsubara frequencies in .
Definition params.hpp:152
bool measure_M4_iw
Measure using NFFT?
Definition params.hpp:135
bool measure_M4ph_iw
Measure using NFFT?
Definition params.hpp:139
bool measure_M3ph_iw
Measure ?
Definition params.hpp:148
alpha_t alpha
The tensor used in the determinantal expansion.
Definition params.hpp:70
bool measure_average_k
Measure the average perturbation order?
Definition params.hpp:117
many_body_operator h_int
Interacting part of the local Hamiltonian.
Definition params.hpp:62
bool measure_sign_only
Measure the sign only?
Definition params.hpp:111
int n_iw_M4
Number of positive fermionic Matsubara frequencies in .
Definition params.hpp:143
int n_warmup_cycles
Number of cycles for thermalization.
Definition params.hpp:79
bool measure_M3pp_iw
Measure ?
Definition params.hpp:146
bool measure_M3pp_tau
Measure ?
Definition params.hpp:154
bool use_double_insertion
Use double insertion?
Definition params.hpp:88
int random_seed
Seed for the random number generator.
Definition params.hpp:82
bool measure_average_sign
Measure the Monte-Carlo sign?
Definition params.hpp:114
static double beta
Inverse temperature associated with all $\tau$ points.
Definition vertex.hpp:23