11#include <fmt/ranges.h>
32 std::vector<long> sigma_embed_decomp;
35 std::vector<std::vector<long>> imp_decomps;
38 std::vector<std::string> _sigma_names;
41 std::vector<std::string> alpha_names;
59 imp_block_t() =
default;
60 imp_block_t(
long n_imp,
long gamma,
long tau) : imp_idx(n_imp), gamma(gamma), tau(tau) {}
61 friend bool operator==(imp_block_t
const &, imp_block_t
const &) =
default;
64 friend std::ostream &
operator<<(std::ostream &out, imp_block_t
const &x) {
65 return out << fmt::format(
"(imp_idx = {}, γ = {}, τ = {})", x.imp_idx, x.gamma, x.tau);
72 nda::array<imp_block_t, 2> psi;
75 std::vector<nda::array<std::vector<std::array<long, 2>>, 2>> reverse_psi;
88 embedding(std::vector<long> sigma_embed_decomposition, std::vector<std::vector<long>> imp_decompositions, nda::array<imp_block_t, 2> psi,
99 imp_block_t
operator[](
long alpha,
long sigma)
const {
return psi(alpha, sigma); }
103 [[nodiscard]] nda::array<imp_block_t, 2>
get_psi()
const {
return psi; }
106 [[nodiscard]]
long n_alpha()
const {
return psi.extent(0); }
109 [[nodiscard]]
long n_sigma()
const {
return psi.extent(1); }
112 [[nodiscard]]
long n_gamma(
long imp_idx)
const {
return long(imp_decomps[imp_idx].size()); }
115 [[nodiscard]]
long n_impurities()
const {
return long(imp_decomps.size()); }
118 [[nodiscard]] std::vector<std::string>
sigma_names()
const {
return _sigma_names; };
121 [[nodiscard]] std::vector<long>
imp_decomposition(
long imp_idx)
const {
return imp_decomps[imp_idx]; };
130 std::string
description(
bool verbosity =
false)
const;
165 embedding replace(
long imp_idx_to_remove,
long imp_idx_to_replace_with)
const;
200 embedding split(
long imp_idx, std::vector<long>
const &block_list)
const;
207 auto make_block_matrix = [](
auto const &gf_struct) {
208 return gf_struct | stdv::transform([](
auto &x) {
209 auto bl_size = x.second;
210 return nda::zeros<dcomplex>(bl_size, bl_size);
212 | tl::to<std::vector<nda::matrix<dcomplex>>>();
214 return imp_block_shape() | stdv::transform([&](
auto const &gf_struct) {
215 auto Sigma_static = make_block_matrix(gf_struct);
216 auto Sigma_dynamic = block_gf<Mesh, matrix_valued>{mesh, gf_struct};
217 return std::make_pair(Sigma_dynamic, Sigma_static);
219 | tl::to<std::vector>();
233 template <
typename Mesh> block2_gf<Mesh, matrix_valued>
embed(std::vector<block_gf<Mesh, matrix_valued>>
const &Sigma_imp_vec)
const;
236 template <
typename Mesh>
237 std::pair<block2_gf<Mesh, matrix_valued>,
block2_matrix_t>
embed(std::vector<block_gf<Mesh, matrix_valued>>
const &Sigma_imp_vec,
238 std::vector<block_matrix_t>
const &Sigma_imp_static_vec)
const;
244 nda::array<nda::array<dcomplex, 3>, 2>
embed(std::vector<std::vector<nda::array<dcomplex, 3>>>
const &Sigma_imp_vec)
const;
247 std::vector<nda::array<dcomplex, 5>>
embed(std::vector<nda::array<dcomplex, 5>>
const &pi_imp_vec)
const;
255 template <
typename Mesh> std::vector<block_gf<Mesh, matrix_valued>>
extract(block2_gf<Mesh, matrix_valued>
const &g_loc)
const;
261 std::vector<std::vector<nda::array<dcomplex, 3>>>
extract(nda::array<dcomplex, 4>
const &g_loc)
const;
264 std::vector<nda::array<dcomplex, 5>>
extract(nda::array<dcomplex, 5>
const &Pi_loc)
const;
289 embedding
make_embedding_impl(local_space
const &C_space, nda::array<std::vector<long>, 2>
const &block_decomposition,
290 std::optional<std::vector<long>>
const &atom_to_imp = std::nullopt);
301 embedding
make_embedding(local_space
const &C_space,
bool use_atom_equivalences =
true);
315 template <
typename Mesh> block2_gf<Mesh, matrix_valued>
embedding::embed(std::vector<block_gf<Mesh, matrix_valued>>
const &Sigma_imp_vec)
const {
317 if (not
all_equal(Sigma_imp_vec | stdv::transform([](
auto &&x) ->
decltype(
auto) {
return x[0].mesh(); })))
318 throw std::runtime_error{
"[embedding_desc::embed]: meshes of solvers are not all equal"};
320 auto const &mesh = Sigma_imp_vec[0][0].mesh();
324 for (
auto &&[S, m] : zip(Sigma_embed, psi)) {
325 if (m.imp_idx == -1)
continue;
326 S() = Sigma_imp_vec[m.imp_idx][m.gamma +
n_gamma(m.imp_idx) * m.tau];
339 template <
typename Mesh>
341 std::vector<block_matrix_t>
const &Sigma_imp_static_vec)
const {
342 if (Sigma_imp_vec.size() != Sigma_imp_static_vec.size()) {
343 throw std::runtime_error(fmt::format(
"The lists of self-energies are not equal {} != {}", Sigma_imp_vec.size(), Sigma_imp_static_vec.size()));
345 return {this->
embed(Sigma_imp_vec), this->
embed(Sigma_imp_static_vec)};
357 template <
typename Mesh> std::vector<block_gf<Mesh, matrix_valued>>
embedding::extract(block2_gf<Mesh, matrix_valued>
const &g)
const {
359 if (
auto decomp =
get_struct(g).dims(
r_all, 0) | tl::to<std::vector>(); decomp != this->sigma_embed_decomp) {
360 if (decomp.size() != 1)
throw std::runtime_error{
"extract: g should have decomp = sigma_embedding_decomp or [1]"};
366 auto extract_one_imp = [&](
long n_imp) {
367 auto gimp = block_gf{g(0, 0).mesh(), imp_gf_stru_list[n_imp]};
368 auto const &rpsi = reverse_psi[n_imp];
369 for (
auto [gamma, tau] : rpsi.indices()) {
370 auto [alpha, sigma] = rpsi(gamma, tau)[0];
371 gimp[gamma +
n_gamma(n_imp) * tau].data() = g(alpha, sigma).data();
375 return range(
n_impurities()) | stdv::transform(extract_one_imp) | tl::to<std::vector>();
380 std::vector<std::vector<long>>
const &atom_partition) {
388#define INSTANTIATE(Mesh) \
389 template block2_gf<Mesh, matrix_valued> embedding::embed(std::vector<block_gf<Mesh, matrix_valued>> const &) const; \
390 template std::pair<block2_gf<Mesh, matrix_valued>, block2_matrix_t> embedding::embed(std::vector<block_gf<Mesh, matrix_valued>> const &, \
391 std::vector<block_matrix_t> const &) const; \
392 template std::vector<block_gf<Mesh, matrix_valued>> embedding::extract(block2_gf<Mesh, matrix_valued> const &) const; \
393 template std::vector<std::pair<block_gf<Mesh, matrix_valued>, block_matrix_t>> embedding::make_zero_imp_self_energies(Mesh const &);
friend void h5_write(h5::group g, std::string const &name, embedding const &x)
h5 read/write
C2PY_IGNORE gf_struct2_t sigma_embed_block_shape() const
Gf block structure for Σ_embed.
long n_impurities() const
Number of impurities.
long n_gamma(long imp_idx) const
Number of blocks in γ for the Σ_imp[imp_idx].
long n_sigma() const
Number of blocks in σ for the Σ_embed.
std::vector< gf_struct_t > imp_block_shape() const
Gf block structure for the impurity solvers.
embedding flip_spin(long alpha) const
Flip the spins (σ) for block α.
bool operator==(embedding const &other) const =default
embedding split(long imp_idx, std::initializer_list< const char * > x)=delete
nda::array< imp_block_t, 2 > get_psi() const
the mapping table ψ
std::vector< std::string > sigma_names() const
The names of the sigma indices.
std::vector< block_gf< Mesh, matrix_valued > > extract(block2_gf< Mesh, matrix_valued > const &g_loc) const
embed tensors
long n_alpha() const
Number of blocks in α for the Σ_embed.
std::vector< long > imp_decomposition(long imp_idx) const
The impurity decomposition.
std::string description(bool verbosity=false) const
Summarize the embedding object.
embedding drop(long imp_idx) const
Remove an impurity from the embedding table ψ
friend std::ostream & operator<<(std::ostream &out, embedding const &E)
stream
friend void h5_read(h5::group g, std::string const &name, embedding &x)
std::vector< std::pair< block_gf< Mesh, matrix_valued >, block_matrix_t > > make_zero_imp_self_energies(Mesh const &mesh)
embedding split(long imp_idx, std::function< bool(long)> p) const
Predicate p (long block_idx) -> 0 or 1.
embedding replace(long imp_idx_to_remove, long imp_idx_to_replace_with) const
Replaces one impurity in the embedding table ψ.
imp_block_t operator[](long alpha, long sigma) const
bracket accessor: [α, σ] -> the corresponding impurity block (n_imp, γ, τ)
block2_gf< Mesh, matrix_valued > embed(std::vector< block_gf< Mesh, matrix_valued > > const &Sigma_imp_vec) const
embed single-particle quantities
#define INSTANTIATE(Mesh)
embedding make_embedding(local_space const &C_space, bool use_atom_equivalences)
Make an embedding from the local space.
block2_gf< Mesh, matrix_valued > make_block2_gf(Mesh const &mesh, gf_struct2_t const &gf_s)
block2_gf< Mesh > decomposition_view(block2_gf< Mesh > const &g, gf_struct2_t const &stru)
gf_struct_t get_struct(block_gf< Mesh > const &g)
std::pair< one_body_elements_on_grid, embedding > make_embedding_with_clusters(one_body_elements_on_grid obe, std::vector< std::vector< long > > const &atom_partition)
std::ostream & operator<<(std::ostream &out, one_body_elements_on_grid const &)
one_body_elements_on_grid permute_local_space(std::vector< std::vector< long > > const &atom_partition, one_body_elements_on_grid const &obe)
embedding make_embedding_impl(local_space const &C_space, nda::array< std::vector< long >, 2 > const &block_decomposition, std::optional< std::vector< long > > const &atom_to_imp)
nda::array< nda::matrix< dcomplex >, 2 > block2_matrix_t
static constexpr auto r_all
bool all_equal(R const &r)
Determines if all elements in the given range are equal.
std::vector< nda::matrix< dcomplex > > block_matrix_t
A one-body elements struct where all of the underlying data exists on a fixed momentum grid.