7#include <triqs/tb/tb_hamiltonian.hpp>
10#include <triqs/mesh/imfreq.hpp>
12#include "triqs/lattice/bz_integrators.hpp"
13#include "triqs/lattice/gloc.hpp"
16#include <triqs/gfs/functions/density.hpp>
17#include <triqs/utility/root_finder.hpp>
18#include "triqs/tb/superlattice.hpp"
22 using namespace triqs::tb;
23 using namespace triqs::lattice;
31 std::vector<tb_hamiltonian>
H;
40 mpi::broadcast(x.
C_space, c, root);
41 mpi::broadcast(x.
H, c, root);
45 one_body_elements_tb
one_body_elements_from_model(std::vector<std::array<long, 3>>
const &Rs, std::vector<nda::array<dcomplex, 2>>
const &HR,
46 spin_kind_e spin_kind, std::vector<atomic_orbs> atomic_shells);
64 std::vector<atomic_orbs> atomic_shells);
79 spin_kind_e spin_kind, std::vector<atomic_orbs> atomic_shells);
85 std::vector<atomic_orbs> atomic_shells);
95 nda::array<nda::matrix<dcomplex>, 2>
Hloc(std::vector<tb_hamiltonian>
const &H_sigma, std::vector<atomic_orbs>
const &atomic_shells);
104 nda::array<nda::matrix<dcomplex>, 2>
impurity_levels(one_body_elements_tb
const &obe);
148 template <
typename Mesh>
149 block2_gf<Mesh, matrix_valued>
gloc(
one_body_elements_tb const &obe,
double mu, block2_gf<Mesh, matrix_valued>
const &Sigma_dynamic,
150 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt) {
152 auto &mesh = Sigma_dynamic(0, 0).mesh();
156 if (n_sigma != Sigma_static.shape(1)) {
throw std::runtime_error(
"Mismatch between the spin channels in Sigma_Static and Sigma_Dynamic"); }
157 if (n_sigma != obe.
H.size()) {
throw std::runtime_error(
"Mismatch between the spin channels in Sigma and spin channels in Hamiltonian."); }
162 for (
auto sigma : range(n_sigma)) {
165 auto Sigma_full_space = gfs::gf(mesh, {obe.
H[sigma].n_orbitals(), obe.
H[sigma].n_orbitals()});
167 for (
auto [n, w] : enumerate(mesh)) {
168 Sigma_full_space.data()(n, R, R) = Sigma_dynamic(block, sigma).data()(n,
r_all,
r_all) + Sigma_static(block, sigma);
172 gloc_result(0, sigma) = triqs::lattice::gloc(obe.
H[sigma], mu, Sigma_full_space, opt);
190 template <
typename Mesh>
191 block2_gf<Mesh, matrix_valued>
gloc(Mesh
const &mesh,
one_body_elements_tb const &obe,
double mu, triqs::lattice::bz_int_options
const &opt) {
193 for (
auto sigma : range(obe.
C_space.
n_sigma())) { result(0, sigma) =
gloc(mesh, obe.
H[sigma], mu, opt); }
213 template <
typename Mesh>
215 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt) {
221 auto Gloc =
gloc(obe, mu, Sigma_dynamic, Sigma_static, opt);
223 for (
auto sigma : range(n_sigma)) {
224 n += real(nda::trace(
density(Gloc(0, sigma))));
245 template <
typename Mesh>
247 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt,
248 std::string method =
"dichotomy",
double precision = 1.e-5,
bool verbosity =
true) {
249 std::function<double(
double)> f = [&obe, &Sigma_dynamic, &Sigma_static, &opt](
double x) {
250 return density(obe, x, Sigma_dynamic, Sigma_static, opt);
252 return std::get<0>(triqs::utility::root_finder(method, f, 0.0, target_density, precision, 0.5, 1000,
"Chemical Potential",
"Total Density", verbosity));
269 template <
typename Mesh>
271 triqs::lattice::bz_int_options
const &opt, std::string method =
"dichotomy",
double precision = 1.e-5,
272 bool verbosity =
true) {
275 auto Sigma_static = nda::array<nda::matrix<dcomplex>, 2>(1, obe.
C_space.
n_sigma());
276 for (
auto [i, j] : Sigma_static.indices()) { Sigma_static(i, j) = nda::zeros<dcomplex>(obe.
C_space.
dim(), obe.
C_space.
dim()); }
277 return find_chemical_potential(target_density, obe, Sigma_dynamic, Sigma_static, opt, method, precision, verbosity);
283 template block2_gf<mesh::imfreq, matrix_valued>
gloc(one_body_elements_tb
const &obe,
double mu,
284 block2_gf<mesh::imfreq, matrix_valued>
const &Sigma_dynamic,
285 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static,
286 triqs::lattice::bz_int_options
const &opt);
288 template block2_gf<mesh::imfreq, matrix_valued>
gloc(mesh::imfreq
const &mesh, one_body_elements_tb
const &obe,
double mu,
289 triqs::lattice::bz_int_options
const &opt);
291 template double density(one_body_elements_tb
const &obe,
double mu, block2_gf<mesh::imfreq, matrix_valued>
const &Sigma_dynamic,
292 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt);
295 block2_gf<mesh::imfreq, matrix_valued>
const &Sigma_dynamic,
296 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt,
297 std::string method,
double precision,
bool verbosity);
299 template double find_chemical_potential(
double const target_density, one_body_elements_tb
const &obe, mesh::imfreq
const &mesh,
300 triqs::lattice::bz_int_options
const &opt, std::string method,
double precision,
bool verbosity);
Describe the atomic orbitals within downfolded space.
long n_sigma() const
Dimension of the index.
long dim() const
Dimension of the correlated space.
C2PY_IGNORE gf_struct2_t Gc_block_shape() const
Shape of the Green function in the correlated space, without block decomposition.
block2_gf< Mesh, matrix_valued > gloc(one_body_elements_on_grid const &obe, double mu, block2_gf< Mesh, matrix_valued > const &Sigma_dynamic, nda::array< nda::matrix< dcomplex >, 2 > const &Sigma_static)
Compute local Green's function on a mesh.
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.
double find_chemical_potential(double const target_density, one_body_elements_on_grid const &obe, double beta, std::string method="dichotomy", double precision=1.e-5, bool verbosity=true)
Find the chemical potenital from the local Green's function given a target density.
double density(one_body_elements_on_grid const &obe, double mu, block2_gf< Mesh, matrix_valued > const &Sigma_dynamic, nda::array< nda::matrix< dcomplex >, 2 > const &Sigma_static)
Compute the density of the lattice Green's function with a self-energy using Woodbury.
one_body_elements_tb one_body_elements_from_wannier90(std::string const &wannier_file_path, spin_kind_e spin_kind, std::vector< atomic_orbs > atomic_shells)
Construct a one-body elements TB object from Wannier90 in the case of a single spin index.
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_tb make_obe_from_tb(std::vector< tb_hamiltonian > H_sigma, spin_kind_e spin_kind, std::vector< atomic_orbs > atomic_shells)
Helper to contruct and return an OBE_tb object given a list of tb_Hamiltonians of length n_sigma.
one_body_elements_tb rotate(one_body_elements_tb const &obe, nda::matrix< dcomplex > const &U)
Rotate a tight-binding Hamiltonian by a unitary matrix .
one_body_elements_tb fold(tb::superlattice const &sl, one_body_elements_tb const &obe)
spin_kind_e
Kind of σ index.
nda::array< nda::matrix< dcomplex >, 2 > Hloc(std::vector< tb_hamiltonian > const &H_sigma, std::vector< atomic_orbs > const &atomic_shells)
Compute given tight binding Hamiltonians.
one_body_elements_tb one_body_elements_from_model(std::vector< std::array< long, 3 > > const &Rs, std::vector< nda::array< dcomplex, 2 > > const &HR, spin_kind_e spin_kind, std::vector< atomic_orbs > atomic_shells)
static constexpr auto r_all
generator< std::pair< long, nda::range > > enumerated_sub_slices(auto sub_div)
nda::array< long, 2 > dims
A one-body elements using a tight-binding Hamiltonian.
bool operator==(one_body_elements_tb const &) const =default
Equality comparison operator.
friend void mpi_broadcast(one_body_elements_tb &x, mpi::communicator c={}, int root=0)
MPI broadcast.
std::vector< tb_hamiltonian > H
List of TB Hamiltonians.
local_space C_space
Local space.