7#include <triqs/lattice/tb_hamiltonian.hpp>
9#include <triqs/mesh/imfreq.hpp>
11#include "triqs/lattice/bz_integrators.hpp"
12#include "triqs/lattice/gloc.hpp"
15#include <triqs/gfs/functions/density.hpp>
17#include "triqs/lattice/superlattice.hpp"
21 using triqs::lattice::superlattice;
25 std::vector<tb_hamiltonian>
H;
41 std::vector<atomic_orbs> atomic_shells);
56 spin_kind_e spin_kind, std::vector<atomic_orbs> atomic_shells);
60 std::vector<atomic_orbs> atomic_shells);
68 nda::array<nda::matrix<dcomplex>, 2>
Hloc(std::vector<tb_hamiltonian>
const &H_sigma, std::vector<atomic_orbs>
const &atomic_shells);
104 template <
typename Mesh>
105 block2_gf<Mesh, matrix_valued>
gloc(
one_body_elements_tb const &obe,
double mu, block2_gf<Mesh, matrix_valued>
const &Sigma_dynamic,
106 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt) {
108 auto &mesh = Sigma_dynamic(0, 0).mesh();
112 if (n_sigma != Sigma_static.shape(1)) {
throw std::runtime_error(
"Mismatch between the spin channels in Sigma_Static and Sigma_Dynamic"); }
113 if (n_sigma != obe.
H.size()) {
throw std::runtime_error(
"Mismatch between the spin channels in Sigma and spin channels in Hamiltonian."); }
116 auto embedding_decomp =
get_struct(Sigma_dynamic).dims(
r_all, 0) | tl::to<std::vector>();
118 for (
auto sigma : range(n_sigma)) {
121 auto Sigma_full_space = gfs::gf(mesh, {obe.
H[sigma].n_orbitals(), obe.
H[sigma].n_orbitals()});
123 for (
auto [n, w] : enumerate(mesh)) {
124 Sigma_full_space.data()(n, R, R) = Sigma_dynamic(block, sigma).data()(n,
r_all,
r_all) + Sigma_static(block, sigma);
128 gloc_result(0, sigma) =
gloc(obe.
H[sigma], mu, Sigma_full_space, opt);
146 template <
typename Mesh>
147 block2_gf<Mesh, matrix_valued>
gloc(Mesh
const &mesh,
one_body_elements_tb const &obe,
double mu, triqs::lattice::bz_int_options
const &opt) {
149 for (
auto sigma : range(obe.
C_space.
n_sigma())) { result(0, sigma) =
gloc(mesh, obe.
H[sigma], mu, opt); }
167 template <
typename Mesh>
169 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt) {
175 auto Gloc =
gloc(obe, mu, Sigma_dynamic, Sigma_static, opt);
177 for (
auto sigma : range(n_sigma)) {
178 n += real(nda::trace(
density(Gloc(0, sigma))));
199 template <
typename Mesh>
201 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt,
202 std::string method =
"dichotomy",
double precision = 1.e-5,
bool verbosity =
true) {
203 std::function<double(
double)> f = [&obe, &Sigma_dynamic, &Sigma_static, &opt](
double x) {
204 return density(obe, x, Sigma_dynamic, Sigma_static, opt);
206 return std::get<0>(
triqs::root_finder(method, f, 0.0, target_density, precision, 0.5, 1000,
"Chemical Potential",
"Total Density", verbosity));
223 template <
typename Mesh>
225 triqs::lattice::bz_int_options
const &opt, std::string method =
"dichotomy",
double precision = 1.e-5,
226 bool verbosity =
true) {
229 auto Sigma_static = nda::array<nda::matrix<dcomplex>, 2>(1, obe.
C_space.
n_sigma());
230 for (
auto [i, j] : Sigma_static.indices()) { Sigma_static(i, j) = nda::zeros<dcomplex>(obe.
C_space.
dim(), obe.
C_space.
dim()); }
231 return find_chemical_potential(target_density, obe, Sigma_dynamic, Sigma_static, opt, method, precision, verbosity);
237 template block2_gf<mesh::imfreq, matrix_valued>
gloc(one_body_elements_tb
const &obe,
double mu,
238 block2_gf<mesh::imfreq, matrix_valued>
const &Sigma_dynamic,
239 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static,
240 triqs::lattice::bz_int_options
const &opt);
242 template block2_gf<mesh::imfreq, matrix_valued>
gloc(mesh::imfreq
const &mesh, one_body_elements_tb
const &obe,
double mu,
243 triqs::lattice::bz_int_options
const &opt);
245 template double density(one_body_elements_tb
const &obe,
double mu, block2_gf<mesh::imfreq, matrix_valued>
const &Sigma_dynamic,
246 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt);
249 block2_gf<mesh::imfreq, matrix_valued>
const &Sigma_dynamic,
250 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt,
251 std::string method,
double precision,
bool verbosity);
253 template double find_chemical_potential(
double const target_density, one_body_elements_tb
const &obe, mesh::imfreq
const &mesh,
254 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 Gš local Green's function on Mesh(MxM)
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.
block2_gf< Mesh, matrix_valued > make_block2_gf(Mesh const &mesh, gf_struct2_t const &gf_s)
gf_struct_t get_struct(block_gf< Mesh > const &g)
one_body_elements_tb fold(lattice::superlattice const &sl, one_body_elements_tb const &obe)
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.
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 Hloc = H(R=0) given n_sigma tight_binding Hamiltonians.
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 obe_tb from Wannier90 in the case of a single spin index.
std::pair< double, double > root_finder(std::string method, std::function< double(double)> f, double x_init, double y_value, double precision, double delta_x, long max_loops=1000, std::string x_name="", std::string y_name="", bool verbosity=false)
Root finder f(x) = 0.
static constexpr auto r_all
generator< std::pair< long, nda::range > > enumerated_sub_slices(auto sub_div)
std::vector< tb_hamiltonian > H