9#include <triqs/mesh.hpp>
15#pragma omp declare reduction(block2_gf_sum : block2_gf<imfreq, matrix_valued> : omp_out += omp_in) \
16 initializer(omp_priv = make_block2_gf(omp_orig(0, 0).mesh(), get_struct(omp_orig)))
17#pragma omp declare reduction(block2_gf_sum : block2_gf<dlr_imfreq, matrix_valued> : omp_out += omp_in) \
18 initializer(omp_priv = make_block2_gf(omp_orig(0, 0).mesh(), get_struct(omp_orig)))
31 template <
typename Mesh>
32 block2_gf<Mesh, matrix_valued> gloc_for_matrix_valued_dispersion_impl(one_body_elements_on_grid
const &obe,
double mu,
33 block2_gf<Mesh, matrix_valued>
const &Sigma_dynamic,
34 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static) {
36 auto n_sigma = obe.C_space.n_sigma();
37 auto n_M = obe.C_space.dim();
38 auto n_kpts = long(obe.H.n_k());
39 auto const &mesh = Sigma_dynamic(0, 0).mesh();
41 auto embedding_decomp =
get_struct(Sigma_dynamic).dims(
r_all, 0) | tl::to<std::vector>();
43 auto PSP = [&](
auto &w,
auto &k_idx,
auto &sigma) {
44 auto N_nu = obe.H.N_nu(sigma, k_idx);
45 auto out = nda::zeros<dcomplex>(N_nu, N_nu);
47 auto P = obe.P.P(sigma, k_idx)(R,
r_all);
48 out(
r_all,
r_all) += dagger(P) * nda::matrix<dcomplex>{Sigma_dynamic(alpha, sigma).data()(w,
r_all,
r_all) + Sigma_static(alpha, sigma)} * P;
53 auto gloc_k = [&](
auto &k_idx,
auto &sigma) {
54 auto out = gf{mesh, {n_M, n_M}};
55 auto P = obe.P.P(sigma, k_idx);
56 for (
auto &&[n, w] : enumerate(mesh)) {
57 out.data()(n,
r_all,
r_all) = P * inverse(w + mu - obe.H.H(sigma, k_idx) - PSP(n, k_idx, sigma)) * dagger(P);
62 auto gloc_result =
make_block2_gf(mesh, obe.C_space.Gc_block_shape());
63 mpi::communicator comm = {};
64#pragma omp parallel for collapse(2) reduction(block2_gf_sum : gloc_result) default(none) shared(comm, gloc_k, n_kpts, n_sigma, obe, r_all)
65 for (
auto k_idx : mpi::chunk(range(n_kpts), comm)) {
66 for (
auto sigma : range(n_sigma)) { gloc_result(0, sigma).data()(
r_all,
r_all,
r_all) += obe.H.k_weights(k_idx) * gloc_k(k_idx, sigma).data(); }
68 gloc_result = mpi::all_reduce(gloc_result);
70 if (
auto const &S = obe.ibz_symm_ops; S) { gloc_result = S->symmetrize(gloc_result, obe.C_space.atomic_decomposition()); }
91 template <
typename Mesh>
93 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static) {
96 if (obe.
H.
matrix_valued)
return gloc_for_matrix_valued_dispersion_impl(obe, mu, Sigma_dynamic, Sigma_static);
98 auto n_sigma = Sigma_dynamic.size2();
100 auto n_kpts = long(obe.
H.
n_k());
101 auto const &mesh = Sigma_dynamic(0, 0).mesh();
103 auto omegas = mesh | tl::to<std::vector<dcomplex>>();
106 auto embedding_decomp =
get_struct(Sigma_dynamic).dims(
r_all, 0) | tl::to<std::vector>();
112 mpi::communicator comm = {};
113#pragma omp parallel for collapse(2) reduction(block2_gf_sum : gloc_result) default(none) \
114 shared(comm, r_all, n_kpts, n_sigma, obe, mu, omegas, mesh, M, embedding_decomp, Sigma_dynamic, Sigma_static)
115 for (
auto k_idx : mpi::chunk(range(n_kpts), comm)) {
116 for (
auto sigma : range(n_sigma)) {
117 auto Y = detail::G0_C_k_sigma(obe, mu, k_idx, sigma, omegas,
false);
118 for (
auto &&[n, om] : itertools::enumerate(mesh)) {
120 auto B = detail::calc_inv_G_G0(M, embedding_decomp, Sigma_dynamic, Sigma_static, om, sigma, Y1, Y1);
126 gloc_result = mpi::all_reduce(gloc_result);
148 auto Sigma_static = nda::array<nda::matrix<dcomplex>, 2>(1, obe.
C_space.
n_sigma());
149 for (
auto [i, j] : Sigma_static.indices()) { Sigma_static(i, j) = nda::zeros<dcomplex>(obe.
C_space.
dim(), obe.
C_space.
dim()); }
150 return gloc(obe, mu, Sigma_dynamic, Sigma_static);
165 template <
typename Mesh>
166 block_gf<Mesh, matrix_valued>
hybridization(std::vector<nda::matrix<dcomplex>>
const &epsilon_levels, block_gf<Mesh, matrix_valued>
const &Gloc,
167 block_gf<Mesh, matrix_valued>
const &Sigma_dynamic,
168 std::vector<nda::matrix<dcomplex>>
const &Sigma_static) {
170 auto mesh = Gloc[0].mesh();
171 auto Delta = block_gf{mesh, gf_struct};
172 auto n_blocks = gf_struct.size();
173 for (
auto bl : range(n_blocks)) {
174 for (
auto &&[n, w] : enumerate(mesh))
176 (w - epsilon_levels[bl] - inverse(Gloc[bl]).data()(n,
r_all,
r_all) - (Sigma_dynamic[bl].data()(n,
r_all,
r_all) + Sigma_static[bl]));
190 template <
typename Mesh>
191 block_gf<Mesh, matrix_valued>
hybridization(std::vector<nda::matrix<dcomplex>>
const &epsilon_levels, block_gf<Mesh, matrix_valued>
const &Gloc) {
192 auto Sigma_static =
get_struct(Gloc) | stdv::transform([](
auto &x) {
return nda::zeros<dcomplex>(x.second, x.second); })
193 | tl::to<std::vector<nda::matrix<dcomplex>>>();
194 auto Sigma_dynamic = block_gf{Gloc[0].mesh(),
get_struct(Gloc)};
195 return hybridization(epsilon_levels, Gloc, Sigma_dynamic, Sigma_static);
201 block2_gf<imfreq, matrix_valued>
const &Sigma_dynamic,
202 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static);
205 block2_gf<dlr_imfreq, matrix_valued>
const &Sigma_dynamic,
206 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static);
208 template block_gf<imfreq, matrix_valued>
hybridization(std::vector<nda::matrix<dcomplex>>
const &epsilon_levels,
209 block_gf<imfreq, matrix_valued>
const &Gloc);
210 template block_gf<imfreq, matrix_valued>
hybridization(std::vector<nda::matrix<dcomplex>>
const &epsilon_levels,
211 block_gf<imfreq, matrix_valued>
const &Gloc,
212 block_gf<imfreq, matrix_valued>
const &Sigma_dynamic,
213 std::vector<nda::matrix<dcomplex>>
const &Sigma_static);
214 template block_gf<dlr_imfreq, matrix_valued>
hybridization(std::vector<nda::matrix<dcomplex>>
const &epsilon_levels,
215 block_gf<dlr_imfreq, matrix_valued>
const &Gloc);
216 template block_gf<dlr_imfreq, matrix_valued>
hybridization(std::vector<nda::matrix<dcomplex>>
const &epsilon_levels,
217 block_gf<dlr_imfreq, matrix_valued>
const &Gloc,
218 block_gf<dlr_imfreq, matrix_valued>
const &Sigma_dynamic,
219 std::vector<nda::matrix<dcomplex>>
const &Sigma_static);
long n_sigma() const
Dimension of the Ļ index.
auto atomic_decomposition() const
Generates [dimension of the atomic shell].
long dim() const
Dimension of the correlated space.
C2PY_IGNORE gf_struct2_t Gc_block_shape() const
Shape of the Green function in the correlated space, without block decomposition.
A utility class for measuring the execution time of a scope.
block2_gf< Mesh, matrix_valued > gloc(one_body_elements_on_grid const &obe, double mu, block2_gf< Mesh, matrix_valued > const &Sigma_dynamic, nda::array< nda::matrix< dcomplex >, 2 > const &Sigma_static)
compute Gš local Green's function on Mesh(MxM)
block_gf< Mesh, matrix_valued > hybridization(std::vector< nda::matrix< dcomplex > > const &epsilon_levels, block_gf< Mesh, matrix_valued > const &Gloc, block_gf< Mesh, matrix_valued > const &Sigma_dynamic, std::vector< nda::matrix< dcomplex > > const &Sigma_static)
Compute the hybridization function from the effective impurity levels, the local Green's function,...
block2_gf< Mesh, matrix_valued > make_block2_gf(Mesh const &mesh, gf_struct2_t const &gf_s)
gf_struct_t get_struct(block_gf< Mesh > const &g)
static constexpr auto r_all
generator< std::pair< long, nda::range > > enumerated_sub_slices(auto sub_div)
bool matrix_valued
Is the dispersion matrix-valued?
nda::array< double, 1 > k_weights
k_weights[k_idx]
long n_k() const
Number of k points in the grid.
A one-body elements struct where all of the underlying data exists on a fixed momentum grid.
C2PY_IGNORE std::optional< ibz_symmetry_ops > ibz_symm_ops
IBZ symmetrizer after a k-sum.