25 auto n_k = res.
P_k.extent(0);
26 auto n_sigma = res.P_k.extent(1);
27 for (
auto isig : range(n_sigma)) {
28 auto decomp = range(U.extent(0)) | stdv::transform([&](
auto &&m) {
return U(m, isig).extent(0); }) | tl::to<std::vector>();
29 for (
auto ik : range(n_k)) {
32 res.P_k(ik, isig, sli,
r_all) = dagger(U(a, isig)) * matrix_const_view<dcomplex>{this->
P_k(ik, isig, sli,
r_all)};
54 auto atomic_shells = atom_indices | stdv::transform([&](
auto i) {
return obe.
C_space.
atomic_shells()[i]; }) | tl::to<std::vector>();
58 for (
auto &&[iatom, atom] : enumerate(atom_indices)) {
63 auto n_atoms = atom_partition.size();
66 auto irreps_per_atom = nda::array<std::vector<long>, 2>(n_atoms, n_sigma);
67 for (
auto &&[ipart, partition] : enumerate(atom_partition)) {
68 if (partition.size() == 1) {
71 irreps_per_atom(ipart,
r_all) = std::vector{
72 stdr::fold_left(partition | stdv::transform([&](
auto idx) {
return obe.
C_space.
atomic_shells()[idx].dim; }), 0, std::plus<>())};
76 auto new_C_space =
local_space{spin_kind, atomic_shells, irreps_per_atom, new_rot_from_dft_to_local_basis, new_rot_from_sph_to_dft_basis};
80 auto [n_k, n_sig, n_M, n_nu] = obe.
P.
P_k.shape();
82 auto P_k_list = atom_decomp | stdv::transform([&](
auto dim) {
return nda::zeros<dcomplex>(n_k, n_sig, dim, n_nu); }) | tl::to<std::vector>();
87 auto new_P_k_list = atom_indices | stdv::transform([&](
auto i) {
return P_k_list[i]; }) | tl::to<std::vector>();
89 auto new_atom_decomp = new_C_space.atomic_decomposition() | tl::to<std::vector>();
91 auto P_k = nda::zeros<dcomplex>(n_k, n_sig, n_M, n_nu);
98 if (!obe.
ibz_symm_ops)
return {.H = obe.
H, .C_space = new_C_space, .P = new_P, .ibz_symm_ops = {}};
100 std::vector<long> inv_atom_indices(atom_indices.size());
101 for (
long i = 0; i < atom_indices.size(); ++i) { inv_atom_indices[atom_indices[i]] = i; }
104 for (
auto &op : new_ibz_symm_ops.ops) {
105 auto old_perm = op.permutation;
106 auto old_mats = op.mats;
107 for (
auto i : range(atom_indices.size())) {
108 op.permutation[i] = inv_atom_indices[old_perm[atom_indices[i]]];
109 op.mats[i] = old_mats[atom_indices[i]];
112 return {.H = obe.
H, .C_space = new_C_space, .P = new_P, .ibz_symm_ops = new_ibz_symm_ops};
120 auto results_per_atom = nda::array<nda::matrix<dcomplex>, 2>{n_atoms, n_sigma};
125 for (
auto sigma : range(n_sigma)) {
126 auto hloc0 = nda::zeros<dcomplex>(M_a, M_a);
127 for (
auto ik : range(obe.
H.
n_k())) {
128 auto P = obe.
P.
P(sigma, ik)(R_atom,
r_all);
129 hloc0 += obe.
H.
k_weights(ik) * P * obe.
H.
H(sigma, ik) * dagger(P);
131 results_per_atom(atom_idx, sigma) = hloc0;
135 if (
auto const &S = obe.
ibz_symm_ops; S) results_per_atom = S->symmetrize(results_per_atom);
138 for (
auto atom_idx : range(n_atoms)) {
140 results_per_atom(atom_idx,
r_all) = results_per_atom(inequiv,
r_all);
144 auto result = nda::array<nda::matrix<dcomplex>, 2>{1, n_sigma};
145 for (
auto sigma : range(n_sigma)) {
148 result(0, sigma)(r_atom, r_atom) = results_per_atom(atom, sigma);
162 nda::array<dcomplex, 3> detail::G0_C_k_sigma(one_body_elements_on_grid
const &obe,
double mu,
long k_idx,
long sigma,
163 std::vector<dcomplex>
const &omegas,
bool mu_derivative) {
166 auto n_nu = obe.H.N_nu(sigma, k_idx);
167 auto R_nu = nda::range(n_nu);
168 auto M = obe.C_space.dim();
171 auto n_omega = omegas.size();
172 auto Dinv = nda::matrix<dcomplex>(n_omega, n_nu);
173 auto Hk = obe.H.H(sigma, k_idx);
174 constexpr auto sqr = [](
auto x) {
return x * x; };
177 if (not mu_derivative) {
178 for (
auto [n, om] : enumerate(omegas))
179 for (auto nu : R_nu) Dinv(n, nu) = 1 / (om + mu -
Hk(nu, nu));
181 for (
auto [n, om] : enumerate(omegas))
182 for (auto nu : R_nu) Dinv(n, nu) = -1 / sqr(om + mu -
Hk(nu, nu));
186 auto PP = nda::zeros<dcomplex>(n_nu, M, M);
187 auto P = obe.P.P(sigma, k_idx);
188 for (
auto m : range(M))
189 for (auto mp : range(M))
190 for (auto nu : R_nu) PP(nu, m, mp) = P(m, nu) * conj(P(mp, nu));
194 auto Y = nda::zeros<dcomplex>(n_omega, M, M);
195 auto M_asmat =
cmat_vt{nda::group_indices_view(PP, nda::idx_group<0>, nda::idx_group<1, 2>)};
196 auto Y_asmat =
cmat_vt{nda::group_indices_view(Y, nda::idx_group<0>, nda::idx_group<1, 2>)};
197 nda::blas::gemm(1, Dinv, M_asmat, 0, Y_asmat);
Describe the atomic orbitals within downfolded space.
spin_kind_e spin_kind() const
Spin kind of index.
nda::array< nda::matrix< dcomplex >, 1 > const & rotation_from_spherical_to_dft_basis() const
Array of rotation matrices from spherical harmonics to dft specific orbital basis.
long n_sigma() const
Dimension of the index.
nda::array< nda::matrix< dcomplex >, 2 > const & rotation_from_dft_to_local_basis() const
2-dim array of all local rotation matices that rotate the data.
nda::array< std::vector< long >, 2 > const & atoms_block_decomposition() const
2-dim array of all blocks spanning space -> atoms_block_decomposition.
auto atomic_decomposition() const
Transformed view containing the dimension of each atomic shell.
long dim() const
Dimension of the correlated space.
std::vector< atomic_orbs > const & atomic_shells() const
List of all atomic shells spanning the space.
long n_atoms() const
The number of atoms.
long first_shell_of_its_equiv_cls(long idx) const
Given the index of an atomic shell, return the index of the first atomic shell of its equivalence cla...
nda::array< nda::matrix< dcomplex >, 2 > impurity_levels(one_body_elements_on_grid const &obe)
Compute the local impurity levels from the single-particle dispersion.
std::vector< T > flatten(const std::vector< std::vector< T > > &nested)
one_body_elements_on_grid rotate_local_basis(nda::array< nda::matrix< dcomplex >, 2 > const &U, one_body_elements_on_grid const &x)
Rotates the local basis of the downfolding projector.
one_body_elements_on_grid permute_local_space(std::vector< std::vector< long > > const &atom_partition, one_body_elements_on_grid const &obe)
static constexpr auto r_all
nda::matrix_view< dcomplex > cmat_vt
generator< std::pair< long, nda::range > > enumerated_sub_slices(auto sub_div)
nda::array< double, 1 > k_weights
Weight in the BZ for each k-point.
long n_k() const
Number of k-points in the grid.
nda::matrix_const_view< dcomplex > H(long sigma, long k_idx) const
Get for a given and .
The projector that downfolds the energy bands onto a set of localized atomic-like orbitals.
nda::matrix_const_view< dcomplex > P(long sigma, long k_idx) const
Get for a given and .
spin_kind_e spin_kind
Spin kind of the one-body data.
nda::array< dcomplex, 4 > P_k
Projector .
nda::array< long, 2 > n_bands_per_k
Number of bands for each k-point and .
downfolding_projector rotate_local_basis(nda::array< nda::matrix< dcomplex >, 2 > const &U) const
Rotates the local basis of the downfolding projector.
A one-body elements struct where all of the underlying data exists on a fixed momentum grid.
local_space C_space
Local space.
band_dispersion H
Band dispersion.
downfolding_projector P
Downfolding projector .
C2PY_IGNORE std::optional< ibz_symmetry_ops > ibz_symm_ops
IBZ symmetrizer after a k-sum.