mirror of
https://github.com/triqs/dft_tools
synced 2024-11-07 06:33:48 +01:00
Modified sumk_dft to work also on real axis
extract_G_loc(), total_density(), and calc_mu() support now real frequency data, which is necessary for DMFT when a real frequency impurity solver is used.
This commit is contained in:
parent
7fe5f0222c
commit
c5a9c9dfbb
@ -561,7 +561,7 @@ class SumkDFT:
|
|||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells):
|
||||||
for bname,gf in SK_Sigma_imp[icrsh]: gf << self.rotloc(icrsh,gf,direction='toGlobal')
|
for bname,gf in SK_Sigma_imp[icrsh]: gf << self.rotloc(icrsh,gf,direction='toGlobal')
|
||||||
|
|
||||||
def extract_G_loc(self, mu=None, with_Sigma=True, with_dc=True):
|
def extract_G_loc(self, mu=None, iw_or_w='iw', with_Sigma=True, with_dc=True, broadening=None):
|
||||||
r"""
|
r"""
|
||||||
Extracts the local downfolded Green function by the Brillouin-zone integration of the lattice Green's function.
|
Extracts the local downfolded Green function by the Brillouin-zone integration of the lattice Green's function.
|
||||||
|
|
||||||
@ -573,6 +573,10 @@ class SumkDFT:
|
|||||||
If True then the local GF is calculated with the self-energy self.Sigma_imp.
|
If True then the local GF is calculated with the self-energy self.Sigma_imp.
|
||||||
with_dc : boolean, optional
|
with_dc : boolean, optional
|
||||||
If True then the double-counting correction is subtracted from the self-energy in calculating the GF.
|
If True then the double-counting correction is subtracted from the self-energy in calculating the GF.
|
||||||
|
broadening : float, optional
|
||||||
|
Imaginary shift for the axis along which the real-axis GF is calculated.
|
||||||
|
If not provided, broadening will be set to double of the distance between mesh points in 'mesh'.
|
||||||
|
Only relevant for real-frequency GF.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
@ -583,19 +587,31 @@ class SumkDFT:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if mu is None: mu = self.chemical_potential
|
if mu is None: mu = self.chemical_potential
|
||||||
|
|
||||||
|
if iw_or_w == "iw":
|
||||||
G_loc = [ self.Sigma_imp_iw[icrsh].copy() for icrsh in range(self.n_corr_shells) ] # this list will be returned
|
G_loc = [ self.Sigma_imp_iw[icrsh].copy() for icrsh in range(self.n_corr_shells) ] # this list will be returned
|
||||||
for icrsh in range(self.n_corr_shells): G_loc[icrsh].zero() # initialize to zero
|
|
||||||
beta = G_loc[0].mesh.beta
|
beta = G_loc[0].mesh.beta
|
||||||
|
G_loc_inequiv = [ BlockGf( name_block_generator = [ (block,GfImFreq(indices = inner, mesh = G_loc[0].mesh)) for block,inner in self.gf_struct_solver[ish].iteritems() ],
|
||||||
|
make_copies = False) for ish in range(self.n_inequiv_shells) ]
|
||||||
|
elif iw_or_w == "w":
|
||||||
|
G_loc = [ self.Sigma_imp_w[icrsh].copy() for icrsh in range(self.n_corr_shells) ] # this list will be returned
|
||||||
|
mesh = G_loc[0].mesh
|
||||||
|
G_loc_inequiv = [ BlockGf( name_block_generator = [ (block,GfReFreq(indices = inner, mesh = mesh)) for block,inner in self.gf_struct_solver[ish].iteritems() ],
|
||||||
|
make_copies = False) for ish in range(self.n_inequiv_shells) ]
|
||||||
|
|
||||||
|
for icrsh in range(self.n_corr_shells): G_loc[icrsh].zero() # initialize to zero
|
||||||
|
|
||||||
ikarray = numpy.array(range(self.n_k))
|
ikarray = numpy.array(range(self.n_k))
|
||||||
for ik in mpi.slice_array(ikarray):
|
for ik in mpi.slice_array(ikarray):
|
||||||
|
if iw_or_w == 'iw':
|
||||||
G_latt_iw = self.lattice_gf(ik=ik, mu=mu, iw_or_w="iw", with_Sigma=with_Sigma, with_dc=with_dc, beta=beta)
|
G_latt = self.lattice_gf(ik=ik, mu=mu, iw_or_w=iw_or_w, with_Sigma=with_Sigma, with_dc=with_dc, beta=beta)
|
||||||
G_latt_iw *= self.bz_weights[ik]
|
elif iw_or_w == 'w':
|
||||||
|
G_latt = self.lattice_gf(ik=ik, mu=mu, iw_or_w=iw_or_w, with_Sigma=with_Sigma, with_dc=with_dc, broadening=broadening, mesh=mesh)
|
||||||
|
G_latt *= self.bz_weights[ik]
|
||||||
|
|
||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells):
|
||||||
tmp = G_loc[icrsh].copy() # init temporary storage
|
tmp = G_loc[icrsh].copy() # init temporary storage
|
||||||
for bname,gf in tmp: tmp[bname] << self.downfold(ik,icrsh,bname,G_latt_iw[bname],gf)
|
for bname,gf in tmp: tmp[bname] << self.downfold(ik,icrsh,bname,G_latt[bname],gf)
|
||||||
G_loc[icrsh] += tmp
|
G_loc[icrsh] += tmp
|
||||||
|
|
||||||
# Collect data from mpi
|
# Collect data from mpi
|
||||||
@ -613,8 +629,6 @@ class SumkDFT:
|
|||||||
for bname,gf in G_loc[icrsh]: G_loc[icrsh][bname] << self.rotloc(icrsh,gf,direction='toLocal')
|
for bname,gf in G_loc[icrsh]: G_loc[icrsh][bname] << self.rotloc(icrsh,gf,direction='toLocal')
|
||||||
|
|
||||||
# transform to CTQMC blocks:
|
# transform to CTQMC blocks:
|
||||||
G_loc_inequiv = [ BlockGf( name_block_generator = [ (block,GfImFreq(indices = inner, mesh = G_loc[0].mesh)) for block,inner in self.gf_struct_solver[ish].iteritems() ],
|
|
||||||
make_copies = False) for ish in range(self.n_inequiv_shells) ]
|
|
||||||
for ish in range(self.n_inequiv_shells):
|
for ish in range(self.n_inequiv_shells):
|
||||||
for block,inner in self.gf_struct_solver[ish].iteritems():
|
for block,inner in self.gf_struct_solver[ish].iteritems():
|
||||||
for ind1 in inner:
|
for ind1 in inner:
|
||||||
@ -1072,14 +1086,14 @@ class SumkDFT:
|
|||||||
for bl in degsh: gf_to_symm[bl] << ss
|
for bl in degsh: gf_to_symm[bl] << ss
|
||||||
|
|
||||||
|
|
||||||
def total_density(self, mu=None, with_Sigma=True, with_dc=True):
|
def total_density(self, mu=None, iw_or_w="iw", with_Sigma=True, with_dc=True, broadening=None):
|
||||||
r"""
|
r"""
|
||||||
Calculates the total charge within the energy window for a given chemical potential.
|
Calculates the total charge within the energy window for a given chemical potential.
|
||||||
The chemical potential is either given by parameter `mu` or, if it is not specified,
|
The chemical potential is either given by parameter `mu` or, if it is not specified,
|
||||||
taken from `self.chemical_potential`.
|
taken from `self.chemical_potential`.
|
||||||
|
|
||||||
The total charge is calculated from the trace of the GF in the Bloch basis.
|
The total charge is calculated from the trace of the GF in the Bloch basis.
|
||||||
By deafult, a full interacting GF is used. To use the non-interacting GF, set
|
By default, a full interacting GF is used. To use the non-interacting GF, set
|
||||||
parameter `with_Sigma = False`.
|
parameter `with_Sigma = False`.
|
||||||
|
|
||||||
The number of bands within the energy windows generally depends on `k`. The trace is
|
The number of bands within the energy windows generally depends on `k`. The trace is
|
||||||
@ -1096,11 +1110,18 @@ class SumkDFT:
|
|||||||
----------
|
----------
|
||||||
mu : float, optional
|
mu : float, optional
|
||||||
Input chemical potential. If not specified, `self.chemical_potential` is used instead.
|
Input chemical potential. If not specified, `self.chemical_potential` is used instead.
|
||||||
|
iw_or_w : string, optional
|
||||||
|
- `iw_or_w` = 'iw' for a imaginary-frequency self-energy
|
||||||
|
- `iw_or_w` = 'w' for a real-frequency self-energy
|
||||||
with_Sigma : boolean, optional
|
with_Sigma : boolean, optional
|
||||||
If `True` the full interacing GF is evaluated, otherwise the self-energy is not
|
If `True` the full interacing GF is evaluated, otherwise the self-energy is not
|
||||||
included and the charge would correspond to a non-interacting system.
|
included and the charge would correspond to a non-interacting system.
|
||||||
with_dc : boolean, optional
|
with_dc : boolean, optional
|
||||||
Whether or not to subtract the double-counting term from the self-energy.
|
Whether or not to subtract the double-counting term from the self-energy.
|
||||||
|
broadening : float, optional
|
||||||
|
Imaginary shift for the axis along which the real-axis GF is calculated.
|
||||||
|
If not provided, broadening will be set to double of the distance between mesh points in 'mesh'.
|
||||||
|
Only relevant for real-frequency GF.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
@ -1112,8 +1133,8 @@ class SumkDFT:
|
|||||||
dens = 0.0
|
dens = 0.0
|
||||||
ikarray = numpy.array(range(self.n_k))
|
ikarray = numpy.array(range(self.n_k))
|
||||||
for ik in mpi.slice_array(ikarray):
|
for ik in mpi.slice_array(ikarray):
|
||||||
G_latt_iw = self.lattice_gf(ik=ik, mu=mu, iw_or_w="iw", with_Sigma=with_Sigma, with_dc=with_dc)
|
G_latt = self.lattice_gf(ik=ik, mu=mu, iw_or_w=iw_or_w, with_Sigma=with_Sigma, with_dc=with_dc, broadening=broadening)
|
||||||
dens += self.bz_weights[ik] * G_latt_iw.total_density()
|
dens += self.bz_weights[ik] * G_latt.total_density()
|
||||||
# collect data from mpi:
|
# collect data from mpi:
|
||||||
dens = mpi.all_reduce(mpi.world, dens, lambda x,y : x+y)
|
dens = mpi.all_reduce(mpi.world, dens, lambda x,y : x+y)
|
||||||
mpi.barrier()
|
mpi.barrier()
|
||||||
@ -1134,7 +1155,7 @@ class SumkDFT:
|
|||||||
self.chemical_potential = mu
|
self.chemical_potential = mu
|
||||||
|
|
||||||
|
|
||||||
def calc_mu(self, precision=0.01):
|
def calc_mu(self, precision=0.01, iw_or_w='iw',broadening=None):
|
||||||
r"""
|
r"""
|
||||||
Searches for the chemical potential that gives the DFT total charge.
|
Searches for the chemical potential that gives the DFT total charge.
|
||||||
A simple bisection method is used.
|
A simple bisection method is used.
|
||||||
@ -1143,6 +1164,13 @@ class SumkDFT:
|
|||||||
----------
|
----------
|
||||||
precision : float, optional
|
precision : float, optional
|
||||||
A desired precision of the resulting total charge.
|
A desired precision of the resulting total charge.
|
||||||
|
iw_or_w : string, optional
|
||||||
|
- `iw_or_w` = 'iw' for a imaginary-frequency self-energy
|
||||||
|
- `iw_or_w` = 'w' for a real-frequency self-energy
|
||||||
|
broadening : float, optional
|
||||||
|
Imaginary shift for the axis along which the real-axis GF is calculated.
|
||||||
|
If not provided, broadening will be set to double of the distance between mesh points in 'mesh'.
|
||||||
|
Only relevant for real-frequency GF.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
@ -1151,7 +1179,7 @@ class SumkDFT:
|
|||||||
within specified precision.
|
within specified precision.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
F = lambda mu : self.total_density(mu=mu)
|
F = lambda mu : self.total_density(mu=mu,iw_or_w=iw_or_w,broadening=broadening)
|
||||||
density = self.density_required - self.charge_below
|
density = self.density_required - self.charge_below
|
||||||
|
|
||||||
self.chemical_potential = dichotomy.dichotomy(function = F,
|
self.chemical_potential = dichotomy.dichotomy(function = F,
|
||||||
|
Loading…
Reference in New Issue
Block a user