mirror of
https://github.com/triqs/dft_tools
synced 2025-01-03 01:55:56 +01:00
More minor changes
This commit is contained in:
parent
5eaa27a946
commit
5ad2acfee6
@ -68,12 +68,12 @@ class SumkLDA:
|
|||||||
# convert spin_block_names to indices -- if spin polarized, differentiate up and down blocks
|
# convert spin_block_names to indices -- if spin polarized, differentiate up and down blocks
|
||||||
self.spin_names_to_ind = [{}, {}]
|
self.spin_names_to_ind = [{}, {}]
|
||||||
for iso in range(2): # SO = 0 or 1
|
for iso in range(2): # SO = 0 or 1
|
||||||
for ibl in range(self.n_spin_blocks[iso]):
|
for isp in range(self.n_spin_blocks[iso]):
|
||||||
self.spin_names_to_ind[iso][self.spin_block_names[iso][ibl]] = ibl * self.SP
|
self.spin_names_to_ind[iso][self.spin_block_names[iso][isp]] = isp * self.SP
|
||||||
|
|
||||||
# GF structure used for the local things in the k sums
|
# GF structure used for the local things in the k sums
|
||||||
# Most general form allowing for all hybridisation, i.e. largest blocks possible
|
# Most general form allowing for all hybridisation, i.e. largest blocks possible
|
||||||
self.gf_struct_sumk = [ [ (b, range( self.corr_shells[icrsh][3])) for b in self.spin_block_names[self.corr_shells[icrsh][4]] ]
|
self.gf_struct_sumk = [ [ (sp, range( self.corr_shells[icrsh][3])) for sp in self.spin_block_names[self.corr_shells[icrsh][4]] ]
|
||||||
for icrsh in range(self.n_corr_shells) ]
|
for icrsh in range(self.n_corr_shells) ]
|
||||||
|
|
||||||
#-----
|
#-----
|
||||||
@ -83,8 +83,8 @@ class SumkLDA:
|
|||||||
optional_things = optional_things)
|
optional_things = optional_things)
|
||||||
if (not self.subgroup_present) or (not self.value_read['gf_struct_solver']):
|
if (not self.subgroup_present) or (not self.value_read['gf_struct_solver']):
|
||||||
# No gf_struct was stored in HDF, so first set a standard one:
|
# No gf_struct was stored in HDF, so first set a standard one:
|
||||||
self.gf_struct_solver = [ dict([ (b, range(self.corr_shells[self.inequiv_to_corr[ish]][3]) )
|
self.gf_struct_solver = [ dict([ (sp, range(self.corr_shells[self.inequiv_to_corr[ish]][3]) )
|
||||||
for b in self.spin_block_names[self.corr_shells[self.inequiv_to_corr[ish]][4]] ])
|
for sp in self.spin_block_names[self.corr_shells[self.inequiv_to_corr[ish]][4]] ])
|
||||||
for ish in range(self.n_inequiv_shells)
|
for ish in range(self.n_inequiv_shells)
|
||||||
]
|
]
|
||||||
# Set standard (identity) maps from gf_struct_sumk <-> gf_struct_solver
|
# Set standard (identity) maps from gf_struct_sumk <-> gf_struct_solver
|
||||||
@ -247,7 +247,7 @@ class SumkLDA:
|
|||||||
and chemical potential mu."""
|
and chemical potential mu."""
|
||||||
|
|
||||||
ntoi = self.spin_names_to_ind[self.SO]
|
ntoi = self.spin_names_to_ind[self.SO]
|
||||||
bln = self.spin_block_names[self.SO]
|
spn = self.spin_block_names[self.SO]
|
||||||
|
|
||||||
if not hasattr(self,"Sigma_imp"): with_Sigma = False
|
if not hasattr(self,"Sigma_imp"): with_Sigma = False
|
||||||
|
|
||||||
@ -261,14 +261,14 @@ class SumkLDA:
|
|||||||
set_up_G_upfold = True
|
set_up_G_upfold = True
|
||||||
else: # yes if inconsistencies present in existing G_upfold
|
else: # yes if inconsistencies present in existing G_upfold
|
||||||
GFsize = [ gf.N1 for bname,gf in self.G_upfold]
|
GFsize = [ gf.N1 for bname,gf in self.G_upfold]
|
||||||
unchangedsize = all( [ self.n_orbitals[ik,ntoi[bln[ibl]]] == GFsize[ibl]
|
unchangedsize = all( [ self.n_orbitals[ik,ntoi[spn[isp]]] == GFsize[isp]
|
||||||
for ibl in range(self.n_spin_blocks[self.SO]) ] )
|
for isp in range(self.n_spin_blocks[self.SO]) ] )
|
||||||
if (not unchangedsize) or (self.G_upfold.mesh.beta != beta): set_up_G_upfold = True
|
if (not unchangedsize) or (self.G_upfold.mesh.beta != beta): set_up_G_upfold = True
|
||||||
|
|
||||||
# Set up G_upfold
|
# Set up G_upfold
|
||||||
if set_up_G_upfold:
|
if set_up_G_upfold:
|
||||||
block_structure = [ range(self.n_orbitals[ik,ntoi[b]]) for b in bln ]
|
block_structure = [ range(self.n_orbitals[ik,ntoi[sp]]) for sp in spn ]
|
||||||
gf_struct = [ (bln[ibl], block_structure[ibl]) for ibl in range(self.n_spin_blocks[self.SO]) ]
|
gf_struct = [ (spn[isp], block_structure[isp]) for isp in range(self.n_spin_blocks[self.SO]) ]
|
||||||
block_ind_list = [block for block,inner in gf_struct]
|
block_ind_list = [block for block,inner in gf_struct]
|
||||||
if with_Sigma:
|
if with_Sigma:
|
||||||
glist = lambda : [ GfImFreq(indices = inner, mesh = self.Sigma_imp[0].mesh) for block,inner in gf_struct]
|
glist = lambda : [ GfImFreq(indices = inner, mesh = self.Sigma_imp[0].mesh) for block,inner in gf_struct]
|
||||||
@ -278,12 +278,12 @@ class SumkLDA:
|
|||||||
self.G_upfold.zero()
|
self.G_upfold.zero()
|
||||||
|
|
||||||
self.G_upfold << iOmega_n
|
self.G_upfold << iOmega_n
|
||||||
idmat = [numpy.identity(self.n_orbitals[ik,ntoi[bl]],numpy.complex_) for bl in bln]
|
idmat = [numpy.identity(self.n_orbitals[ik,ntoi[sp]],numpy.complex_) for sp in spn]
|
||||||
M = copy.deepcopy(idmat)
|
M = copy.deepcopy(idmat)
|
||||||
for ibl in range(self.n_spin_blocks[self.SO]):
|
for isp in range(self.n_spin_blocks[self.SO]):
|
||||||
ind = ntoi[bln[ibl]]
|
ind = ntoi[spn[isp]]
|
||||||
n_orb = self.n_orbitals[ik,ind]
|
n_orb = self.n_orbitals[ik,ind]
|
||||||
M[ibl] = self.hopping[ik,ind,0:n_orb,0:n_orb] - (idmat[ibl]*mu) - (idmat[ibl] * self.h_field * (1-2*ibl))
|
M[isp] = self.hopping[ik,ind,0:n_orb,0:n_orb] - (idmat[isp]*mu) - (idmat[isp] * self.h_field * (1-2*isp))
|
||||||
self.G_upfold -= M
|
self.G_upfold -= M
|
||||||
|
|
||||||
if with_Sigma:
|
if with_Sigma:
|
||||||
@ -295,81 +295,94 @@ class SumkLDA:
|
|||||||
return self.G_upfold
|
return self.G_upfold
|
||||||
|
|
||||||
|
|
||||||
def density_matrix(self, method = 'using_gf', beta=40.0):
|
def put_Sigma(self, Sigma_imp):
|
||||||
"""Calculate density matrices in one of two ways:
|
"""Puts the impurity self energies for inequivalent atoms into the class, respects the multiplicity of the atoms."""
|
||||||
if 'using_gf': First get upfolded gf (g_loc is not set up), then density matrix.
|
|
||||||
It is useful for Hubbard I, and very quick.
|
assert isinstance(Sigma_imp,list), "Sigma_imp has to be a list of Sigmas for the correlated shells, even if it is of length 1!"
|
||||||
No assumption on the hopping structure is made (ie diagonal or not).
|
assert len(Sigma_imp) == self.n_inequiv_shells, "give exactly one Sigma for each inequivalent corr. shell!"
|
||||||
if 'using_point_integration': Only works for diagonal hopping matrix (true in wien2k).
|
|
||||||
"""
|
# init self.Sigma_imp:
|
||||||
dens_mat = [ {} for icrsh in range(self.n_corr_shells)]
|
if all(type(gf) == GfImFreq for bname,gf in Sigma_imp[0]):
|
||||||
|
# Imaginary frequency Sigma:
|
||||||
|
self.Sigma_imp = [ BlockGf( name_block_generator = [ (block,GfImFreq(indices = inner, mesh = Sigma_imp[0].mesh)) for block,inner in self.gf_struct_sumk[icrsh] ],
|
||||||
|
make_copies = False) for icrsh in range(self.n_corr_shells) ]
|
||||||
|
elif all(type(gf) == GfReFreq for bname,gf in Sigma_imp[0]):
|
||||||
|
# Real frequency Sigma:
|
||||||
|
self.Sigma_imp = [ BlockGf( name_block_generator = [ (block,GfReFreq(indices = inner, mesh = Sigma_imp[0].mesh)) for block,inner in self.gf_struct_sumk[icrsh] ],
|
||||||
|
make_copies = False) for icrsh in range(self.n_corr_shells) ]
|
||||||
|
else:
|
||||||
|
raise ValueError, "This type of Sigma is not handled."
|
||||||
|
|
||||||
|
# transform the CTQMC blocks to the full matrix:
|
||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells):
|
||||||
for bl in self.spin_block_names[self.corr_shells[icrsh][4]]:
|
ish = self.corr_to_inequiv[icrsh] # ish is the index of the inequivalent shell corresponding to icrsh
|
||||||
dens_mat[icrsh][bl] = numpy.zeros([self.corr_shells[icrsh][3],self.corr_shells[icrsh][3]], numpy.complex_)
|
for block,inner in self.gf_struct_solver[ish].iteritems():
|
||||||
|
for ind1 in inner:
|
||||||
|
for ind2 in inner:
|
||||||
|
block_sumk,ind1_sumk = self.solver_to_sumk[ish][(block,ind1)]
|
||||||
|
block_sumk,ind2_sumk = self.solver_to_sumk[ish][(block,ind2)]
|
||||||
|
self.Sigma_imp[icrsh][block_sumk][ind1_sumk,ind2_sumk] << Sigma_imp[ish][block][ind1,ind2]
|
||||||
|
|
||||||
|
# rotation from local to global coordinate system:
|
||||||
|
if self.use_rotations:
|
||||||
|
for icrsh in range(self.n_corr_shells):
|
||||||
|
for bname,gf in self.Sigma_imp[icrsh]: self.Sigma_imp[icrsh][bname] << self.rotloc(icrsh, gf, direction = 'toGlobal')
|
||||||
|
|
||||||
|
|
||||||
|
def extract_G_loc(self, mu = None, with_Sigma = True):
|
||||||
|
"""
|
||||||
|
Extracts the local downfolded Green function at the chemical potential of the class.
|
||||||
|
At the end, the local G is rotated from the global coordinate system to the local system.
|
||||||
|
if with_Sigma = False: Sigma is not included => non-interacting local GF
|
||||||
|
"""
|
||||||
|
|
||||||
|
if mu is None: mu = self.chemical_potential
|
||||||
|
Gloc = [ self.Sigma_imp[icrsh].copy() for icrsh in range(self.n_corr_shells) ] # this list will be returned
|
||||||
|
for icrsh in range(self.n_corr_shells): Gloc[icrsh].zero() # initialize to zero
|
||||||
|
beta = Gloc[0].mesh.beta
|
||||||
|
|
||||||
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 method == "using_gf":
|
S = self.lattice_gf_matsubara(ik = ik, mu = mu, with_Sigma = with_Sigma, beta = beta)
|
||||||
|
S *= self.bz_weights[ik]
|
||||||
G_upfold = self.lattice_gf_matsubara(ik=ik, beta=beta, mu=self.chemical_potential)
|
|
||||||
G_upfold *= self.bz_weights[ik]
|
|
||||||
dm = G_upfold.density()
|
|
||||||
MMat = [dm[bl] for bl in self.spin_block_names[self.SO]]
|
|
||||||
|
|
||||||
elif method == "using_point_integration":
|
|
||||||
|
|
||||||
ntoi = self.spin_names_to_ind[self.SO]
|
|
||||||
bln = self.spin_block_names[self.SO]
|
|
||||||
unchangedsize = all( [self.n_orbitals[ik,ntoi[bl]] == self.n_orbitals[0,ntoi[bl]] for bl in bln] )
|
|
||||||
if unchangedsize:
|
|
||||||
dim = self.n_orbitals[0,ntoi[bl]]
|
|
||||||
else:
|
|
||||||
dim = self.n_orbitals[ik,ntoi[bl]]
|
|
||||||
MMat = [numpy.zeros( [dim,dim], numpy.complex_) for bl in bln]
|
|
||||||
|
|
||||||
for ibl, bl in enumerate(bln):
|
|
||||||
ind = ntoi[bl]
|
|
||||||
for inu in range(self.n_orbitals[ik,ind]):
|
|
||||||
if (self.hopping[ik,ind,inu,inu] - self.h_field*(1-2*ibl)) < 0.0: # only works for diagonal hopping matrix (true in wien2k)
|
|
||||||
MMat[ibl][inu,inu] = 1.0
|
|
||||||
else:
|
|
||||||
MMat[ibl][inu,inu] = 0.0
|
|
||||||
|
|
||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells):
|
||||||
for ibl, bn in enumerate(self.spin_block_names[self.corr_shells[icrsh][4]]):
|
tmp = Gloc[icrsh].copy() # init temporary storage
|
||||||
isp = self.spin_names_to_ind[self.corr_shells[icrsh][4]][bn]
|
for bname,gf in tmp: tmp[bname] << self.downfold(ik,icrsh,bname,S[bname],gf)
|
||||||
dim = self.corr_shells[icrsh][3]
|
Gloc[icrsh] += tmp
|
||||||
n_orb = self.n_orbitals[ik,isp]
|
|
||||||
projmat = self.proj_mat[ik,isp,icrsh,0:dim,0:n_orb]
|
|
||||||
if method == "using_gf":
|
|
||||||
dens_mat[icrsh][bn] += numpy.dot( numpy.dot(projmat,MMat[ibl]),
|
|
||||||
projmat.transpose().conjugate() )
|
|
||||||
elif method == "using_point_integration":
|
|
||||||
dens_mat[icrsh][bn] += self.bz_weights[ik] * numpy.dot( numpy.dot(projmat,MMat[ibl]) ,
|
|
||||||
projmat.transpose().conjugate() )
|
|
||||||
|
|
||||||
# get data from nodes:
|
# collect data from mpi
|
||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells): Gloc[icrsh] << mpi.all_reduce(mpi.world, Gloc[icrsh], lambda x,y : x+y)
|
||||||
for bname in dens_mat[icrsh]:
|
|
||||||
dens_mat[icrsh][bname] = mpi.all_reduce(mpi.world, dens_mat[icrsh][bname], lambda x,y : x+y)
|
|
||||||
mpi.barrier()
|
mpi.barrier()
|
||||||
|
|
||||||
if self.symm_op != 0: dens_mat = self.symmcorr.symmetrize(dens_mat)
|
# Gloc[:] is now the sum over k projected to the local orbitals.
|
||||||
|
# here comes the symmetrisation, if needed:
|
||||||
|
if self.symm_op != 0: Gloc = self.symmcorr.symmetrize(Gloc)
|
||||||
|
|
||||||
# Rotate to local coordinate system:
|
# Gloc is rotated to the local coordinate system:
|
||||||
if self.use_rotations:
|
if self.use_rotations:
|
||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells):
|
||||||
for bn in dens_mat[icrsh]:
|
for bname,gf in Gloc[icrsh]: Gloc[icrsh][bname] << self.rotloc(icrsh,gf,direction = 'toLocal')
|
||||||
if self.rot_mat_time_inv[icrsh] == 1: dens_mat[icrsh][bn] = dens_mat[icrsh][bn].conjugate()
|
|
||||||
dens_mat[icrsh][bn] = numpy.dot( numpy.dot(self.rot_mat[icrsh].conjugate().transpose(),dens_mat[icrsh][bn]),
|
|
||||||
self.rot_mat[icrsh] )
|
|
||||||
|
|
||||||
return dens_mat
|
# transform to CTQMC blocks:
|
||||||
|
Glocret = [ BlockGf( name_block_generator = [ (block,GfImFreq(indices = inner, mesh = Gloc[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 block,inner in self.gf_struct_solver[ish].iteritems():
|
||||||
|
for ind1 in inner:
|
||||||
|
for ind2 in inner:
|
||||||
|
block_sumk,ind1_sumk = self.solver_to_sumk[ish][(block,ind1)]
|
||||||
|
block_sumk,ind2_sumk = self.solver_to_sumk[ish][(block,ind2)]
|
||||||
|
Glocret[ish][block][ind1,ind2] << Gloc[self.inequiv_to_corr[ish]][block_sumk][ind1_sumk,ind2_sumk]
|
||||||
|
|
||||||
|
# return only the inequivalent shells:
|
||||||
|
return Glocret
|
||||||
|
|
||||||
|
|
||||||
def analyse_block_structure(self, threshold = 0.00001, include_shells = None, dm = None):
|
def analyse_block_structure(self, threshold = 0.00001, include_shells = None, dm = None):
|
||||||
""" Determines the Green function block structure from simple point integration."""
|
""" Determines the Green's function block structure from simple point integration."""
|
||||||
|
|
||||||
self.gf_struct_solver = [ {} for ish in range(self.n_inequiv_shells) ]
|
self.gf_struct_solver = [ {} for ish in range(self.n_inequiv_shells) ]
|
||||||
self.sumk_to_solver = [ {} for ish in range(self.n_inequiv_shells) ]
|
self.sumk_to_solver = [ {} for ish in range(self.n_inequiv_shells) ]
|
||||||
@ -382,10 +395,9 @@ class SumkLDA:
|
|||||||
if include_shells is None: include_shells = range(self.n_inequiv_shells)
|
if include_shells is None: include_shells = range(self.n_inequiv_shells)
|
||||||
for ish in include_shells:
|
for ish in include_shells:
|
||||||
|
|
||||||
block_ind_list = [ block for block,inner in self.gf_struct_sumk[self.inequiv_to_corr[ish]] ]
|
|
||||||
for block in block_ind_list:
|
for sp in self.spin_block_names[self.corr_shells[self.inequiv_to_corr[ish]][4]]:
|
||||||
dm = dens_mat[ish][block]
|
dmbool = (abs(dens_mat[ish][sp]) > threshold) # gives an index list of entries larger that threshold
|
||||||
dmbool = (abs(dm) > threshold) # gives an index list of entries larger that threshold
|
|
||||||
|
|
||||||
# Determine off-diagonal entries in upper triangular part of density matrix
|
# Determine off-diagonal entries in upper triangular part of density matrix
|
||||||
offdiag = []
|
offdiag = []
|
||||||
@ -393,9 +405,9 @@ class SumkLDA:
|
|||||||
for j in range(i+1,len(dmbool)):
|
for j in range(i+1,len(dmbool)):
|
||||||
if dmbool[i,j]: offdiag.append([i,j])
|
if dmbool[i,j]: offdiag.append([i,j])
|
||||||
|
|
||||||
|
# Determine the number of non-hybridising blocks in the gf
|
||||||
num_blocs = len(dmbool)
|
num_blocs = len(dmbool)
|
||||||
blocs = [ [i] for i in range(num_blocs) ]
|
blocs = [ [i] for i in range(num_blocs) ]
|
||||||
|
|
||||||
for i in range(len(offdiag)):
|
for i in range(len(offdiag)):
|
||||||
for j in range(len(blocs[offdiag[i][1]])): blocs[offdiag[i][0]].append(blocs[offdiag[i][1]][j])
|
for j in range(len(blocs[offdiag[i][1]])): blocs[offdiag[i][0]].append(blocs[offdiag[i][1]][j])
|
||||||
del blocs[offdiag[i][1]]
|
del blocs[offdiag[i][1]]
|
||||||
@ -407,17 +419,18 @@ class SumkLDA:
|
|||||||
offdiag[j].sort()
|
offdiag[j].sort()
|
||||||
num_blocs -= 1
|
num_blocs -= 1
|
||||||
|
|
||||||
|
# Set the gf_struct for the solver accordingly
|
||||||
for i in range(num_blocs):
|
for i in range(num_blocs):
|
||||||
blocs[i].sort()
|
blocs[i].sort()
|
||||||
self.gf_struct_solver[ish].update( [('%s_%s'%(block,i),range(len(blocs[i])))] )
|
self.gf_struct_solver[ish].update( [('%s_%s'%(sp,i),range(len(blocs[i])))] )
|
||||||
|
|
||||||
# Construct sumk_to_solver taking (sumk_block, sumk_index) --> (solver_block, solver_inner)
|
# Construct sumk_to_solver taking (sumk_block, sumk_index) --> (solver_block, solver_inner)
|
||||||
# and solver_to_sumk taking (solver_block, solver_inner) --> (sumk_block, sumk_index)
|
# and solver_to_sumk taking (solver_block, solver_inner) --> (sumk_block, sumk_index)
|
||||||
for i in range(num_blocs):
|
for i in range(num_blocs):
|
||||||
for j in range(len(blocs[i])):
|
for j in range(len(blocs[i])):
|
||||||
block_sumk = block
|
block_sumk = sp
|
||||||
inner_sumk = blocs[i][j]
|
inner_sumk = blocs[i][j]
|
||||||
block_solv = '%s_%s'%(block,i)
|
block_solv = '%s_%s'%(sp,i)
|
||||||
inner_solv = j
|
inner_solv = j
|
||||||
self.sumk_to_solver[ish][(block_sumk,inner_sumk)] = (block_solv,inner_solv)
|
self.sumk_to_solver[ish][(block_sumk,inner_sumk)] = (block_solv,inner_solv)
|
||||||
self.solver_to_sumk[ish][(block_solv,inner_solv)] = (block_sumk,inner_sumk)
|
self.solver_to_sumk[ish][(block_solv,inner_solv)] = (block_sumk,inner_sumk)
|
||||||
@ -457,16 +470,78 @@ class SumkLDA:
|
|||||||
return dens_mat
|
return dens_mat
|
||||||
|
|
||||||
|
|
||||||
def symm_deg_gf(self,gf_to_symm,orb):
|
def density_matrix(self, method = 'using_gf', beta = 40.0):
|
||||||
"""Symmetrises a GF for the given degenerate shells self.deg_shells"""
|
"""Calculate density matrices in one of two ways:
|
||||||
|
if 'using_gf': First get upfolded gf (g_loc is not set up), then density matrix.
|
||||||
|
It is useful for Hubbard I, and very quick.
|
||||||
|
No assumption on the hopping structure is made (ie diagonal or not).
|
||||||
|
if 'using_point_integration': Only works for diagonal hopping matrix (true in wien2k).
|
||||||
|
"""
|
||||||
|
dens_mat = [ {} for icrsh in range(self.n_corr_shells)]
|
||||||
|
for icrsh in range(self.n_corr_shells):
|
||||||
|
for sp in self.spin_block_names[self.corr_shells[icrsh][4]]:
|
||||||
|
dens_mat[icrsh][sp] = numpy.zeros([self.corr_shells[icrsh][3],self.corr_shells[icrsh][3]], numpy.complex_)
|
||||||
|
|
||||||
|
ikarray = numpy.array(range(self.n_k))
|
||||||
|
for ik in mpi.slice_array(ikarray):
|
||||||
|
|
||||||
|
if method == "using_gf":
|
||||||
|
|
||||||
|
G_upfold = self.lattice_gf_matsubara(ik = ik, beta = beta, mu = self.chemical_potential)
|
||||||
|
G_upfold *= self.bz_weights[ik]
|
||||||
|
dm = G_upfold.density()
|
||||||
|
MMat = [dm[sp] for sp in self.spin_block_names[self.SO]]
|
||||||
|
|
||||||
|
elif method == "using_point_integration":
|
||||||
|
|
||||||
|
ntoi = self.spin_names_to_ind[self.SO]
|
||||||
|
spn = self.spin_block_names[self.SO]
|
||||||
|
unchangedsize = all( [self.n_orbitals[ik,ntoi[sp]] == self.n_orbitals[0,ntoi[sp]] for sp in spn] )
|
||||||
|
if unchangedsize:
|
||||||
|
dim = self.n_orbitals[0,ntoi[sp]]
|
||||||
|
else:
|
||||||
|
dim = self.n_orbitals[ik,ntoi[sp]]
|
||||||
|
MMat = [numpy.zeros( [dim,dim], numpy.complex_) for sp in spn]
|
||||||
|
|
||||||
|
for isp, sp in enumerate(spn):
|
||||||
|
ind = ntoi[sp]
|
||||||
|
for inu in range(self.n_orbitals[ik,ind]):
|
||||||
|
if (self.hopping[ik,ind,inu,inu] - self.h_field*(1-2*isp)) < 0.0: # only works for diagonal hopping matrix (true in wien2k)
|
||||||
|
MMat[isp][inu,inu] = 1.0
|
||||||
|
else:
|
||||||
|
MMat[isp][inu,inu] = 0.0
|
||||||
|
|
||||||
|
for icrsh in range(self.n_corr_shells):
|
||||||
|
for isp, sp in enumerate(self.spin_block_names[self.corr_shells[icrsh][4]]):
|
||||||
|
isp = self.spin_names_to_ind[self.corr_shells[icrsh][4]][sp]
|
||||||
|
dim = self.corr_shells[icrsh][3]
|
||||||
|
n_orb = self.n_orbitals[ik,isp]
|
||||||
|
projmat = self.proj_mat[ik,isp,icrsh,0:dim,0:n_orb]
|
||||||
|
if method == "using_gf":
|
||||||
|
dens_mat[icrsh][sp] += numpy.dot( numpy.dot(projmat,MMat[isp]),
|
||||||
|
projmat.transpose().conjugate() )
|
||||||
|
elif method == "using_point_integration":
|
||||||
|
dens_mat[icrsh][sp] += self.bz_weights[ik] * numpy.dot( numpy.dot(projmat,MMat[isp]) ,
|
||||||
|
projmat.transpose().conjugate() )
|
||||||
|
|
||||||
|
# get data from nodes:
|
||||||
|
for icrsh in range(self.n_corr_shells):
|
||||||
|
for bname in dens_mat[icrsh]:
|
||||||
|
dens_mat[icrsh][bname] = mpi.all_reduce(mpi.world, dens_mat[icrsh][bname], lambda x,y : x+y)
|
||||||
|
mpi.barrier()
|
||||||
|
|
||||||
|
if self.symm_op != 0: dens_mat = self.symmcorr.symmetrize(dens_mat)
|
||||||
|
|
||||||
|
# Rotate to local coordinate system:
|
||||||
|
if self.use_rotations:
|
||||||
|
for icrsh in range(self.n_corr_shells):
|
||||||
|
for bl in dens_mat[icrsh]:
|
||||||
|
if self.rot_mat_time_inv[icrsh] == 1: dens_mat[icrsh][bl] = dens_mat[icrsh][bl].conjugate()
|
||||||
|
dens_mat[icrsh][bl] = numpy.dot( numpy.dot(self.rot_mat[icrsh].conjugate().transpose(),dens_mat[icrsh][bl]),
|
||||||
|
self.rot_mat[icrsh] )
|
||||||
|
|
||||||
|
return dens_mat
|
||||||
|
|
||||||
for degsh in self.deg_shells[orb]:
|
|
||||||
#loop over degenerate shells:
|
|
||||||
ss = gf_to_symm[degsh[0]].copy()
|
|
||||||
ss.zero()
|
|
||||||
Ndeg = len(degsh)
|
|
||||||
for bl in degsh: ss += gf_to_symm[bl] / (1.0*Ndeg)
|
|
||||||
for bl in degsh: gf_to_symm[bl] << ss
|
|
||||||
|
|
||||||
# For simple dft input, get crystal field splittings.
|
# For simple dft input, get crystal field splittings.
|
||||||
def eff_atomic_levels(self):
|
def eff_atomic_levels(self):
|
||||||
@ -475,8 +550,8 @@ class SumkLDA:
|
|||||||
# define matrices for inequivalent shells:
|
# define matrices for inequivalent shells:
|
||||||
eff_atlevels = [ {} for ish in range(self.n_inequiv_shells) ]
|
eff_atlevels = [ {} 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 bn in self.spin_block_names[self.corr_shells[self.inequiv_to_corr[ish]][4]]:
|
for sp in self.spin_block_names[self.corr_shells[self.inequiv_to_corr[ish]][4]]:
|
||||||
eff_atlevels[ish][bn] = numpy.identity(self.corr_shells[self.inequiv_to_corr[ish]][3], numpy.complex_)
|
eff_atlevels[ish][sp] = numpy.identity(self.corr_shells[self.inequiv_to_corr[ish]][3], numpy.complex_)
|
||||||
|
|
||||||
# Chemical Potential:
|
# Chemical Potential:
|
||||||
for ish in range(self.n_inequiv_shells):
|
for ish in range(self.n_inequiv_shells):
|
||||||
@ -492,20 +567,20 @@ class SumkLDA:
|
|||||||
# calculate the sum over k. Does not depend on mu, so do it only once:
|
# calculate the sum over k. Does not depend on mu, so do it only once:
|
||||||
self.Hsumk = [ {} for icrsh in range(self.n_corr_shells) ]
|
self.Hsumk = [ {} for icrsh in range(self.n_corr_shells) ]
|
||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells):
|
||||||
for bn in self.spin_block_names[self.corr_shells[icrsh][4]]:
|
for sp in self.spin_block_names[self.corr_shells[icrsh][4]]:
|
||||||
dim = self.corr_shells[icrsh][3] #*(1+self.corr_shells[icrsh][4])
|
dim = self.corr_shells[icrsh][3] #*(1+self.corr_shells[icrsh][4])
|
||||||
self.Hsumk[icrsh][bn] = numpy.zeros([dim,dim],numpy.complex_)
|
self.Hsumk[icrsh][sp] = numpy.zeros([dim,dim],numpy.complex_)
|
||||||
|
|
||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells):
|
||||||
dim = self.corr_shells[icrsh][3]
|
dim = self.corr_shells[icrsh][3]
|
||||||
for ibl, bn in enumerate(self.spin_block_names[self.corr_shells[icrsh][4]]):
|
for isp, sp in enumerate(self.spin_block_names[self.corr_shells[icrsh][4]]):
|
||||||
isp = self.spin_names_to_ind[self.corr_shells[icrsh][4]][bn]
|
isp = self.spin_names_to_ind[self.corr_shells[icrsh][4]][sp]
|
||||||
for ik in range(self.n_k):
|
for ik in range(self.n_k):
|
||||||
n_orb = self.n_orbitals[ik,isp]
|
n_orb = self.n_orbitals[ik,isp]
|
||||||
MMat = numpy.identity(n_orb, numpy.complex_)
|
MMat = numpy.identity(n_orb, numpy.complex_)
|
||||||
MMat = self.hopping[ik,isp,0:n_orb,0:n_orb] - (1-2*ibl) * self.h_field * MMat
|
MMat = self.hopping[ik,isp,0:n_orb,0:n_orb] - (1-2*isp) * self.h_field * MMat
|
||||||
projmat = self.proj_mat[ik,isp,icrsh,0:dim,0:n_orb]
|
projmat = self.proj_mat[ik,isp,icrsh,0:dim,0:n_orb]
|
||||||
self.Hsumk[icrsh][bn] += self.bz_weights[ik] * numpy.dot( numpy.dot(projmat,MMat),
|
self.Hsumk[icrsh][sp] += self.bz_weights[ik] * numpy.dot( numpy.dot(projmat,MMat),
|
||||||
projmat.conjugate().transpose() )
|
projmat.conjugate().transpose() )
|
||||||
|
|
||||||
# symmetrisation:
|
# symmetrisation:
|
||||||
@ -514,34 +589,32 @@ class SumkLDA:
|
|||||||
# Rotate to local coordinate system:
|
# Rotate to local coordinate system:
|
||||||
if self.use_rotations:
|
if self.use_rotations:
|
||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells):
|
||||||
for bn in self.Hsumk[icrsh]:
|
for bl in self.Hsumk[icrsh]:
|
||||||
|
|
||||||
if self.rot_mat_time_inv[icrsh] == 1: self.Hsumk[icrsh][bn] = self.Hsumk[icrsh][bn].conjugate()
|
if self.rot_mat_time_inv[icrsh] == 1: self.Hsumk[icrsh][bl] = self.Hsumk[icrsh][bl].conjugate()
|
||||||
self.Hsumk[icrsh][bn] = numpy.dot( numpy.dot(self.rot_mat[icrsh].conjugate().transpose(),self.Hsumk[icrsh][bn]) ,
|
self.Hsumk[icrsh][bl] = numpy.dot( numpy.dot(self.rot_mat[icrsh].conjugate().transpose(),self.Hsumk[icrsh][bl]) ,
|
||||||
self.rot_mat[icrsh] )
|
self.rot_mat[icrsh] )
|
||||||
|
|
||||||
# add to matrix:
|
# add to matrix:
|
||||||
for ish in range(self.n_inequiv_shells):
|
for ish in range(self.n_inequiv_shells):
|
||||||
for bn in eff_atlevels[ish]:
|
for bl in eff_atlevels[ish]:
|
||||||
eff_atlevels[ish][bn] += self.Hsumk[self.inequiv_to_corr[ish]][bn]
|
eff_atlevels[ish][bl] += self.Hsumk[self.inequiv_to_corr[ish]][bl]
|
||||||
|
|
||||||
|
|
||||||
return eff_atlevels
|
return eff_atlevels
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __init_dc(self):
|
def __init_dc(self):
|
||||||
|
|
||||||
# construct the density matrix dm_imp and double counting arrays
|
# construct the density matrix dm_imp and double counting arrays
|
||||||
self.dc_imp = [ {} for icrsh in range(self.n_corr_shells)]
|
self.dc_imp = [ {} for icrsh in range(self.n_corr_shells)]
|
||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells):
|
||||||
dim = self.corr_shells[icrsh][3]
|
dim = self.corr_shells[icrsh][3]
|
||||||
for j in range(len(self.gf_struct_sumk[icrsh])):
|
spn = self.spin_block_names[self.corr_shells[icrsh][4]]
|
||||||
self.dc_imp[icrsh]['%s'%self.gf_struct_sumk[icrsh][j][0]] = numpy.zeros([dim,dim],numpy.float_)
|
for sp in spn: self.dc_imp[icrsh][sp] = numpy.zeros([dim,dim],numpy.float_)
|
||||||
self.dc_energ = [0.0 for icrsh in range(self.n_corr_shells)]
|
self.dc_energ = [0.0 for icrsh in range(self.n_corr_shells)]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def set_dc(self,dens_mat,U_interact,J_hund,orb=0,use_dc_formula=0,use_val=None):
|
def set_dc(self,dens_mat,U_interact,J_hund,orb=0,use_dc_formula=0,use_val=None):
|
||||||
"""Sets the double counting term for inequiv orbital orb:
|
"""Sets the double counting term for inequiv orbital orb:
|
||||||
use_dc_formula = 0: LDA+U FLL double counting,
|
use_dc_formula = 0: LDA+U FLL double counting,
|
||||||
@ -549,7 +622,6 @@ class SumkLDA:
|
|||||||
use_dc_formula = 2: AMF.
|
use_dc_formula = 2: AMF.
|
||||||
Be sure that you are using the correct interaction Hamiltonian!"""
|
Be sure that you are using the correct interaction Hamiltonian!"""
|
||||||
|
|
||||||
|
|
||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells):
|
||||||
|
|
||||||
iorb = self.corr_to_inequiv[icrsh] # iorb is the index of the inequivalent shell corresponding to icrsh
|
iorb = self.corr_to_inequiv[icrsh] # iorb is the index of the inequivalent shell corresponding to icrsh
|
||||||
@ -559,110 +631,70 @@ class SumkLDA:
|
|||||||
Ncr = {}
|
Ncr = {}
|
||||||
dim = self.corr_shells[icrsh][3] #*(1+self.corr_shells[icrsh][4])
|
dim = self.corr_shells[icrsh][3] #*(1+self.corr_shells[icrsh][4])
|
||||||
|
|
||||||
for j in range(len(self.gf_struct_sumk[icrsh])):
|
spn = self.spin_block_names[self.corr_shells[icrsh][4]]
|
||||||
self.dc_imp[icrsh]['%s'%self.gf_struct_sumk[icrsh][j][0]] = numpy.identity(dim,numpy.float_)
|
for sp in spn:
|
||||||
blname = self.gf_struct_sumk[icrsh][j][0]
|
self.dc_imp[icrsh][sp] = numpy.identity(dim,numpy.float_)
|
||||||
Ncr[blname] = 0.0
|
Ncr[sp] = 0.0
|
||||||
|
|
||||||
for block,inner in self.gf_struct_solver[iorb].iteritems():
|
for block,inner in self.gf_struct_solver[iorb].iteritems():
|
||||||
bl = self.solver_to_sumk_block[iorb][block]
|
bl = self.solver_to_sumk_block[iorb][block]
|
||||||
Ncr[bl] += dens_mat[block].real.trace()
|
Ncr[bl] += dens_mat[block].real.trace()
|
||||||
|
|
||||||
Ncrtot = 0.0
|
Ncrtot = 0.0
|
||||||
block_ind_list = [block for block,inner in self.gf_struct_sumk[icrsh]]
|
|
||||||
for bl in block_ind_list:
|
spn = self.spin_block_names[self.corr_shells[icrsh][4]]
|
||||||
Ncrtot += Ncr[bl]
|
for sp in spn:
|
||||||
|
Ncrtot += Ncr[sp]
|
||||||
|
|
||||||
# average the densities if there is no SP:
|
# average the densities if there is no SP:
|
||||||
if self.SP == 0:
|
if self.SP == 0:
|
||||||
for bl in block_ind_list:
|
for sp in spn: Ncr[sp] = Ncrtot / len(spn)
|
||||||
Ncr[bl] = Ncrtot / len(block_ind_list)
|
|
||||||
# correction for SO: we have only one block in this case, but in DC we need N/2
|
# correction for SO: we have only one block in this case, but in DC we need N/2
|
||||||
elif self.SP == 1 and self.SO == 1:
|
elif self.SP == 1 and self.SO == 1:
|
||||||
for bl in block_ind_list:
|
for sp in spn: Ncr[sp] = Ncrtot / 2.0
|
||||||
Ncr[bl] = Ncrtot / 2.0
|
|
||||||
|
|
||||||
if use_val is None:
|
if use_val is None:
|
||||||
|
|
||||||
if use_dc_formula == 0: # FLL
|
if use_dc_formula == 0: # FLL
|
||||||
|
|
||||||
self.dc_energ[icrsh] = U_interact / 2.0 * Ncrtot * (Ncrtot-1.0)
|
self.dc_energ[icrsh] = U_interact / 2.0 * Ncrtot * (Ncrtot-1.0)
|
||||||
for bl in block_ind_list:
|
for sp in spn:
|
||||||
Uav = U_interact*(Ncrtot-0.5) - J_hund*(Ncr[bl] - 0.5)
|
Uav = U_interact*(Ncrtot-0.5) - J_hund*(Ncr[sp] - 0.5)
|
||||||
self.dc_imp[icrsh][bl] *= Uav
|
self.dc_imp[icrsh][sp] *= Uav
|
||||||
self.dc_energ[icrsh] -= J_hund / 2.0 * (Ncr[bl]) * (Ncr[bl]-1.0)
|
self.dc_energ[icrsh] -= J_hund / 2.0 * (Ncr[sp]) * (Ncr[sp]-1.0)
|
||||||
mpi.report("DC for shell %(icrsh)i and block %(bl)s = %(Uav)f"%locals())
|
mpi.report("DC for shell %(icrsh)i and block %(sp)s = %(Uav)f"%locals())
|
||||||
|
|
||||||
elif use_dc_formula == 1: # Held's formula, with U_interact the interorbital onsite interaction
|
elif use_dc_formula == 1: # Held's formula, with U_interact the interorbital onsite interaction
|
||||||
|
|
||||||
self.dc_energ[icrsh] = (U_interact + (dim-1)*(U_interact-2.0*J_hund) + (dim-1)*(U_interact-3.0*J_hund))/(2*dim-1) / 2.0 * Ncrtot * (Ncrtot-1.0)
|
self.dc_energ[icrsh] = (U_interact + (dim-1)*(U_interact-2.0*J_hund) + (dim-1)*(U_interact-3.0*J_hund))/(2*dim-1) / 2.0 * Ncrtot * (Ncrtot-1.0)
|
||||||
for bl in block_ind_list:
|
for sp in spn:
|
||||||
Uav =(U_interact + (dim-1)*(U_interact-2.0*J_hund) + (dim-1)*(U_interact-3.0*J_hund))/(2*dim-1) * (Ncrtot-0.5)
|
Uav =(U_interact + (dim-1)*(U_interact-2.0*J_hund) + (dim-1)*(U_interact-3.0*J_hund))/(2*dim-1) * (Ncrtot-0.5)
|
||||||
self.dc_imp[icrsh][bl] *= Uav
|
self.dc_imp[icrsh][sp] *= Uav
|
||||||
mpi.report("DC for shell %(icrsh)i and block %(bl)s = %(Uav)f"%locals())
|
mpi.report("DC for shell %(icrsh)i and block %(sp)s = %(Uav)f"%locals())
|
||||||
|
|
||||||
elif use_dc_formula == 2: # AMF
|
elif use_dc_formula == 2: # AMF
|
||||||
|
|
||||||
self.dc_energ[icrsh] = 0.5 * U_interact * Ncrtot * Ncrtot
|
self.dc_energ[icrsh] = 0.5 * U_interact * Ncrtot * Ncrtot
|
||||||
for bl in block_ind_list:
|
for sp in spn:
|
||||||
Uav = U_interact*(Ncrtot - Ncr[bl]/dim) - J_hund * (Ncr[bl] - Ncr[bl]/dim)
|
Uav = U_interact*(Ncrtot - Ncr[sp]/dim) - J_hund * (Ncr[sp] - Ncr[sp]/dim)
|
||||||
self.dc_imp[icrsh][bl] *= Uav
|
self.dc_imp[icrsh][sp] *= Uav
|
||||||
self.dc_energ[icrsh] -= (U_interact + (dim-1)*J_hund)/dim * 0.5 * Ncr[bl] * Ncr[bl]
|
self.dc_energ[icrsh] -= (U_interact + (dim-1)*J_hund)/dim * 0.5 * Ncr[sp] * Ncr[sp]
|
||||||
mpi.report("DC for shell %(icrsh)i and block %(bl)s = %(Uav)f"%locals())
|
mpi.report("DC for shell %(icrsh)i and block %(sp)s = %(Uav)f"%locals())
|
||||||
|
|
||||||
# output:
|
# output:
|
||||||
mpi.report("DC energy for shell %s = %s"%(icrsh,self.dc_energ[icrsh]))
|
mpi.report("DC energy for shell %s = %s"%(icrsh,self.dc_energ[icrsh]))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
block_ind_list = [block for block,inner in self.gf_struct_sumk[icrsh]]
|
|
||||||
for bl in block_ind_list:
|
|
||||||
self.dc_imp[icrsh][bl] *= use_val
|
|
||||||
|
|
||||||
self.dc_energ[icrsh] = use_val * Ncrtot
|
self.dc_energ[icrsh] = use_val * Ncrtot
|
||||||
|
for sp in spn:
|
||||||
|
self.dc_imp[icrsh][sp] *= use_val
|
||||||
|
|
||||||
# output:
|
# output:
|
||||||
mpi.report("DC for shell %(icrsh)i = %(use_val)f"%locals())
|
mpi.report("DC for shell %(icrsh)i = %(use_val)f"%locals())
|
||||||
mpi.report("DC energy = %s"%self.dc_energ[icrsh])
|
mpi.report("DC energy = %s"%self.dc_energ[icrsh])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def put_Sigma(self, Sigma_imp):
|
|
||||||
"""Puts the impurity self energies for inequivalent atoms into the class, respects the multiplicity of the atoms."""
|
|
||||||
|
|
||||||
assert isinstance(Sigma_imp,list), "Sigma_imp has to be a list of Sigmas for the correlated shells, even if it is of length 1!"
|
|
||||||
assert len(Sigma_imp) == self.n_inequiv_shells, "give exactly one Sigma for each inequivalent corr. shell!"
|
|
||||||
|
|
||||||
# init self.Sigma_imp:
|
|
||||||
if all(type(gf) == GfImFreq for bname,gf in Sigma_imp[0]):
|
|
||||||
# Imaginary frequency Sigma:
|
|
||||||
self.Sigma_imp = [ BlockGf( name_block_generator = [ (block,GfImFreq(indices = inner, mesh = Sigma_imp[0].mesh)) for block,inner in self.gf_struct_sumk[icrsh] ],
|
|
||||||
make_copies = False) for icrsh in range(self.n_corr_shells) ]
|
|
||||||
elif all(type(gf) == GfReFreq for bname,gf in Sigma_imp[0]):
|
|
||||||
# Real frequency Sigma:
|
|
||||||
self.Sigma_imp = [ BlockGf( name_block_generator = [ (block,GfReFreq(indices = inner, mesh = Sigma_imp[0].mesh)) for block,inner in self.gf_struct_sumk[icrsh] ],
|
|
||||||
make_copies = False) for icrsh in range(self.n_corr_shells) ]
|
|
||||||
else:
|
|
||||||
raise ValueError, "This type of Sigma is not handled."
|
|
||||||
|
|
||||||
# transform the CTQMC blocks to the full matrix:
|
|
||||||
for icrsh in range(self.n_corr_shells):
|
|
||||||
ish = self.corr_to_inequiv[icrsh] # ish is the index of the inequivalent shell corresponding to icrsh
|
|
||||||
|
|
||||||
for block,inner in self.gf_struct_solver[ish].iteritems():
|
|
||||||
for ind1 in inner:
|
|
||||||
for ind2 in inner:
|
|
||||||
block_sumk,ind1_sumk = self.solver_to_sumk[ish][(block,ind1)]
|
|
||||||
block_sumk,ind2_sumk = self.solver_to_sumk[ish][(block,ind2)]
|
|
||||||
self.Sigma_imp[icrsh][block_sumk][ind1_sumk,ind2_sumk] << Sigma_imp[ish][block][ind1,ind2]
|
|
||||||
|
|
||||||
# rotation from local to global coordinate system:
|
|
||||||
if self.use_rotations:
|
|
||||||
for icrsh in range(self.n_corr_shells):
|
|
||||||
for bname,gf in self.Sigma_imp[icrsh]: self.Sigma_imp[icrsh][bname] << self.rotloc(icrsh,gf,direction='toGlobal')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def add_dc(self):
|
def add_dc(self):
|
||||||
"""Substracts the double counting term from the impurity self energy."""
|
"""Substracts the double counting term from the impurity self energy."""
|
||||||
|
|
||||||
@ -677,11 +709,16 @@ class SumkLDA:
|
|||||||
return sres # list of self energies corrected by DC
|
return sres # list of self energies corrected by DC
|
||||||
|
|
||||||
|
|
||||||
|
def symm_deg_gf(self,gf_to_symm,orb):
|
||||||
|
"""Symmetrises a GF for the given degenerate shells self.deg_shells"""
|
||||||
|
|
||||||
def set_mu(self,mu):
|
for degsh in self.deg_shells[orb]:
|
||||||
"""Sets a new chemical potential"""
|
#loop over degenerate shells:
|
||||||
|
ss = gf_to_symm[degsh[0]].copy()
|
||||||
self.chemical_potential = mu
|
ss.zero()
|
||||||
|
n_deg = len(degsh)
|
||||||
|
for bl in degsh: ss += gf_to_symm[bl] / (1.0*n_deg)
|
||||||
|
for bl in degsh: gf_to_symm[bl] << ss
|
||||||
|
|
||||||
|
|
||||||
def total_density(self, mu):
|
def total_density(self, mu):
|
||||||
@ -695,7 +732,6 @@ class SumkLDA:
|
|||||||
|
|
||||||
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):
|
||||||
|
|
||||||
S = self.lattice_gf_matsubara(ik = ik, mu = mu)
|
S = self.lattice_gf_matsubara(ik = ik, mu = mu)
|
||||||
@ -708,6 +744,12 @@ class SumkLDA:
|
|||||||
return dens
|
return dens
|
||||||
|
|
||||||
|
|
||||||
|
def set_mu(self,mu):
|
||||||
|
"""Sets a new chemical potential"""
|
||||||
|
|
||||||
|
self.chemical_potential = mu
|
||||||
|
|
||||||
|
|
||||||
def find_mu(self, precision = 0.01):
|
def find_mu(self, precision = 0.01):
|
||||||
"""
|
"""
|
||||||
Searches for mu in order to give the desired charge
|
Searches for mu in order to give the desired charge
|
||||||
@ -715,7 +757,6 @@ class SumkLDA:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
F = lambda mu : self.total_density(mu = mu)
|
F = lambda mu : self.total_density(mu = mu)
|
||||||
|
|
||||||
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,
|
||||||
@ -727,80 +768,21 @@ class SumkLDA:
|
|||||||
return self.chemical_potential
|
return self.chemical_potential
|
||||||
|
|
||||||
|
|
||||||
def extract_G_loc(self, mu=None, with_Sigma = True):
|
|
||||||
"""
|
|
||||||
Extracts the local downfolded Green function at the chemical potential of the class.
|
|
||||||
At the end, the local G is rotated from the global coordinate system to the local system.
|
|
||||||
if with_Sigma = False: Sigma is not included => non-interacting local GF
|
|
||||||
"""
|
|
||||||
|
|
||||||
if mu is None: mu = self.chemical_potential
|
|
||||||
|
|
||||||
Gloc = [ self.Sigma_imp[icrsh].copy() for icrsh in range(self.n_corr_shells) ] # this list will be returned
|
|
||||||
for icrsh in range(self.n_corr_shells): Gloc[icrsh].zero() # initialize to zero
|
|
||||||
beta = Gloc[0].mesh.beta
|
|
||||||
|
|
||||||
ikarray=numpy.array(range(self.n_k))
|
|
||||||
|
|
||||||
for ik in mpi.slice_array(ikarray):
|
|
||||||
|
|
||||||
S = self.lattice_gf_matsubara(ik=ik,mu=mu,with_Sigma = with_Sigma, beta = beta)
|
|
||||||
S *= self.bz_weights[ik]
|
|
||||||
|
|
||||||
for icrsh in range(self.n_corr_shells):
|
|
||||||
tmp = Gloc[icrsh].copy() # init temporary storage
|
|
||||||
for bname,gf in tmp: tmp[bname] << self.downfold(ik,icrsh,bname,S[bname],gf)
|
|
||||||
Gloc[icrsh] += tmp
|
|
||||||
|
|
||||||
#collect data from mpi:
|
|
||||||
for icrsh in range(self.n_corr_shells):
|
|
||||||
Gloc[icrsh] << mpi.all_reduce(mpi.world, Gloc[icrsh], lambda x,y : x+y)
|
|
||||||
mpi.barrier()
|
|
||||||
|
|
||||||
# Gloc[:] is now the sum over k projected to the local orbitals.
|
|
||||||
# here comes the symmetrisation, if needed:
|
|
||||||
if self.symm_op != 0: Gloc = self.symmcorr.symmetrize(Gloc)
|
|
||||||
|
|
||||||
# Gloc is rotated to the local coordinate system:
|
|
||||||
if self.use_rotations:
|
|
||||||
for icrsh in range(self.n_corr_shells):
|
|
||||||
for bname,gf in Gloc[icrsh]: Gloc[icrsh][bname] << self.rotloc(icrsh,gf,direction='toLocal')
|
|
||||||
|
|
||||||
# transform to CTQMC blocks:
|
|
||||||
Glocret = [ BlockGf( name_block_generator = [ (block,GfImFreq(indices = inner, mesh = Gloc[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 block,inner in self.gf_struct_solver[ish].iteritems():
|
|
||||||
for ind1 in inner:
|
|
||||||
for ind2 in inner:
|
|
||||||
block_sumk,ind1_sumk = self.solver_to_sumk[ish][(block,ind1)]
|
|
||||||
block_sumk,ind2_sumk = self.solver_to_sumk[ish][(block,ind2)]
|
|
||||||
Glocret[ish][block][ind1,ind2] << Gloc[self.inequiv_to_corr[ish]][block_sumk][ind1_sumk,ind2_sumk]
|
|
||||||
|
|
||||||
# return only the inequivalent shells:
|
|
||||||
return Glocret
|
|
||||||
|
|
||||||
|
|
||||||
def calc_density_correction(self,filename = 'dens_mat.dat'):
|
def calc_density_correction(self,filename = 'dens_mat.dat'):
|
||||||
""" Calculates the density correction in order to feed it back to the DFT calculations."""
|
""" Calculates the density correction in order to feed it back to the DFT calculations."""
|
||||||
|
|
||||||
assert type(filename) == StringType, "filename has to be a string!"
|
assert type(filename) == StringType, "filename has to be a string!"
|
||||||
|
|
||||||
ntoi = self.spin_names_to_ind[self.SO]
|
ntoi = self.spin_names_to_ind[self.SO]
|
||||||
bln = self.spin_block_names[self.SO]
|
spn = self.spin_block_names[self.SO]
|
||||||
|
dens = {sp: 0.0 for sp in spn}
|
||||||
|
|
||||||
# Set up deltaN:
|
# Set up deltaN:
|
||||||
deltaN = {}
|
deltaN = {}
|
||||||
for b in bln:
|
for sp in spn:
|
||||||
deltaN[b] = [ numpy.zeros( [self.n_orbitals[ik,ntoi[b]],self.n_orbitals[ik,ntoi[b]]], numpy.complex_) for ik in range(self.n_k)]
|
deltaN[sp] = [numpy.zeros([self.n_orbitals[ik,ntoi[sp]],self.n_orbitals[ik,ntoi[sp]]], numpy.complex_) for ik in range(self.n_k)]
|
||||||
|
|
||||||
ikarray = numpy.array(range(self.n_k))
|
ikarray = numpy.array(range(self.n_k))
|
||||||
|
|
||||||
dens = {}
|
|
||||||
for b in bln:
|
|
||||||
dens[b] = 0.0
|
|
||||||
|
|
||||||
for ik in mpi.slice_array(ikarray):
|
for ik in mpi.slice_array(ikarray):
|
||||||
S = self.lattice_gf_matsubara(ik = ik, mu = self.chemical_potential)
|
S = self.lattice_gf_matsubara(ik = ik, mu = self.chemical_potential)
|
||||||
for bname,gf in S:
|
for bname,gf in S:
|
||||||
@ -847,7 +829,7 @@ class SumkLDA:
|
|||||||
if self.SO == 0: to_write = {f: (0, 'up'), f1: (1, 'down')}
|
if self.SO == 0: to_write = {f: (0, 'up'), f1: (1, 'down')}
|
||||||
if self.SO == 1: to_write = {f: (0, 'ud'), f1: (0, 'ud')}
|
if self.SO == 1: to_write = {f: (0, 'ud'), f1: (0, 'ud')}
|
||||||
for fout in to_write.iterkeys():
|
for fout in to_write.iterkeys():
|
||||||
isp, bn = to_write[fout]
|
isp, sp = to_write[fout]
|
||||||
for ik in range(self.n_k):
|
for ik in range(self.n_k):
|
||||||
fout.write("%s\n"%self.n_orbitals[ik,isp])
|
fout.write("%s\n"%self.n_orbitals[ik,isp])
|
||||||
for inu in range(self.n_orbitals[ik,isp]):
|
for inu in range(self.n_orbitals[ik,isp]):
|
||||||
@ -859,7 +841,6 @@ class SumkLDA:
|
|||||||
|
|
||||||
return deltaN, dens
|
return deltaN, dens
|
||||||
|
|
||||||
|
|
||||||
################
|
################
|
||||||
# FIXME LEAVE UNDOCUMENTED
|
# FIXME LEAVE UNDOCUMENTED
|
||||||
################
|
################
|
||||||
@ -912,7 +893,7 @@ class SumkLDA:
|
|||||||
dcnew = dichotomy.dichotomy(function = F,
|
dcnew = dichotomy.dichotomy(function = F,
|
||||||
x_init = guess, y_value = density,
|
x_init = guess, y_value = density,
|
||||||
precision_on_y = precision, delta_x = 0.5,
|
precision_on_y = precision, delta_x = 0.5,
|
||||||
max_loops = 100, x_name="Double-Counting", y_name= "Total Density",
|
max_loops = 100, x_name = "Double Counting", y_name= "Total Density",
|
||||||
verbosity = 3)[0]
|
verbosity = 3)[0]
|
||||||
|
|
||||||
return dcnew
|
return dcnew
|
||||||
|
@ -86,19 +86,19 @@ class SumkLDATools(SumkLDA):
|
|||||||
present and with_Sigma=True, the mesh is taken from Sigma. Otherwise, the mesh has to be given."""
|
present and with_Sigma=True, the mesh is taken from Sigma. Otherwise, the mesh has to be given."""
|
||||||
|
|
||||||
ntoi = self.spin_names_to_ind[self.SO]
|
ntoi = self.spin_names_to_ind[self.SO]
|
||||||
bln = self.spin_block_names[self.SO]
|
spn = self.spin_block_names[self.SO]
|
||||||
|
|
||||||
if not hasattr(self,"Sigma_imp"): with_Sigma=False
|
if not hasattr(self,"Sigma_imp"): with_Sigma=False
|
||||||
if with_Sigma:
|
if with_Sigma:
|
||||||
assert all(type(gf) == GfReFreq for bname,gf in self.Sigma_imp[0]), "Real frequency Sigma needed for lattice_gf_realfreq!"
|
assert all(type(gf) == GfReFreq for bname,gf in self.Sigma_imp[0]), "Real frequency Sigma needed for lattice_gf_realfreq!"
|
||||||
stmp = self.add_dc()
|
stmp = self.add_dc()
|
||||||
else:
|
else:
|
||||||
assert (not (mesh is None)),"Without Sigma, give the mesh=(om_min,om_max,n_points) for lattice_gf_realfreq!"
|
assert (not mesh is None),"Without Sigma, give the mesh=(om_min,om_max,n_points) for lattice_gf_realfreq!"
|
||||||
|
|
||||||
if self.G_upfold_refreq is None:
|
if self.G_upfold_refreq is None:
|
||||||
# first setting up of G_upfold_refreq
|
# first setting up of G_upfold_refreq
|
||||||
block_structure = [ range(self.n_orbitals[ik,ntoi[b]]) for b in bln ]
|
block_structure = [ range(self.n_orbitals[ik,ntoi[sp]]) for sp in spn ]
|
||||||
gf_struct = [ (bln[ibl], block_structure[ibl]) for ibl in range(self.n_spin_blocks[self.SO]) ]
|
gf_struct = [ (spn[isp], block_structure[isp]) for isp in range(self.n_spin_blocks[self.SO]) ]
|
||||||
block_ind_list = [block for block,inner in gf_struct]
|
block_ind_list = [block for block,inner in gf_struct]
|
||||||
if with_Sigma:
|
if with_Sigma:
|
||||||
glist = lambda : [ GfReFreq(indices = inner, mesh=self.Sigma_imp[0].mesh) for block,inner in gf_struct]
|
glist = lambda : [ GfReFreq(indices = inner, mesh=self.Sigma_imp[0].mesh) for block,inner in gf_struct]
|
||||||
@ -108,12 +108,12 @@ class SumkLDATools(SumkLDA):
|
|||||||
self.G_upfold_refreq.zero()
|
self.G_upfold_refreq.zero()
|
||||||
|
|
||||||
GFsize = [ gf.N1 for bname,gf in self.G_upfold_refreq]
|
GFsize = [ gf.N1 for bname,gf in self.G_upfold_refreq]
|
||||||
unchangedsize = all( [ self.n_orbitals[ik,ntoi[bln[ibl]]] == GFsize[ibl]
|
unchangedsize = all( [ self.n_orbitals[ik,ntoi[spn[isp]]] == GFsize[isp]
|
||||||
for ibl in range(self.n_spin_blocks[self.SO]) ] )
|
for isp in range(self.n_spin_blocks[self.SO]) ] )
|
||||||
|
|
||||||
if not unchangedsize:
|
if not unchangedsize:
|
||||||
block_structure = [ range(self.n_orbitals[ik,ntoi[b]]) for b in bln ]
|
block_structure = [ range(self.n_orbitals[ik,ntoi[sp]]) for sp in spn ]
|
||||||
gf_struct = [ (bln[ibl], block_structure[ibl]) for ibl in range(self.n_spin_blocks[self.SO]) ]
|
gf_struct = [ (spn[isp], block_structure[isp]) for isp in range(self.n_spin_blocks[self.SO]) ]
|
||||||
block_ind_list = [block for block,inner in gf_struct]
|
block_ind_list = [block for block,inner in gf_struct]
|
||||||
if with_Sigma:
|
if with_Sigma:
|
||||||
glist = lambda : [ GfReFreq(indices = inner, mesh =self.Sigma_imp[0].mesh) for block,inner in gf_struct]
|
glist = lambda : [ GfReFreq(indices = inner, mesh =self.Sigma_imp[0].mesh) for block,inner in gf_struct]
|
||||||
@ -122,14 +122,14 @@ class SumkLDATools(SumkLDA):
|
|||||||
self.G_upfold_refreq = BlockGf(name_list = block_ind_list, block_list = glist(),make_copies=False)
|
self.G_upfold_refreq = BlockGf(name_list = block_ind_list, block_list = glist(),make_copies=False)
|
||||||
self.G_upfold_refreq.zero()
|
self.G_upfold_refreq.zero()
|
||||||
|
|
||||||
idmat = [numpy.identity(self.n_orbitals[ik,ntoi[b]],numpy.complex_) for b in bln]
|
idmat = [numpy.identity(self.n_orbitals[ik,ntoi[sp]],numpy.complex_) for sp in spn]
|
||||||
|
|
||||||
self.G_upfold_refreq << Omega + 1j*broadening
|
self.G_upfold_refreq << Omega + 1j*broadening
|
||||||
M = copy.deepcopy(idmat)
|
M = copy.deepcopy(idmat)
|
||||||
for ibl in range(self.n_spin_blocks[self.SO]):
|
for isp in range(self.n_spin_blocks[self.SO]):
|
||||||
ind = ntoi[bln[ibl]]
|
ind = ntoi[spn[isp]]
|
||||||
n_orb = self.n_orbitals[ik,ind]
|
n_orb = self.n_orbitals[ik,ind]
|
||||||
M[ibl] = self.hopping[ik,ind,0:n_orb,0:n_orb] - (idmat[ibl]*mu) - (idmat[ibl] * self.h_field * (1-2*ibl))
|
M[isp] = self.hopping[ik,ind,0:n_orb,0:n_orb] - (idmat[isp]*mu) - (idmat[isp] * self.h_field * (1-2*isp))
|
||||||
self.G_upfold_refreq -= M
|
self.G_upfold_refreq -= M
|
||||||
|
|
||||||
if with_Sigma:
|
if with_Sigma:
|
||||||
@ -166,9 +166,9 @@ class SumkLDATools(SumkLDA):
|
|||||||
# init:
|
# init:
|
||||||
Gloc = []
|
Gloc = []
|
||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells):
|
||||||
b_list = [block for block,inner in self.gf_struct_sumk[icrsh]]
|
spn = self.spin_block_names[self.corr_shells[icrsh][4]]
|
||||||
glist = lambda : [ GfReFreq(indices = inner, window = (om_min,om_max), n_points = n_om) for block,inner in self.gf_struct_sumk[icrsh]]
|
glist = lambda : [ GfReFreq(indices = inner, window = (om_min,om_max), n_points = n_om) for block,inner in self.gf_struct_sumk[icrsh]]
|
||||||
Gloc.append(BlockGf(name_list = b_list, block_list = glist(),make_copies=False))
|
Gloc.append(BlockGf(name_list = spn, block_list = glist(),make_copies=False))
|
||||||
for icrsh in range(self.n_corr_shells): Gloc[icrsh].zero() # initialize to zero
|
for icrsh in range(self.n_corr_shells): Gloc[icrsh].zero() # initialize to zero
|
||||||
|
|
||||||
for ik in range(self.n_k):
|
for ik in range(self.n_k):
|
||||||
@ -246,7 +246,7 @@ class SumkLDATools(SumkLDA):
|
|||||||
|
|
||||||
mu = self.chemical_potential
|
mu = self.chemical_potential
|
||||||
|
|
||||||
gf_struct_proj = [ [ (b, range(self.shells[i][3])) for b in self.spin_block_names[self.SO] ] for i in range(self.n_shells) ]
|
gf_struct_proj = [ [ (sp, range(self.shells[i][3])) for sp in self.spin_block_names[self.SO] ] for i in range(self.n_shells) ]
|
||||||
Gproj = [BlockGf(name_block_generator = [ (block,GfReFreq(indices = inner, mesh = self.Sigma_imp[0].mesh)) for block,inner in gf_struct_proj[ish] ], make_copies = False )
|
Gproj = [BlockGf(name_block_generator = [ (block,GfReFreq(indices = inner, mesh = self.Sigma_imp[0].mesh)) for block,inner in gf_struct_proj[ish] ], make_copies = False )
|
||||||
for ish in range(self.n_shells)]
|
for ish in range(self.n_shells)]
|
||||||
for ish in range(self.n_shells): Gproj[ish].zero()
|
for ish in range(self.n_shells): Gproj[ish].zero()
|
||||||
@ -366,7 +366,7 @@ class SumkLDATools(SumkLDA):
|
|||||||
# calculate A(k,w):
|
# calculate A(k,w):
|
||||||
|
|
||||||
mu = self.chemical_potential
|
mu = self.chemical_potential
|
||||||
bln = self.spin_block_names[self.SO]
|
spn = self.spin_block_names[self.SO]
|
||||||
|
|
||||||
# init DOS:
|
# init DOS:
|
||||||
M = [x.real for x in self.Sigma_imp[0].mesh]
|
M = [x.real for x in self.Sigma_imp[0].mesh]
|
||||||
@ -381,19 +381,19 @@ class SumkLDATools(SumkLDA):
|
|||||||
|
|
||||||
if ishell is None:
|
if ishell is None:
|
||||||
Akw = {}
|
Akw = {}
|
||||||
for b in bln: Akw[b] = numpy.zeros([self.n_k, n_om ],numpy.float_)
|
for sp in spn: Akw[sp] = numpy.zeros([self.n_k, n_om ],numpy.float_)
|
||||||
else:
|
else:
|
||||||
Akw = {}
|
Akw = {}
|
||||||
for b in bln: Akw[b] = numpy.zeros([self.shells[ishell][3],self.n_k, n_om ],numpy.float_)
|
for sp in spn: Akw[sp] = numpy.zeros([self.shells[ishell][3],self.n_k, n_om ],numpy.float_)
|
||||||
|
|
||||||
if fermi_surface:
|
if fermi_surface:
|
||||||
om_minplot = -2.0*broadening
|
om_minplot = -2.0*broadening
|
||||||
om_maxplot = 2.0*broadening
|
om_maxplot = 2.0*broadening
|
||||||
Akw = {}
|
Akw = {}
|
||||||
for b in bln: Akw[b] = numpy.zeros([self.n_k,1],numpy.float_)
|
for sp in spn: Akw[sp] = numpy.zeros([self.n_k,1],numpy.float_)
|
||||||
|
|
||||||
if not (ishell is None):
|
if not ishell is None:
|
||||||
GFStruct_proj = [ (b, range(self.shells[ishell][3])) for b in bln ]
|
GFStruct_proj = [ (sp, range(self.shells[ishell][3])) for sp in spn ]
|
||||||
Gproj = BlockGf(name_block_generator = [ (block,GfReFreq(indices = inner, mesh = self.Sigma_imp[0].mesh)) for block,inner in GFStruct_proj ], make_copies = False)
|
Gproj = BlockGf(name_block_generator = [ (block,GfReFreq(indices = inner, mesh = self.Sigma_imp[0].mesh)) for block,inner in GFStruct_proj ], make_copies = False)
|
||||||
Gproj.zero()
|
Gproj.zero()
|
||||||
|
|
||||||
@ -428,7 +428,7 @@ class SumkLDATools(SumkLDA):
|
|||||||
for iom in range(n_om):
|
for iom in range(n_om):
|
||||||
if (M[iom] > om_minplot) and (M[iom] < om_maxplot):
|
if (M[iom] > om_minplot) and (M[iom] < om_maxplot):
|
||||||
for ish in range(self.shells[ishell][3]):
|
for ish in range(self.shells[ishell][3]):
|
||||||
for ibn in bln:
|
for ibn in spn:
|
||||||
Akw[ibn][ish,ik,iom] = Gproj[ibn].data[iom,ish,ish].imag/(-3.1415926535)
|
Akw[ibn][ish,ik,iom] = Gproj[ibn].data[iom,ish,ish].imag/(-3.1415926535)
|
||||||
|
|
||||||
|
|
||||||
@ -436,7 +436,7 @@ class SumkLDATools(SumkLDA):
|
|||||||
if mpi.is_master_node():
|
if mpi.is_master_node():
|
||||||
if ishell is None:
|
if ishell is None:
|
||||||
|
|
||||||
for ibn in bln:
|
for ibn in spn:
|
||||||
# loop over GF blocs:
|
# loop over GF blocs:
|
||||||
|
|
||||||
if invert_Akw:
|
if invert_Akw:
|
||||||
@ -470,7 +470,7 @@ class SumkLDATools(SumkLDA):
|
|||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for ibn in bln:
|
for ibn in spn:
|
||||||
for ish in range(self.shells[ishell][3]):
|
for ish in range(self.shells[ishell][3]):
|
||||||
|
|
||||||
if invert_Akw:
|
if invert_Akw:
|
||||||
@ -503,13 +503,13 @@ class SumkLDATools(SumkLDA):
|
|||||||
if self.symm_op: self.symmpar = Symmetry(self.hdf_file,subgroup=self.symmpar_data)
|
if self.symm_op: self.symmpar = Symmetry(self.hdf_file,subgroup=self.symmpar_data)
|
||||||
|
|
||||||
# Density matrix in the window
|
# Density matrix in the window
|
||||||
bln = self.spin_block_names[self.SO]
|
spn = self.spin_block_names[self.SO]
|
||||||
ntoi = self.spin_names_to_ind[self.SO]
|
ntoi = self.spin_names_to_ind[self.SO]
|
||||||
self.dens_mat_window = [ [numpy.zeros([self.shells[ish][3],self.shells[ish][3]],numpy.complex_) for ish in range(self.n_shells)]
|
self.dens_mat_window = [ [numpy.zeros([self.shells[ish][3],self.shells[ish][3]],numpy.complex_) for ish in range(self.n_shells)]
|
||||||
for isp in range(len(bln)) ] # init the density matrix
|
for isp in range(len(spn)) ] # init the density matrix
|
||||||
|
|
||||||
mu = self.chemical_potential
|
mu = self.chemical_potential
|
||||||
GFStruct_proj = [ [ (b, range(self.shells[i][3])) for b in bln ] for i in range(self.n_shells) ]
|
GFStruct_proj = [ [ (sp, range(self.shells[i][3])) for sp in spn ] for i in range(self.n_shells) ]
|
||||||
if hasattr(self,"Sigma_imp"):
|
if hasattr(self,"Sigma_imp"):
|
||||||
Gproj = [BlockGf(name_block_generator = [ (block,GfImFreq(indices = inner, mesh = self.Sigma_imp[0].mesh)) for block,inner in GFStruct_proj[ish] ], make_copies = False)
|
Gproj = [BlockGf(name_block_generator = [ (block,GfImFreq(indices = inner, mesh = self.Sigma_imp[0].mesh)) for block,inner in GFStruct_proj[ish] ], make_copies = False)
|
||||||
for ish in range(self.n_shells)]
|
for ish in range(self.n_shells)]
|
||||||
@ -553,7 +553,7 @@ class SumkLDATools(SumkLDA):
|
|||||||
isp+=1
|
isp+=1
|
||||||
|
|
||||||
# add Density matrices to get the total:
|
# add Density matrices to get the total:
|
||||||
dens_mat = [ [ self.dens_mat_below[ntoi[bln[isp]]][ish]+self.dens_mat_window[isp][ish] for ish in range(self.n_shells)]
|
dens_mat = [ [ self.dens_mat_below[ntoi[spn[isp]]][ish]+self.dens_mat_window[isp][ish] for ish in range(self.n_shells)]
|
||||||
for isp in range(len(bln)) ]
|
for isp in range(len(spn)) ]
|
||||||
|
|
||||||
return dens_mat
|
return dens_mat
|
||||||
|
Loading…
Reference in New Issue
Block a user