TRIQS/triqs_modest 3.3.0
Modular Electronic Structure Toolkit
Loading...
Searching...
No Matches
loaders.cpp
Go to the documentation of this file.
1// Copyright (c) 2025--present, The Simons Foundation
2// This file is part of TRIQS/modest 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 "loaders.hpp"
7#include "dft_tools/utils.hpp"
9#include "utils/nda_supp.hpp"
10#include "utils/h5_proxy.hpp"
11#include "utils/to_vector.hpp"
12#include "utils/graph_algo.hpp"
13
14namespace triqs::modest {
15 // utility to flatten a nested vector (move to utils/ ?)
16
17 // free function for svd (FIXME: nda::linalg::svd) (see TRIQS/nda PR#103)
18 nda::matrix<dcomplex> svd(const nda::matrix<dcomplex> &A) {
19 auto Acopy = nda::matrix<dcomplex, nda::F_layout>{transpose(A)};
20 long m = Acopy.extent(0);
21 // auto S = nda::vector<double>(m);
22 auto U = nda::matrix<dcomplex, nda::F_layout>(m, m);
23 auto VT = nda::matrix<dcomplex, nda::F_layout>(m, m);
24 [[maybe_unused]] auto status = nda::lapack::gesvd(Acopy, nda::vector<double>(m), U, VT);
25 return nda::matrix<dcomplex>{transpose(U * VT)};
26 }
27
28 namespace detail {
29 // inject an object T from the C space to W space (used in the context of post-processing).
30 nda::array<std::vector<long>, 2> inject_to_new_space(nda::array<std::vector<long>, 2> const &T, std::vector<atomic_orbs> const &old_space,
31 std::vector<atomic_orbs> const &new_space) {
32 auto n_atoms = new_space.size();
33 auto n_sigma = T.extent(1);
34 auto Tembed = nda::array<std::vector<long>, 2>(n_atoms, n_sigma);
35
36 auto old_indices = old_space | stdv::transform([](auto &x) { return x.dft_idx; }) | tl::to<std::vector>();
37 auto new_indices = new_space | stdv::transform([](auto &x) { return x.dft_idx; }) | tl::to<std::vector>();
38
39 for (auto const &[n, nidx] : enumerate(new_indices)) {
40 if (auto it = std::find(begin(old_indices), end(old_indices), nidx); it != end(old_indices)) {
41 auto uidx = std::distance(begin(old_indices), it);
42 Tembed(n, r_all) = T(uidx, r_all);
43 } else {
44 Tembed(n, r_all) = std::vector<long>{long(new_space[n].dim)};
45 }
46 }
47 return Tembed;
48 }
49 } // namespace detail
50
51 //-------------------------------------------------------
52 // Disovers (approximate) irreducible symmetries for Green's function from the non-interacting part of the local
53 // Hamiltonian (H0 = ∑k P(k) Hνν' P†(k) ), which represents the block structure of the TRIQS Gf.
54 std::pair<nda::array<std::vector<long>, 2>, nda::array<nda::matrix<dcomplex>, 2>>
55 discover_symmetries(nda::array<nda::matrix<dcomplex>, 2> const &Hloc0, std::vector<atomic_orbs> const &atomic_shells, double block_threshold,
56 bool diagonalize_hloc) {
57
58 auto [n_atoms, n_sigma] = Hloc0.shape();
59 auto decomposition = nda::array<std::vector<long>, 2>(n_atoms, n_sigma);
60 auto U_rotation = nda::array<nda::matrix<dcomplex>, 2>(n_atoms, n_sigma);
61
62 for (auto const &[atom, shell] : enumerate(atomic_shells)) {
63 for (auto sigma : nda::range(n_sigma)) {
64 auto D = find_blocks(nda::matrix<double>{abs(Hloc0(atom, sigma))}, block_threshold);
65 U_rotation(atom, sigma) = nda::make_matrix_from_permutation<dcomplex>(nda::flatten(D));
66 decomposition(atom, sigma) = D | stdv::transform([](auto &x) { return long(x.size()); }) | tl::to<std::vector>();
67
68 // diagonalize the hloc0 to find a new basis of orbitals
69 if (diagonalize_hloc) {
70 auto U_diag = nda::matrix<dcomplex>(shell.dim, shell.dim);
71 for (auto &&[idx, r_idx] : enumerated_sub_slices(decomposition(atom, sigma))) {
72 auto hperm = dagger(U_rotation(atom, sigma)) * Hloc0(atom, sigma) * U_rotation(atom, sigma);
73 U_diag(r_idx, r_idx) = std::get<1>(nda::linalg::eigenelements(hperm(r_idx, r_idx)));
74 }
75 U_rotation(atom, sigma) *= U_diag;
76 }
77 }
78 }
79 return {decomposition, U_rotation};
80 }
81
82 //-------------------------------------------------------
83 // Enumerate the different reading modes for the obe factory functions.
84 enum class ReadMode {
85 Correlated, // reads bands, projectors, and correlated shells from "dft_input"
86 ThetaProjectors, // read bands ands shells from "dft_input" and projectors from "dft_parproj_input" ("proj_mat_all")
87 Bands // read bands and projectors from "dft_bands_input"
88 };
89
90 //-------------------------------------------------------
91 // Read rotation matrices from hdf5. (internal)
92 std::vector<cmat_t> read_rotation_matrices(std::string const &filename, ReadMode mode) {
93
94 auto root = h5::proxy{filename, 'r'};
95 auto SO = long(root["dft_input"]["SO"]);
96
97 auto read_mats = [SO](auto group, auto name1, auto name2) {
98 auto mats = to_vector<cmat_t>(sort_keys_as_int(group[name1]));
99 auto mats_tinv = to_vector<long>(sort_keys_as_int(group[name2]));
100 auto mats_tinv_and_SO = mats_tinv | stdv::transform([SO](long const &x) { return (x == 1 && SO == 1) ? 1 : 0; }) | tl::to<std::vector<long>>();
101
102 // NB: mat = D(R_{\alpaha})
103 // if mat has time inversion symmetry (T), then T*D(R_{\alpha}) = -D(R_{\alpha})
104 return mats
105 | stdv::transform([mats_tinv_and_SO, i = 0](cmat_t const &x) mutable { return (mats_tinv_and_SO[i++] == 1) ? -conj(svd(x)) : svd(x); })
106 | tl::to<std::vector<cmat_t>>();
107 };
108 return (mode == ReadMode::Correlated) ? read_mats(root["dft_input"], "rot_mat", "rot_mat_time_inv") :
109 (mode == ReadMode::ThetaProjectors) ? read_mats(root["dft_parproj_input"], "rot_mat_all", "rot_mat_all_time_inv") :
110 throw std::runtime_error("This should not happen!");
111 }
112
113 //-------------------------------------------------------
114 // Read projectors using ReadMode, rotate to local frame, and embed them in the M space. (internal)
115 nda::array<dcomplex, 4> load_rotate_and_format_projectors(std::string const &filename, ReadMode mode, std::vector<cmat_t> const &rot_mats,
116 std::vector<long> const &atom_decomp) {
117 auto load_Pks = [](auto f, auto m) {
118 auto root = h5::proxy{f, 'r'};
119 if (m == ReadMode::Correlated || m == ReadMode::Bands) {
120 return (m == ReadMode::Correlated) ? as<nda::array<dcomplex, 5>>(root["dft_input"]["proj_mat"]) :
121 as<nda::array<dcomplex, 5>>(root["dft_bands_input"]["proj_mat"]);
122 } else if (m == ReadMode::ThetaProjectors) {
123 auto tmp = as<nda::array<dcomplex, 6>>(root["dft_parproj_input"]["proj_mat_all"]);
124 // FIXME: The θ projectors have an extra dimesion called ir. Not sure why it is there...
125 return nda::array<dcomplex, 5>{tmp(r_all, r_all, r_all, 0, r_all, r_all)};
126 } else {
127 throw std::runtime_error{"This should not happen!"};
128 }
129 };
130
131 auto P_k_tmp = load_Pks(filename, mode);
132 auto n_atoms = P_k_tmp.extent(2);
133 auto P_k_list = range(n_atoms) | stdv::transform([&](auto atom) { return P_k_tmp(r_all, r_all, atom, r_all, r_all); }) | tl::to<std::vector>();
134
135 // Merge the rotation matrices R into the Ps: P <- dagger(R) * P
136 auto [n_k, n_sigma, n_m, n_nu] = P_k_list[0].shape(); // NOLINT
137 for (auto isig : range(n_sigma)) {
138 for (auto ik : range(n_k)) {
139 for (auto const &[R, P] : zip(rot_mats, P_k_list)) {
140 P(ik, isig, nda::range(0, R.extent(0)), r_all) = dagger(R) * nda::matrix<dcomplex>{P(ik, isig, nda::range(0, R.extent(0)), r_all)};
141 }
142 }
143 }
144
145 // Place the P_k_list into the P_k living in the M x M space.
146 long M = stdr::fold_left(atom_decomp, 0, std::plus<>());
147 auto P_k = nda::zeros<dcomplex>(n_k, n_sigma, M, n_nu);
148 for (auto const &[atom, sli] : enumerated_sub_slices(atom_decomp)) {
149 P_k(r_all, r_all, sli, r_all) = P_k_list[atom](r_all, r_all, nda::range(0, atom_decomp[atom]), r_all);
150 }
151 return P_k;
152 }
153
154 //-------------------------------------------------------
155 // Read band dispersion and k-weights according to ReadMode. (internal)
156 std::tuple<nda::array<dcomplex, 4>, nda::matrix<long>, nda::array<double, 1>> read_bands_and_weights(std::string filename, ReadMode mode) {
157 auto root = h5::proxy{filename, 'r'};
158 if (mode == ReadMode::Correlated || mode == ReadMode::ThetaProjectors) {
159 auto g_dft = root["dft_input"];
160 return {as<nda::array<dcomplex, 4>>(g_dft["hopping"]), as<nda::matrix<long>>(g_dft["n_orbitals"]),
161 as<nda::array<double, 1>>(g_dft["bz_weights"])};
162 } else if (mode == ReadMode::Bands) {
163 auto g_dft = root["dft_bands_input"];
164 return {as<nda::array<dcomplex, 4>>(g_dft["hopping"]), as<nda::matrix<long>>(g_dft["n_orbitals"]), {}};
165 } else {
166 throw std::runtime_error{"This should not happen!"};
167 }
168 }
169
170 //-------------------------------------------------------
171 // Setup spin_kind enum. (internal)
172 spin_kind_e read_spin_kind(auto const &filename) {
173 // set up spin_type
174 auto g_dft = h5::proxy{filename, 'r'}["dft_input"];
175 return (long(g_dft["SO"]) == 1) ? spin_kind_e::NonColinear : ((long(g_dft["SP"]) == 1) ? spin_kind_e::Polarized : spin_kind_e::NonPolarized);
176 }
177
178 //-------------------------------------------------------
179 // Read atomic shells according to ReadMode. (internal)
180 std::vector<atomic_orbs> read_atomic_shells(auto const &filename, ReadMode mode) {
181 auto g_dft = h5::proxy{filename, 'r'}["dft_input"];
182 return ((mode == ReadMode::Correlated) ? sort_keys_as_int(g_dft["corr_shells"]) : sort_keys_as_int(g_dft["shells"]))
183 | stdv::transform([](auto const &g) {
184 //NB: as<long>(g["atom"]), as<long>(g["dim"]), as<long>(g["equiv_cls_idx"]) );
185 return atomic_orbs{.dim = long(g["dim"]), .l = long(g["l"]), .cls_idx = long(g["sort"]), .dft_idx = long(g["atom"])};
186 })
187 | tl::to<std::vector>();
188 }
189
190 //-------------------------------------------------------
191 // Prepare the spherical Ylm to DFT orbital basis rotations. (internal)
192 nda::array<nda::matrix<dcomplex>, 1> read_spherical_to_dft_basis(std::string dft, std::vector<atomic_orbs> const &atomic_shells) {
193 //TODO: finish this!
194 auto code = dft_tools::dft_code_to_enum(dft);
195 auto Ylms = nda::array<nda::matrix<dcomplex>, 1>(atomic_shells.size());
196 for (auto const &[iatom, atom] : enumerate(atomic_shells)) { Ylms(iatom) = dft_tools::get_spherical_to_dft_rotation(code, atom.l); }
197 return Ylms;
198 }
199
200 //-------------------------------------------------------
201 // Construct the ibz_symmetry_ops according to ReadMode.
202 ibz_symmetry_ops read_ibz_symmetry_ops(auto const &filename, ReadMode mode) {
203
204 auto root = h5::proxy{filename, 'r'};
205
206 auto rot_mats = read_rotation_matrices(filename, mode);
207 auto atomic_shells = read_atomic_shells(filename, mode);
208
209 auto g_symm = (mode == ReadMode::Correlated) ? root["dft_symmcorr_input"] : root["dft_symmpar_input"];
210 auto symm_ops = ibz_symmetry_ops{};
211
212 // read the symmetrization matrices (Q) for each symmetry operation S in the space group G.
213 auto symm_ops_mats = sort_keys_as_int(g_symm["mat"]) | stdv::transform([](auto const &g) { return to_vector<cmat_t>(sort_keys_as_int(g)); })
214 | tl::to<std::vector>();
215
216 // read the permutation table which contains: for each symmetry op S in space group G,
217 // the permutations of all atoms in the crystal structure under S.
218 // dim(perm_table_all) = [number of sym ops][number of atoms in crystal]
219 auto perm_table_all =
220 sort_keys_as_int(g_symm["perm"]) | stdv::transform([](auto const &g) { return to_vector<long>(sort_keys_as_int(g)); }) | tl::to<std::vector>();
221
222 // The permutation table is written for all atoms in the crystal. We must filter to obtain only the correlated atoms.
223 auto corr_atom_to_alpha = std::unordered_map<long, long>{};
224 for (auto iatom : range(atomic_shells.size())) corr_atom_to_alpha[atomic_shells[iatom].dft_idx] = iatom;
225
226 // The filtered permutation table (perm_table_corr): for each sym S, filter only the correlated atoms
227 // and map their indices from dft_idx correlated idx.
228 // dim(perm_table_correlated) = [number of sym ops][number of correlated atoms in crystal]
229 auto perm_table_correlated = perm_table_all | stdv::transform([&](auto const &sym) {
230 return atomic_shells
231 | stdv::transform([&](auto corr_atom) { return corr_atom_to_alpha[sym[corr_atom.dft_idx - 1]]; })
232 | tl::to<std::vector>();
233 })
234 | tl::to<std::vector>();
235
236 // Merge the rotation matrices R into the symmetrization matrices (Qs).
237 for (auto const &[iq, perm] : enumerate(perm_table_correlated)) {
238 for (auto const &[a, b] : enumerate(perm)) { symm_ops_mats[iq][a] = dagger(rot_mats[b]) * symm_ops_mats[iq][a] * rot_mats[a]; }
239 }
240
241 // Does this op have time inversion symmetry
242 auto time_inv_op = to_vector<long>(sort_keys_as_int(g_symm["time_inv"]));
243 // save the symmetry ops in to the ibz_symmetrizer
244 symm_ops.ops = range(perm_table_correlated.size()) | stdv::transform([symm_ops_mats, perm_table_correlated, time_inv_op](auto const &isym) {
245 return ibz_symmetry_ops::op{symm_ops_mats[isym], perm_table_correlated[isym], time_inv_op[isym]};
246 })
247 | tl::to<std::vector>();
248
249 return symm_ops;
250 };
251
252 //-------------------------------------------------------
253 // Prepare one-body elements for a DMFT calculation.
254 std::pair<double, one_body_elements_on_grid> one_body_elements_from_dft_converter(std::string const &filename, double threshold,
255 bool diagonalize_hloc) {
256 //TODO: add verbosity, currently not used.
257 auto g_dft = h5::proxy{filename, 'r'}["dft_input"];
258
259 auto total_density = as<double>(g_dft["density_required"]);
260
261 //TODO: FIXME! hdf5 read to strict on long
262 auto charge_below = (as<std::string>(g_dft["dft_code"]) != "w90" && as<std::string>(g_dft["dft_code"]) != "hk") ?
263 as<double>(g_dft["charge_below"]) :
264 as<long>(g_dft["charge_below"]);
265 total_density -= charge_below;
266
267 // set up spin_type
268 auto spin_kind = read_spin_kind(filename);
269
270 // set up atomic shells
271 auto atomic_shells = read_atomic_shells(filename, ReadMode::Correlated);
272
273 // disperion and k weights
274 auto [H_k, n_bands_per_k, k_weights] = read_bands_and_weights(filename, ReadMode::Correlated);
275
276 // rotation matrices in csc mode
277 auto rot_mats = read_rotation_matrices(filename, ReadMode::Correlated);
278
279 // read and rotate projectors
280 auto atom_decomp = atomic_shells | stdv::transform([](auto &x) { return x.dim; }) | tl::to<std::vector<long>>();
281 auto P_k = load_rotate_and_format_projectors(filename, ReadMode::Correlated, rot_mats, atom_decomp);
282
283 // read symmetry ops
284 //FIXME: auto symm_ops = (long(g_dft["symm_op"]) == 0) ? ibz_symmetry_ops{} : read_ibz(root, atomic_shells, Rmats);
285 auto symm_ops = (long(g_dft["symm_op"]) == 0) ? std::optional<ibz_symmetry_ops>{} :
286 std::optional<ibz_symmetry_ops>(read_ibz_symmetry_ops(filename, ReadMode::Correlated));
287
288 auto n_k = H_k.extent(0);
289 auto H_k_is_diagonal = true;
290 for (auto ik : range(n_k)) {
291 if (!nda::is_diagonal(nda::matrix<dcomplex>{H_k(ik, 0, r_all, r_all)})) {
292 H_k_is_diagonal = false;
293 break;
294 }
295 }
296
297 // auto H_k_is_diagonal = nda::is_diagonal(nda::matrix<dcomplex>{H_k(1, 0, r_all, r_all)});
298 auto eps_k = band_dispersion{
299 .spin_kind = spin_kind, .H_k = std::move(H_k), .n_bands_per_k = n_bands_per_k, .k_weights = k_weights, .matrix_valued = !H_k_is_diagonal};
300 auto proj = downfolding_projector{.spin_kind = spin_kind, .P_k = std::move(P_k), .n_bands_per_k = n_bands_per_k};
301
302 // build a first version without symmetries
303 auto C_space_no_symm = local_space{spin_kind, atomic_shells, {}, {}, {}};
304 auto obe = one_body_elements_on_grid{.H = eps_k, .C_space = C_space_no_symm, .P = proj, .ibz_symm_ops = std::move(symm_ops)};
305
306 // TODO: verbosity should report the symmetries found (or at least the result of the symmetries found).
307 // auto out = ostream_with_verbosity(std::cout, verbosity);
308 // FIXME: verbosity reporting of local H0 which is used to analyze the symmetries
309 auto Hloc0 = obe.C_space.atomic_view(impurity_levels(obe));
310 auto [decomposition, U_rotations] = discover_symmetries(Hloc0, atomic_shells, threshold, diagonalize_hloc);
311 // FIXME: printing of the local symmetries discovered: eigenvalues (and eigenvectors of Hloc0)
312 // Should we print the rotation matrices as well?
313 // This is a lot of matrices that will be printed...is there a more compact representation?
314 // FIXME : NORMALLY the rotate_local_basis shuold also rotate the local_basis !!!
315 // FIXME !! ---> @ HL : the question is multiply rotation_from_dft_basis LEFT OR RIGHT ?
316 // update the orbital set with the decomposition
317
318 // FIXME: h5_proxy bug?
319 // if (!g_dft.has_key("dft_code")) {
320 // throw std::runtime_error{fmt::format(
321 // "The dft_input group in the hdf5 {} does not contain the key dft_code.\nMost likely, this hdf5 file generated using a legacy dft_tools converter.",
322 // filename)};
323 // }
324
325 obe.C_space = local_space{spin_kind, atomic_shells, decomposition, U_rotations,
326 read_spherical_to_dft_basis(as<std::string>(g_dft["dft_code"]), atomic_shells)};
327 // rotate to the local basis.
328 auto obe_final = rotate_local_basis(U_rotations, std::move(obe));
329 // FIXME: The dft_tools converters do not write the spherical_to_dft rotation for all cases.
330 // Solution: hard-code the rotations for each dft_code (read from hdf5) and save in the local space.
331 // The only issue is dft_code breaks backward compatibility with older hdf5 files.
332 // Therefore the user can either pass at this stage this rotation or in the function that constructs the
333 // slate hamiltonian.
334 return {total_density, std::move(obe_final)};
335 }
336
337 //-------------------------------------------------------
338 // Prepare one-body elements with the Θ projectors.
340 //check for group and throw error
341 auto root = h5::proxy{filename, 'r'};
342 if (!root.has_group("dft_parproj_input")) {
343 throw std::runtime_error{fmt::format("The hdf5 file {} does not contain the group dft_parproj_input", filename)};
344 }
345
346 // all the atomic shells
347 auto atomic_shells = read_atomic_shells(filename, ReadMode::ThetaProjectors);
348
349 // The decomposition and rotations must be embedded from the C spcae to the W space
350 auto new_block_decomposition = detail::inject_to_new_space(obe.C_space.atoms_block_decomposition(), obe.C_space.atomic_shells(), atomic_shells);
351
352 // The local space expanded from C to W
353 auto W_space = local_space{obe.C_space.spin_kind(), atomic_shells, new_block_decomposition, {}, {}};
354
355 // rotation matrices using ThetaProjector mode
356 auto rot_mats = read_rotation_matrices(filename, ReadMode::ThetaProjectors);
357
358 // read and rotate projectors
359 auto atom_decomp = W_space.atomic_decomposition() | tl::to<std::vector<long>>();
360 auto P_k = load_rotate_and_format_projectors(filename, ReadMode::ThetaProjectors, rot_mats, atom_decomp);
361 auto theta_proj = downfolding_projector{.spin_kind = obe.C_space.spin_kind(), .P_k = std::move(P_k), .n_bands_per_k = obe.H.n_bands_per_k};
362
363 // create a new IBZ symmetrizer that spans all atoms instead of just the correlated atoms
364 auto symm_ops = (obe.ibz_symm_ops) ? std::optional<ibz_symmetry_ops>(read_ibz_symmetry_ops(filename, ReadMode::ThetaProjectors)) :
365 std::optional<ibz_symmetry_ops>{};
366
367 return one_body_elements_on_grid{.H = obe.H, .C_space = W_space, .P = theta_proj, .ibz_symm_ops = symm_ops};
368 }
369
370 //-------------------------------------------------------
371 // Prepare one-body elements along high-symmetry k-path.
373 // check for group and throw error
374 auto root = h5::proxy{filename, 'r'};
375 if (!root.has_group("dft_bands_input")) {
376 throw std::runtime_error{fmt::format("The hdf5 file {} does not contain the group dft_bands_input", filename)};
377 }
378
379 // disperion and k weights
380 auto [H_k, n_bands_per_k, k_weights] = read_bands_and_weights(filename, ReadMode::Bands);
381
382 // rotation matrices in csc mode
383 auto rot_mats = read_rotation_matrices(filename, ReadMode::Correlated);
384
385 // read and rotate projectors
386 auto atom_decomp = obe.C_space.atomic_decomposition() | tl::to<std::vector<long>>();
387 auto P_k = load_rotate_and_format_projectors(filename, ReadMode::Bands, rot_mats, atom_decomp);
388
389 // construct one-body elements (ibz_symm_ops are needed so we drop)
390 auto eps_k = band_dispersion{
391 .spin_kind = obe.C_space.spin_kind(), .H_k = std::move(H_k), .n_bands_per_k = n_bands_per_k, .k_weights = {}, .matrix_valued = false};
392 auto proj = downfolding_projector{.spin_kind = obe.C_space.spin_kind(), .P_k = std::move(P_k), .n_bands_per_k = n_bands_per_k};
393 auto obe1 = one_body_elements_on_grid{.H = eps_k, .C_space = obe.C_space, .P = proj, .ibz_symm_ops = {}};
394
395 // rotate to the local basis that the self-energies will be defined in.
396 return rotate_local_basis(obe.C_space.rotation_from_dft_to_local_basis(), std::move(obe1));
397 }
398} // namespace triqs::modest
Describe the atomic orbitals within downfolded space.
spin_kind_e spin_kind() const
Spin kind of 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.
std::vector< atomic_orbs > const & atomic_shells() const
List of all atomic shells spanning the space.
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.
one_body_elements_on_grid one_body_elements_on_high_symmetry_path(std::string const &filename, one_body_elements_on_grid const &obe)
Create a one-body elements along specific k-path.
Definition loaders.cpp:372
std::pair< double, one_body_elements_on_grid > one_body_elements_from_dft_converter(std::string const &filename, double threshold, bool diagonalize_hloc)
Create a one-body elements with orthonormalized projectors.
Definition loaders.cpp:254
one_body_elements_on_grid one_body_elements_with_theta_projectors(std::string const &filename, one_body_elements_on_grid const &obe)
Create a one-body elements with the projectors.
Definition loaders.cpp:339
std::vector< T > flatten(const std::vector< std::vector< T > > &nested)
Definition nda_supp.hpp:26
bool is_diagonal(nda::matrix< T > const &M)
Definition nda_supp.hpp:32
DFTCode dft_code_to_enum(std::string const &code)
Definition utils.hpp:22
nda::matrix< dcomplex > get_spherical_to_dft_rotation(DFTCode code, long l)
nda::array< dcomplex, 4 > load_rotate_and_format_projectors(std::string const &filename, ReadMode mode, std::vector< cmat_t > const &rot_mats, std::vector< long > const &atom_decomp)
Definition loaders.cpp:115
std::tuple< nda::array< dcomplex, 4 >, nda::matrix< long >, nda::array< double, 1 > > read_bands_and_weights(std::string filename, ReadMode mode)
Definition loaders.cpp:156
nda::array< nda::matrix< dcomplex >, 1 > read_spherical_to_dft_basis(std::string dft, std::vector< atomic_orbs > const &atomic_shells)
Definition loaders.cpp:192
ibz_symmetry_ops read_ibz_symmetry_ops(auto const &filename, ReadMode mode)
Definition loaders.cpp:202
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.
spin_kind_e
Kind of σ index.
nda::matrix< dcomplex > svd(const nda::matrix< dcomplex > &A)
Definition loaders.cpp:18
std::pair< nda::array< std::vector< long >, 2 >, nda::array< nda::matrix< dcomplex >, 2 > > discover_symmetries(nda::array< nda::matrix< dcomplex >, 2 > const &Hloc0, std::vector< atomic_orbs > const &atomic_shells, double block_threshold, bool diagonalize_hloc)
Find symmetries of the component of a Hamiltonian to determine a GF block structure.
Definition loaders.cpp:55
std::vector< cmat_t > read_rotation_matrices(std::string const &filename, ReadMode mode)
Definition loaders.cpp:92
spin_kind_e read_spin_kind(auto const &filename)
Definition loaders.cpp:172
std::vector< atomic_orbs > read_atomic_shells(auto const &filename, ReadMode mode)
Definition loaders.cpp:180
static constexpr auto r_all
Definition defs.hpp:40
generator< std::pair< long, nda::range > > enumerated_sub_slices(auto sub_div)
nda::matrix< dcomplex > cmat_t
Definition defs.hpp:38
Info on an atomic shell.
long dim
Dimension of the orbital space.
The one-body dispersion as a function of momentum.
nda::array< long, 2 > n_bands_per_k
Number of bands for each k-point and .
spin_kind_e spin_kind
Spin kind of the one-body data.
The projector that downfolds the energy bands onto a set of localized atomic-like orbitals.
spin_kind_e spin_kind
Spin kind of the one-body data.
Irreducible Brillouin Zone (IBZ) symmetry operations to symmetrize observables over the entire Brillo...
A one-body elements struct where all of the underlying data exists on a fixed momentum grid.
band_dispersion H
Band dispersion.
C2PY_IGNORE std::optional< ibz_symmetry_ops > ibz_symm_ops
IBZ symmetrizer after a k-sum.