12#include <triqs/gfs.hpp>
52 std::vector<nda::matrix<dcomplex>> mats;
53 std::vector<long> permutation;
57 bool operator==(op
const &)
const =
default;
60 friend void mpi_broadcast(op &x, mpi::communicator c = {},
int root = 0) {
61 mpi::broadcast(x.mats, c, root);
62 mpi::broadcast(x.permutation, c, root);
63 mpi::broadcast(x.time_inv, c, root);
76 friend std::ostream &
operator<<(std::ostream &out, ibz_symmetry_ops
const &ibz);
79 template <
typename T> nda::array<T, 2>
symmetrize(nda::array<T, 2>
const &X)
const {
80 auto [n_alpha, n_sigma] = X.shape();
81 nda::array<T, 2> result(n_alpha, n_sigma);
82 for (
auto [a, s] : result.indices()) { result(a, s) = nda::zeros<dcomplex>(X(a, s).shape()); }
83 auto n_symm = double(this->ops.size());
84 for (
auto const &sym_op : this->
ops) {
85 for (
auto &&[ialpha, jalpha, mat] : zip(range(n_alpha), sym_op.permutation, sym_op.mats)) {
86 for (
auto sigma : range(n_sigma)) {
87 result(jalpha, sigma) += mat * (sym_op.time_inv ? transpose(X(ialpha, sigma)) : X(ialpha, sigma)) * dagger(mat) / n_symm;
99 template <
typename Mesh>
100 block2_gf<Mesh, matrix_valued>
symmetrize(block2_gf<Mesh, matrix_valued>
const &Gin,
auto const &atomic_decomposition)
const {
104 auto n_sigma = Gout.size2();
105 auto n_symm = double(this->ops.size());
108 enumerated_sub_slices(atomic_decomposition) | stdv::transform([](
auto &&x) {
return std::get<1>(x); }) | tl::to<std::vector>();
111 for (
auto sigma : range(n_sigma)) {
112 for (
auto const &op : this->
ops) {
113 auto const &mat = op.mats[alpha];
114 auto R_jalpha = range_list[op.permutation[alpha]];
115 for (
auto om : Gin(0, sigma).mesh()) {
116 auto A = nda::matrix<dcomplex>{Gin(0, sigma)[om](R_alpha, R_alpha)};
117 Gout(0, sigma)[om](R_jalpha, R_jalpha) += mat * (op.time_inv ? transpose(A) : A) * dagger(mat) / n_symm;
135 for (
auto &sym_op : result.ops)
136 for (
auto &&[a, b] : zip(range(U.extent(0)), sym_op.permutation)) sym_op.mats[a] = dagger(U(b, 0)) * sym_op.mats[a] * U(a, 0);
gf_struct2_t get_struct(block2_gf< Mesh, matrix_valued > const &g)
block2_gf< Mesh, matrix_valued > make_block2_gf(Mesh const &mesh, gf_struct2_t const &gf_s)
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.
generator< std::pair< long, nda::range > > enumerated_sub_slices(auto sub_div)
Irreducible Brillouin Zone (IBZ) symmetry operations to symmetrize observables over the entire Brillo...
friend void mpi_broadcast(ibz_symmetry_ops &x, mpi::communicator c={}, int root=0)
MPI broadcast.
friend std::ostream & operator<<(std::ostream &out, ibz_symmetry_ops const &ibz)
bool operator==(ibz_symmetry_ops const &) const =default
Equality comparison operator.
block2_gf< Mesh, matrix_valued > symmetrize(block2_gf< Mesh, matrix_valued > const &Gin, auto const &atomic_decomposition) const
nda::array< T, 2 > symmetrize(nda::array< T, 2 > const &X) const