TRIQS/triqs_modest 3.3.0
Modular Electronic Structure Toolkit
Loading...
Searching...
No Matches
embed_supp.hpp
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#pragma once
7#include "defs.hpp"
8#include "gf_supp.hpp"
9#include "nda_supp.hpp"
10#include "range_supp.hpp"
11#include "enumerate_slice.hpp"
12
13namespace triqs::modest::detail {
14 auto constexpr r_all = nda::range::all;
15
16 template <int Rank> constexpr bool has_frequency = (Rank == 3 || Rank == 5);
17
18 // Rank 2: T(r, r)
19 template <typename T> auto extract_diagonal(nda::array<T, 2> const &M, nda::range r) { return M(r, r); }
20 template <typename T> void embed_diagonal(nda::array<T, 2> &M, nda::range r, nda::array<T, 2> const &block) { M(r, r) = block; }
21
22 // Rank 3: T(r_all, r, r) - frequency on axis 0
23 template <typename T> auto extract_diagonal(nda::array<T, 3> const &M, nda::range r) { return M(r_all, r, r); }
24 template <typename T> void embed_diagonal(nda::array<T, 3> &M, nda::range r, nda::array<T, 3> const &block) { M(r_all, r, r) = block; }
25
26 // Rank 4: T(r, r, r, r)
27 template <typename T> auto extract_diagonal(nda::array<T, 4> const &M, nda::range r) { return M(r, r, r, r); }
28 template <typename T> void embed_diagonal(nda::array<T, 4> &M, nda::range r, nda::array<T, 4> const &block) { M(r, r, r, r) = block; }
29
30 // Rank 5: T(r_all, r, r, r, r) - frequency on axis 0
31 template <typename T> auto extract_diagonal(nda::array<T, 5> const &M, nda::range r) { return M(r_all, r, r, r, r); }
32 template <typename T> void embed_diagonal(nda::array<T, 5> &M, nda::range r, nda::array<T, 5> const &block) { M(r_all, r, r, r, r) = block; }
33
34 // Constrauct zero array of given rank and type
35 template <int Rank, typename T> auto make_zero_array(long dim, long n_w = 0) {
36 if constexpr (Rank == 2) {
37 return nda::zeros<T>(dim, dim);
38 } else if constexpr (Rank == 3) {
39 return nda::zeros<T>(n_w, dim, dim);
40 } else if constexpr (Rank == 4) {
41 return nda::zeros<T>(dim, dim, dim, dim);
42 } else if constexpr (Rank == 5) {
43 return nda::zeros<T>(n_w, dim, dim, dim, dim);
44 }
45 }
46
47 // From a BlockGf return it's data as a vector (blocks) of arrays
48 template <typename Mesh> std::vector<nda::array<dcomplex, 3>> make_data_view_from_block_gf(block_gf<Mesh, matrix_valued> const &gf) {
49 std::vector<nda::array<dcomplex, 3>> data;
50 for (auto block_idx = 0; block_idx < gf.size(); ++block_idx) { data.push_back(gf[block_idx].data()); }
51 return data;
52 }
53
54 // From a vector of BlockGf return it's data as a vector (impurities) of vector (blocks) of arrays
55 template <typename Mesh>
56 std::vector<std::vector<nda::array<dcomplex, 3>>> make_data_view_from_block_gfs(std::vector<block_gf<Mesh, matrix_valued>> const &gfs) {
57 return gfs | stdv::transform([&](auto g) { return make_data_view_from_block_gf(g); }) | tl::to<std::vector>();
58 }
59
60 // Gather the blocks from a Block2Gf (alpha, sigma) in a vector (sigma) of data arrays
61 template <typename Mesh> std::vector<nda::array<dcomplex, 3>> gather_blocks_to_data_view(block2_gf<Mesh, matrix_valued> const &g) {
62 auto n_sigma = g.size2();
63 auto decomp = get_struct(g).dims(r_all, 0) | tl::to<std::vector>();
64
65 auto n_w = g(0, 0).mesh().size();
66 auto dim = stdr::fold_left(decomp, 0, std::plus<>());
67
68 auto data = range(n_sigma) | stdv::transform([dim, n_w](auto) { return nda::array<dcomplex, 3>(n_w, dim, dim); }) | tl::to<std::vector>();
69 for (auto sigma : range(n_sigma)) {
70 for (auto &&[index, sli] : enumerated_sub_slices(decomp)) { data[sigma](r_all, sli, sli) = g(index, sigma).data(); }
71 };
72 return data;
73 }
74
75 template <typename T> auto gather_blocks_to_data_view(nda::array<nda::matrix<T>, 2> const &M) {
76 auto n_sigma = M.extent(1);
77 auto decomp = range(M.extent(0)) | stdv::transform([&](auto const &alpha) { return M(alpha, 0).shape()[0]; }) | tl::to<std::vector>();
78 auto dim = stdr::fold_left(decomp, 0, std::plus<>());
79 nda::array<nda::array<T, 2>, 2> data(1, n_sigma);
80 for (auto sigma : range(n_sigma)) {
81 data(0, sigma) = nda::zeros<T>(dim, dim);
82 for (auto &&[index, sli] : enumerated_sub_slices(decomp)) { data(0, sigma)(sli, sli) = M(index, sigma); }
83 };
84 return data;
85 }
86
87 // Make a BlockGf from data
88 template <typename Mesh>
89 block_gf<Mesh, matrix_valued> make_block_gf_from_data_view(std::vector<nda::array<dcomplex, 3>> const &data_view, gf_struct_t const &gf_struct,
90 Mesh const &mesh) {
91 auto gf = block_gf<Mesh, matrix_valued>(mesh, gf_struct);
92 for (auto &&[block_idx, block] : enumerate(data_view)) { gf[block_idx].data() = block; }
93 return gf;
94 }
95
96 // Make a Block2Gf from data
97 template <typename Mesh>
98 block2_gf<Mesh, matrix_valued> make_block2_gf_from_data_view(std::vector<nda::array<dcomplex, 3>> const &data_view, gf_struct2_t const &gf_struct2,
99 Mesh const &mesh) {
100 auto gf2 = make_block2_gf(mesh, gf_struct2);
101 auto n_sigma = gf2.size2();
102 auto sigma_embed_decomp = get_struct(gf2).dims(r_all, 0) | tl::to<std::vector>();
103 for (auto [alpha, r_alpha] : enumerated_sub_slices(sigma_embed_decomp)) {
104 for (auto sigma : range(n_sigma)) { gf2(alpha, sigma).data() = data_view[sigma](r_all, r_alpha, r_alpha); }
105 }
106 return gf2;
107 }
108
109 // Convert between matrix<T> and array<T,2>
110 template <typename T> auto matrix_to_array(std::vector<std::vector<nda::matrix<T>>> const &data) {
111 auto tmp_data = std::vector<std::vector<nda::array<T, 2>>>(data.size());
112 for (auto imp : range(data.size())) {
113 for (auto &&[block, block_data] : enumerate(data[imp])) { tmp_data[imp].emplace_back(block_data); }
114 }
115 return tmp_data;
116 }
117
118 // Convert between array<T,2> and matrix<T>
119 template <typename T> auto array_to_matrix(std::vector<std::vector<nda::array<T, 2>>> const &data) {
120 auto tmp_data = std::vector<std::vector<nda::matrix<T>>>(data.size());
121 for (auto imp : range(data.size())) {
122 for (auto &&[block, block_data] : enumerate(data[imp])) { tmp_data[imp].emplace_back(block_data); }
123 }
124 return tmp_data;
125 }
126
127 // Reshape data array to a block2 (nda::array<array_t, 2>) using decomposition
128 template <typename T> auto data_array_to_block2_array(std::vector<nda::array<T, 2>> const &data_view, std::vector<long> const &sigma_embed_decomp) {
129 auto n_alpha = long(sigma_embed_decomp.size());
130 auto n_sigma = long(data_view.size());
131 auto block2_array = nda::array<nda::array<T, 2>, 2>(n_alpha, n_sigma);
132 for (auto &&[alpha, r_alpha] : enumerated_sub_slices(sigma_embed_decomp)) {
133 for (auto sigma : range(n_sigma)) { block2_array(alpha, sigma) = data_view[sigma](r_alpha, r_alpha); }
134 }
135 return block2_array;
136 }
137
138} // namespace triqs::modest::detail
gf_struct2_t get_struct(block2_gf< Mesh, matrix_valued > const &g)
Definition gf_supp.hpp:52
block2_gf< Mesh, matrix_valued > make_block2_gf(Mesh const &mesh, gf_struct2_t const &gf_s)
Definition gf_supp.hpp:41
generator< std::pair< long, nda::range > > enumerated_sub_slices(auto sub_div)
nda::array< long, 2 > dims
Definition gf_supp.hpp:37