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;
28 std::vector<tb_hamiltonian>
H;
49 std::vector<atomic_orbs> atomic_shells);
64 spin_kind_e spin_kind, std::vector<atomic_orbs> atomic_shells);
70 std::vector<atomic_orbs> atomic_shells);
80 nda::array<nda::matrix<dcomplex>, 2>
Hloc(std::vector<tb_hamiltonian>
const &H_sigma, std::vector<atomic_orbs>
const &atomic_shells);
122 template <
typename Mesh>
123 block2_gf<Mesh, matrix_valued>
gloc(
one_body_elements_tb const &obe,
double mu, block2_gf<Mesh, matrix_valued>
const &Sigma_dynamic,
124 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt) {
126 auto &mesh = Sigma_dynamic(0, 0).mesh();
130 if (n_sigma != Sigma_static.shape(1)) {
throw std::runtime_error(
"Mismatch between the spin channels in Sigma_Static and Sigma_Dynamic"); }
131 if (n_sigma != obe.
H.size()) {
throw std::runtime_error(
"Mismatch between the spin channels in Sigma and spin channels in Hamiltonian."); }
134 auto embedding_decomp =
get_struct(Sigma_dynamic).dims(
r_all, 0) | tl::to<std::vector>();
136 for (
auto sigma : range(n_sigma)) {
139 auto Sigma_full_space = gfs::gf(mesh, {obe.
H[sigma].n_orbitals(), obe.
H[sigma].n_orbitals()});
141 for (
auto [n, w] : enumerate(mesh)) {
142 Sigma_full_space.data()(n, R, R) = Sigma_dynamic(block, sigma).data()(n,
r_all,
r_all) + Sigma_static(block, sigma);
146 gloc_result(0, sigma) =
gloc(obe.
H[sigma], mu, Sigma_full_space, opt);
164 template <
typename Mesh>
165 block2_gf<Mesh, matrix_valued>
gloc(Mesh
const &mesh,
one_body_elements_tb const &obe,
double mu, triqs::lattice::bz_int_options
const &opt) {
167 for (
auto sigma : range(obe.
C_space.
n_sigma())) { result(0, sigma) =
gloc(mesh, obe.
H[sigma], mu, opt); }
187 template <
typename Mesh>
189 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt) {
195 auto Gloc =
gloc(obe, mu, Sigma_dynamic, Sigma_static, opt);
197 for (
auto sigma : range(n_sigma)) {
198 n += real(nda::trace(
density(Gloc(0, sigma))));
219 template <
typename Mesh>
221 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt,
222 std::string method =
"dichotomy",
double precision = 1.e-5,
bool verbosity =
true) {
223 std::function<double(
double)> f = [&obe, &Sigma_dynamic, &Sigma_static, &opt](
double x) {
224 return density(obe, x, Sigma_dynamic, Sigma_static, opt);
226 return std::get<0>(
triqs::root_finder(method, f, 0.0, target_density, precision, 0.5, 1000,
"Chemical Potential",
"Total Density", verbosity));
243 template <
typename Mesh>
245 triqs::lattice::bz_int_options
const &opt, std::string method =
"dichotomy",
double precision = 1.e-5,
246 bool verbosity =
true) {
249 auto Sigma_static = nda::array<nda::matrix<dcomplex>, 2>(1, obe.
C_space.
n_sigma());
250 for (
auto [i, j] : Sigma_static.indices()) { Sigma_static(i, j) = nda::zeros<dcomplex>(obe.
C_space.
dim(), obe.
C_space.
dim()); }
251 return find_chemical_potential(target_density, obe, Sigma_dynamic, Sigma_static, opt, method, precision, verbosity);
257 template block2_gf<mesh::imfreq, matrix_valued>
gloc(one_body_elements_tb
const &obe,
double mu,
258 block2_gf<mesh::imfreq, matrix_valued>
const &Sigma_dynamic,
259 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static,
260 triqs::lattice::bz_int_options
const &opt);
262 template block2_gf<mesh::imfreq, matrix_valued>
gloc(mesh::imfreq
const &mesh, one_body_elements_tb
const &obe,
double mu,
263 triqs::lattice::bz_int_options
const &opt);
265 template double density(one_body_elements_tb
const &obe,
double mu, block2_gf<mesh::imfreq, matrix_valued>
const &Sigma_dynamic,
266 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt);
269 block2_gf<mesh::imfreq, matrix_valued>
const &Sigma_dynamic,
270 nda::array<nda::matrix<dcomplex>, 2>
const &Sigma_static, triqs::lattice::bz_int_options
const &opt,
271 std::string method,
double precision,
bool verbosity);
273 template double find_chemical_potential(
double const target_density, one_body_elements_tb
const &obe, mesh::imfreq
const &mesh,
274 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.
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 given tight binding Hamiltonians.
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 .
static constexpr auto r_all
generator< std::pair< long, nda::range > > enumerated_sub_slices(auto sub_div)
A one-body elements using a tight-binding Hamiltonian.
std::vector< tb_hamiltonian > H
List of TB Hamiltonians.
local_space C_space
Local space.