TRIQS/triqs_cthyb 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
G2_iw_acc.cpp
1/*******************************************************************************
2 *
3 * TRIQS: a Toolbox for Research in Interacting Quantum Systems
4 *
5 * Copyright (C) 2018, The Simons Foundation & H. U.R. Strand
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 "./G2_iw_acc.hpp"
24
25namespace triqs_cthyb {
26
27 namespace G2_iw {
28
29 template <G2_channel Channel>
30 measure_G2_iw_base<Channel>::measure_G2_iw_base(std::optional<G2_iw_t> &G2_iw_opt,
31 qmc_data const &data,
32 G2_measures_t const &G2_measures)
33 : data(data), average_sign(0), G2_measures(G2_measures) {
34
35 const double beta = data.config.beta();
36
37 order = G2_measures.params.measure_G2_block_order;
38 int n_bosonic = G2_measures.params.measure_G2_n_bosonic;
39 int n_fermionic = G2_measures.params.measure_G2_n_fermionic;
40
41 // Allocate the two-particle Green's function
42 {
43 mesh::imfreq mesh_f{beta, Fermion, n_fermionic};
44 mesh::imfreq mesh_b{beta, Boson, n_bosonic};
45
46 mesh::prod<imfreq, imfreq, imfreq> mesh_fff{mesh_f, mesh_f, mesh_f};
47 mesh::prod<imfreq, imfreq, imfreq> mesh_bff{mesh_b, mesh_f, mesh_f};
48
49 if (Channel == G2_channel::AllFermionic)
50 G2_iw_opt = make_block2_gf(mesh_fff, G2_measures.gf_struct, order);
51 else
52 G2_iw_opt = make_block2_gf(mesh_bff, G2_measures.gf_struct, order);
53
54 G2_iw.rebind(*G2_iw_opt);
55 G2_iw() = 0;
56 }
57
58 // Allocate temporary two-frequency matrix M
59 {
60 if (Channel == G2_channel::AllFermionic) { // Smaller mesh possible in AllFermionic
61 mesh::imfreq iw_mesh_large{beta, Fermion, 3 * n_fermionic};
62 mesh::imfreq iw_mesh_small{beta, Fermion, n_fermionic};
63 M_mesh = mesh::prod<imfreq, imfreq>{iw_mesh_large, iw_mesh_small};
64 } else {
65 int nfreq = n_bosonic + n_fermionic;
66 mesh::imfreq iw_mesh{beta, Fermion, nfreq};
67 M_mesh = mesh::prod<imfreq, imfreq>{iw_mesh, iw_mesh};
68 }
69
70 // Initialize intermediate scattering matrix
71 M = block_gf{M_mesh, G2_measures.gf_struct};
72 }
73 }
74
75 template <G2_channel Channel>
76 void accumulate_impl_AABB(G2_iw_t::g_t::view_type G2, mc_weight_t s, M_t const &M_ij,
77 M_t const &M_kl);
78 template <G2_channel Channel>
79 void accumulate_impl_ABBA(G2_iw_t::g_t::view_type G2, mc_weight_t s, M_t const &M_ij,
80 M_t const &M_kl);
81
82 template <G2_channel Channel> void measure_G2_iw_base<Channel>::accumulate_G2(mc_weight_t s) {
83
84 s *= data.atomic_reweighting;
85 average_sign += s;
86
87 timer_G2.start();
88 for (auto &m : G2_measures()) {
89 auto G2_iw_block = G2_iw(m.b1.idx, m.b2.idx);
90 bool diag_block = (m.b1.idx == m.b2.idx);
91 if (order == block_order::AABB || diag_block)
92 accumulate_impl_AABB<Channel>(G2_iw_block, s, M(m.b1.idx), M(m.b2.idx));
93 if (order == block_order::ABBA || diag_block)
94 accumulate_impl_ABBA<Channel>(G2_iw_block, s, M(m.b1.idx), M(m.b2.idx));
95 }
96 timer_G2.stop();
97 }
98
99 template <G2_channel Channel>
100 void measure_G2_iw_base<Channel>::collect_results(mpi::communicator const &com) {
101
102 average_sign = mpi::all_reduce(average_sign, com);
103 G2_iw = mpi::all_reduce(G2_iw, com);
104
105 G2_iw = G2_iw / (real(average_sign) * data.config.beta());
106
107 if (com.rank() == 0) {
108 std::cout << "measure/G2_iw: timer_M = " << double(timer_M) << "\n";
109 std::cout << "measure/G2_iw: timer_G2 = " << double(timer_G2) << "\n";
110 }
111 }
112
113 // -- Particle-hole
114
115 template <>
116 void accumulate_impl_AABB<G2_channel::PH>(G2_iw_t::g_t::view_type G2, mc_weight_t s,
117 M_t const &M_ij, M_t const &M_kl) {
118
119 //G2(w, n1, n2)(i, j, k, l) << G2(w, n1, n2)(i, j, k, l) + s * M_ij(n1, n1 + w)(i, j) * M_kl(n2 + w, n2)(k, l);
120 for (const auto &[w, n1, n2] : G2.mesh())
121 for (const auto [i, j, k, l] : G2.target_indices())
122 G2[w, n1, n2](i, j, k, l) += s * M_ij[n1.value(), n1 + w](i, j) * M_kl[n2 + w, n2.value()](k, l);
123 }
124
125 template <>
126 void accumulate_impl_ABBA<G2_channel::PH>(G2_iw_t::g_t::view_type G2, mc_weight_t s,
127 M_t const &M_il, M_t const &M_kj) {
128
129 //G2(w, n1, n2)(i, j, k, l) << G2(w, n1, n2)(i, j, k, l) - s * M_il(n1, n2)(i, l) * M_kj(n2 + w, n1 + w)(k, j);
130 for (const auto &[w, n1, n2] : G2.mesh())
131 for (const auto [i, j, k, l] : G2.target_indices())
132 G2[w, n1, n2](i, j, k, l) -= s * M_il[n1.value(), n2.value()](i, l) * M_kj[n2 + w, n1 + w](k, j);
133 }
134
135 // -- Particle-particle
136
137 template <>
138 void accumulate_impl_AABB<G2_channel::PP>(G2_iw_t::g_t::view_type G2, mc_weight_t s,
139 M_t const &M_ij, M_t const &M_kl) {
140
141 //G2(w, n1, n2)(i, j, k, l) << G2(w, n1, n2)(i, j, k, l) + s * M_ij(n1, w - n2)(i, j) * M_kl(w - n1, n2)(k, l);
142 for (const auto &[w, n1, n2] : G2.mesh())
143 for (const auto [i, j, k, l] : G2.target_indices())
144 G2[w, n1, n2](i, j, k, l) += s * M_ij[n1.value(), w - n2](i, j) * M_kl[w - n1, n2.value()](k, l);
145 }
146
147 template <>
148 void accumulate_impl_ABBA<G2_channel::PP>(G2_iw_t::g_t::view_type G2, mc_weight_t s,
149 M_t const &M_il, M_t const &M_kj) {
150
151 //G2(w, n1, n2)(i, j, k, l) << G2(w, n1, n2)(i, j, k, l) - s * M_il(n1, n2)(i, l) * M_kj(w - n1, w - n2)(k, j);
152
153 for (const auto &[w, n1, n2] : G2.mesh())
154 for (const auto [i, j, k, l] : G2.target_indices())
155 G2[w, n1, n2](i, j, k, l) -= s * M_il[n1.value(), n2.value()](i, l) * M_kj[w - n1, w - n2](k, j);
156 }
157
158 // -- Fermionic
159
160 template <>
161 void accumulate_impl_AABB<G2_channel::AllFermionic>(G2_iw_t::g_t::view_type G2, mc_weight_t s,
162 M_t const &M_ij, M_t const &M_kl) {
163
164 //G2(n1, n2, n3)(i, j, k, l) << G2(n1, n2, n3)(i, j, k, l) + s * M_ij(n2, n1)(j, i) * M_kl(n1 + n3 - n2, n3)(l, k);
165 for (const auto &[n1, n2, n3] : G2.mesh()) {
166 auto n4 = n1 + n3 - n2;
167 for (const auto [i, j, k, l] : G2.target_indices())
168 G2[n1, n2, n3](i, j, k, l) += s * M_ij[n2.value(), n1.value()](j, i) * M_kl[n4, n3.value()](l, k);
169 }
170 }
171
172 template <>
173 void accumulate_impl_ABBA<G2_channel::AllFermionic>(G2_iw_t::g_t::view_type G2, mc_weight_t s,
174 M_t const &M_il, M_t const &M_kj) {
175
176 //G2(n1, n2, n3)(i, j, k, l) << G2(n1, n2, n3)(i, j, k, l) - s * M_il(n1 + n3 - n2, n1)(l, i) * M_kj(n2, n3)(j, k);
177 for (const auto &[n1, n2, n3] : G2.mesh()) {
178 auto n4 = n1 + n3 - n2;
179 for (const auto [i, j, k, l] : G2.target_indices())
180 G2[n1, n2, n3](i, j, k, l) -= s * M_il[n4, n1.value()](l, i) * M_kj[n2.value(), n3.value()](j, k);
181 }
182 }
183
184 template class measure_G2_iw_base<G2_channel::AllFermionic>;
185 template class measure_G2_iw_base<G2_channel::PP>;
186 template class measure_G2_iw_base<G2_channel::PH>;
187
188 } // namespace G2_iw
189} // namespace triqs_cthyb