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