TRIQS/triqs_ctint 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
vertex_factories.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 "./vertex_factories.hpp"
7#include "types.hpp"
8
9namespace triqs_ctint {
10
11 std::vector<vertex_factory_t> make_vertex_factories(params_t const &params, triqs::mc_tools::random_generator &rng,
12 std::optional<block2_gf_const_view<mesh::dlr_imfreq, matrix_valued>> D0_iw,
13 std::optional<gf_const_view<mesh::dlr_imfreq, matrix_valued>> Jperp_iw) {
14
15 std::vector<vertex_factory_t> vertex_factories;
16
17 // ------------ Create Vertex Factory for Static Interactions --------------
18 {
19 std::vector<vertex_idx_t> indices;
20 std::vector<U_scalar_t> amplitudes;
21
22 // Loop over the interaction hamiltonian and insert the corresponding indices/amplitiudes into the lists for the factory
23 for (auto const &term : params.h_int) {
24 amplitudes.push_back(-U_scalar_t(term.coef));
25 auto const &m = term.monomial;
26 if (m.size() != 4 or !(m[0].dagger and m[1].dagger and !m[2].dagger and !m[3].dagger))
27 TRIQS_RUNTIME_ERROR << " Monimial in h_int is not of the form c^+ c^+ c c \n";
28 // Careful: h_int monomials automatically ordered as c^+_0 c^+_1 c_2 c_3
29 auto [bl_cdag_0, idx_cdag_0] = get_int_indices(m[0], params.gf_struct);
30 auto [bl_cdag_1, idx_cdag_1] = get_int_indices(m[1], params.gf_struct);
31 auto [bl_c_1, idx_c_1] = get_int_indices(m[2], params.gf_struct);
32 auto [bl_c_0, idx_c_0] = get_int_indices(m[3], params.gf_struct);
33
34 indices.push_back({bl_cdag_0, idx_cdag_0, bl_c_0, idx_c_0, bl_cdag_1, idx_cdag_1, bl_c_1, idx_c_1});
35 }
36
37 if (indices.size() > 0) {
38 // Construct the factory and insert into list
39 auto l = [beta = params.beta, n_s = params.n_s, indices = std::move(indices), amplitudes = std::move(amplitudes), &rng] {
40 int n = rng(indices.size());
41 tau_t t = tau_t::get_random(rng);
42 int s = rng(n_s);
43 double prop_proba = 1.0 / (beta * indices.size() * n_s);
44 return vertex_t{indices[n], t, t, t, t, amplitudes[n] / n_s, prop_proba, n, s};
45 };
46
47 vertex_factories.emplace_back(l);
48 }
49 } // clean temporaries
50
51 // ------------ Create Vertex Factory for Dynamic Density-Density Interactions --------------
52 if (D0_iw) {
53
54 std::vector<vertex_idx_t> indices;
55 std::vector<int> labels;
56#ifdef INTERACTION_IS_COMPLEX
57 std::vector<gf<imtime, scalar_valued>> D0_tau_lst;
58#else
59 std::vector<gf<imtime, scalar_real_valued>> D0_tau_lst;
60#endif
61
62 // Deterministic vertex label offset: D0 labels start after h_int terms
63 long n_h_int = std::distance(params.h_int.begin(), params.h_int.end());
64
65 // Convert DLR D0_iw -> D0_tau via DLR coefficients and loop over block indices
66 int n_bl = (*D0_iw).size1();
67 int R = (*D0_iw)(0, 0).target_shape()[0];
68 for (int bl1 : range(n_bl))
69 for (int bl2 : range(n_bl)) {
70 auto D0_tau_bl = make_gf_imtime(make_gf_dlr((*D0_iw)(bl1, bl2)), params.n_tau_dynamical_interactions);
71
72 // Loop over non-block indices
73 for (int a = 0; a < D0_tau_bl.target_shape()[0]; a++)
74 for (int b = 0; b < D0_tau_bl.target_shape()[1]; b++) {
75 auto d = slice_target_to_scalar(D0_tau_bl, a, b);
76
77 // Add Vertex generator only if d is non-zero
78 if (max_norm(d) > 1e-10) {
79 indices.push_back({bl1, a, bl1, a, bl2, b, bl2, b});
80 labels.push_back(n_h_int + bl1 * n_bl * R * R + bl2 * R * R + a * R + b);
81#ifdef INTERACTION_IS_COMPLEX
82 D0_tau_lst.emplace_back(d);
83#else
84 if (!is_gf_real(d, 1e-8))
85 std::cerr << "WARNING: Assuming real interaction values, but found Imag(D0(tau)) > 1e-8. Casting to Real.\n";
86 D0_tau_lst.emplace_back(real(d));
87#endif
88 }
89 }
90 }
91
92 if (indices.size() > 0) {
93 auto l = [beta = params.beta, n_s = params.n_s, indices = std::move(indices), labels = std::move(labels), D0_tau_lst = std::move(D0_tau_lst),
94 &rng] {
95 int n = rng(indices.size());
96 tau_t t = tau_t::get_random(rng);
97 tau_t tp = tau_t::get_random(rng);
98 auto [sig, dtau] = cyclic_difference(t, tp);
99 int s = rng(n_s);
100 double prop_proba = 1.0 / (beta * beta * indices.size() * n_s);
101 return vertex_t{indices[n], t, t, tp, tp, -D0_tau_lst[n](dtau) / n_s, prop_proba, labels[n], s};
102 };
103
104 vertex_factories.emplace_back(l);
105 }
106 }
107
108 // ------------ Create Vertex Factory for Dynamic Spin-Spin Interactions --------------
109 if (Jperp_iw) {
110
111 std::vector<vertex_idx_t> indices;
112#ifdef INTERACTION_IS_COMPLEX
113 std::vector<gf<imtime, scalar_valued>> Jperp_tau_lst;
114#else
115 std::vector<gf<imtime, scalar_real_valued>> Jperp_tau_lst;
116#endif
117
118 if (params.n_blocks() != 2) TRIQS_RUNTIME_ERROR << "Jperp requires exactly two blocks corresponding to the spins";
119
120 // Convert DLR Jperp_iw -> Jperp_tau via DLR coefficients
121 auto Jperp_tau = make_gf_imtime(make_gf_dlr(*Jperp_iw), params.n_tau_dynamical_interactions);
122
123 // Loop over non-block indices
124 for (int a = 0; a < Jperp_tau.target_shape()[0]; a++)
125 for (int b = 0; b < Jperp_tau.target_shape()[1]; b++) {
126 auto d = slice_target_to_scalar(Jperp_tau, a, b);
127
128 if (max_norm(d) > 1e-10) {
129 indices.push_back({1, a, 0, a, 0, b, 1, b}); //S^+_a(tau) S^-_b(tau')
130 indices.push_back({0, a, 1, a, 1, b, 0, b}); //S^-_a(tau) S^+_b(tau')
131#ifdef INTERACTION_IS_COMPLEX
132 Jperp_tau_lst.emplace_back(d);
133 Jperp_tau_lst.emplace_back(d);
134#else
135 if (!is_gf_real(d, 1e-8)) std::cerr << "WARNING: Assuming real interaction values, but found Imag(Jperp(tau)) > 1e-8. Casting to Real.\n";
136 Jperp_tau_lst.emplace_back(real(d));
137 Jperp_tau_lst.emplace_back(real(d));
138#endif
139 }
140 }
141
142 if (indices.size() > 0) {
143 auto l = [beta = params.beta, indices = std::move(indices), Jperp_tau_lst = std::move(Jperp_tau_lst), &rng] {
144 int n = rng(indices.size());
145 tau_t t = tau_t::get_random(rng);
146 tau_t tp = tau_t::get_random(rng);
147 auto [sig, dtau] = cyclic_difference(t, tp);
148 double prop_proba = 1.0 / (beta * beta * indices.size());
149 return vertex_t{indices[n], t, t, tp, tp, Jperp_tau_lst[n](dtau) / 2.0, prop_proba}; // We add two identical terms above -> Divide by 2
150 };
151
152 vertex_factories.emplace_back(l);
153 }
154 }
155
156 return vertex_factories;
157 }
158
159} // namespace triqs_ctint
A struct combining both constr_params_t and solve_params_t.
Definition params.hpp:210
static tau_t get_random(RNG &rng)
Get a random point in $[0,\beta[$.
Definition vertex.hpp:29