mirror of
https://github.com/triqs/dft_tools
synced 2024-08-29 23:33:43 +02:00
Fix bugs in sumk_lda_tools.py
This is again a merge of Leonid's and Markus' changes. It must be checked! I had to make some choices! modified: python/sumk_lda_tools.py
This commit is contained in:
parent
2d5cf0abc7
commit
8db8a52eaa
@ -42,8 +42,8 @@ def read_fortran_file (filename):
|
|||||||
import os.path
|
import os.path
|
||||||
if not(os.path.exists(filename)) : raise IOError, "File %s does not exists"%filename
|
if not(os.path.exists(filename)) : raise IOError, "File %s does not exists"%filename
|
||||||
for line in open(filename,'r') :
|
for line in open(filename,'r') :
|
||||||
for x in line.replace('D','E').split() :
|
for x in line.replace('D','E').split() :
|
||||||
yield string.atof(x)
|
yield string.atof(x)
|
||||||
|
|
||||||
|
|
||||||
class SumkLDATools(SumkLDA):
|
class SumkLDATools(SumkLDA):
|
||||||
@ -99,22 +99,21 @@ class SumkLDATools(SumkLDA):
|
|||||||
return gf_rotated
|
return gf_rotated
|
||||||
|
|
||||||
|
|
||||||
def lattice_gf_realfreq(self, ik, mu, broadening, mesh=None, beta=40, with_Sigma=True):
|
def lattice_gf_realfreq(self, ik, mu, broadening, mesh=None, with_Sigma=True):
|
||||||
"""Calculates the lattice Green function on the real frequency axis. If self energy is
|
"""Calculates the lattice Green function on the real frequency axis. If self energy is
|
||||||
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.names_to_ind[self.SO]
|
ntoi = self.names_to_ind[self.SO]
|
||||||
bln = self.blocnames[self.SO]
|
bln = self.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 type(self.Sigma_imp[0]) == GfReFreq, "Real frequency Sigma needed for lattice_gf_realfreq!"
|
assert self.Sigma_imp[0].note == 'ReFreq', "Real frequency Sigma needed for lattice_gf_realfreq!"
|
||||||
beta = self.Sigma_imp[0].mesh.beta
|
|
||||||
stmp = self.add_dc()
|
stmp = self.add_dc()
|
||||||
else:
|
else:
|
||||||
assert (not (mesh is None)),"Without Sigma, give the mesh 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.Gupf_refreq is None):
|
if (self.Gupf_refreq is None):
|
||||||
# first setting up of Gupf_refreq
|
# first setting up of Gupf_refreq
|
||||||
BS = [ range(self.n_orbitals[ik,ntoi[ib]]) for ib in bln ]
|
BS = [ range(self.n_orbitals[ik,ntoi[ib]]) for ib in bln ]
|
||||||
gf_struct = [ (bln[ib], BS[ib]) for ib in range(self.n_spin_blocks_gf[self.SO]) ]
|
gf_struct = [ (bln[ib], BS[ib]) for ib in range(self.n_spin_blocks_gf[self.SO]) ]
|
||||||
@ -122,7 +121,7 @@ class SumkLDATools(SumkLDA):
|
|||||||
if (with_Sigma):
|
if (with_Sigma):
|
||||||
glist = lambda : [ GfReFreq(indices = al, mesh =self.Sigma_imp[0].mesh) for a,al in gf_struct]
|
glist = lambda : [ GfReFreq(indices = al, mesh =self.Sigma_imp[0].mesh) for a,al in gf_struct]
|
||||||
else:
|
else:
|
||||||
glist = lambda : [ GfReFreq(indices = al, beta = beta, mesh_array = mesh) for a,al in gf_struct]
|
glist = lambda : [ GfReFreq(indices = al, window=(mesh[0],mesh[1]),n_points=mesh[2]) for a,al in gf_struct]
|
||||||
self.Gupf_refreq = BlockGf(name_list = a_list, block_list = glist(),make_copies=False)
|
self.Gupf_refreq = BlockGf(name_list = a_list, block_list = glist(),make_copies=False)
|
||||||
self.Gupf_refreq.zero()
|
self.Gupf_refreq.zero()
|
||||||
|
|
||||||
@ -137,7 +136,7 @@ class SumkLDATools(SumkLDA):
|
|||||||
if (with_Sigma):
|
if (with_Sigma):
|
||||||
glist = lambda : [ GfReFreq(indices = al, mesh =self.Sigma_imp[0].mesh) for a,al in gf_struct]
|
glist = lambda : [ GfReFreq(indices = al, mesh =self.Sigma_imp[0].mesh) for a,al in gf_struct]
|
||||||
else:
|
else:
|
||||||
glist = lambda : [ GfReFreq(indices = al, beta = beta, mesh_array = mesh) for a,al in gf_struct]
|
glist = lambda : [ GfReFreq(indices = al, window=(mesh[0],mesh[1]),n_points=mesh[2]) for a,al in gf_struct]
|
||||||
self.Gupf_refreq = BlockGf(name_list = a_list, block_list = glist(),make_copies=False)
|
self.Gupf_refreq = BlockGf(name_list = a_list, block_list = glist(),make_copies=False)
|
||||||
self.Gupf_refreq.zero()
|
self.Gupf_refreq.zero()
|
||||||
|
|
||||||
@ -167,7 +166,8 @@ class SumkLDATools(SumkLDA):
|
|||||||
|
|
||||||
|
|
||||||
delta_om = (om_max-om_min)/(n_om-1)
|
delta_om = (om_max-om_min)/(n_om-1)
|
||||||
mesh = numpy.zeros([n_om],numpy.float_)
|
om_mesh = numpy.zeros([n_om],numpy.float_)
|
||||||
|
for i in range(n_om): om_mesh[i] = om_min + delta_om * i
|
||||||
|
|
||||||
DOS = {}
|
DOS = {}
|
||||||
for bn in self.block_names[self.SO]:
|
for bn in self.block_names[self.SO]:
|
||||||
@ -179,22 +179,20 @@ class SumkLDATools(SumkLDA):
|
|||||||
for bn in self.block_names[self.corr_shells[self.invshellmap[icrsh]][4]]:
|
for bn in self.block_names[self.corr_shells[self.invshellmap[icrsh]][4]]:
|
||||||
dl = self.corr_shells[self.invshellmap[icrsh]][3]
|
dl = self.corr_shells[self.invshellmap[icrsh]][3]
|
||||||
DOSproj[icrsh][bn] = numpy.zeros([n_om],numpy.float_)
|
DOSproj[icrsh][bn] = numpy.zeros([n_om],numpy.float_)
|
||||||
DOSproj_orb[icrsh][bn] = numpy.zeros([dl,dl,n_om],numpy.float_)
|
DOSproj_orb[icrsh][bn] = numpy.zeros([n_om,dl,dl],numpy.float_)
|
||||||
|
|
||||||
|
|
||||||
for i in range(n_om): mesh[i] = om_min + delta_om * i
|
|
||||||
|
|
||||||
# init:
|
# init:
|
||||||
Gloc = []
|
Gloc = []
|
||||||
for icrsh in range(self.n_corr_shells):
|
for icrsh in range(self.n_corr_shells):
|
||||||
b_list = [a for a,al in self.gf_struct_corr[icrsh]]
|
b_list = [a for a,al in self.gf_struct_corr[icrsh]]
|
||||||
glist = lambda : [ GfReFreq(indices = al, beta = beta, mesh_array = mesh) for a,al in self.gf_struct_corr[icrsh]]
|
#glist = lambda : [ GfReFreq(indices = al, beta = beta, mesh_array = mesh) for a,al in self.gf_struct_corr[icrsh]]
|
||||||
|
glist = lambda : [ GfReFreq(indices = al, window = (om_min,om_max), n_points = n_om) for a,al in self.gf_struct_corr[icrsh]]
|
||||||
Gloc.append(BlockGf(name_list = b_list, block_list = glist(),make_copies=False))
|
Gloc.append(BlockGf(name_list = b_list, block_list = glist(),make_copies=False))
|
||||||
for icrsh in xrange(self.n_corr_shells): Gloc[icrsh].zero() # initialize to zero
|
for icrsh in xrange(self.n_corr_shells): Gloc[icrsh].zero() # initialize to zero
|
||||||
|
|
||||||
for ik in xrange(self.n_k):
|
for ik in xrange(self.n_k):
|
||||||
|
|
||||||
Gupf=self.lattice_gf_realfreq(ik=ik,mu=self.chemical_potential,broadening=broadening,beta=beta,mesh=mesh,with_Sigma=False)
|
Gupf=self.lattice_gf_realfreq(ik=ik,mu=self.chemical_potential,broadening=broadening,mesh=(om_min,om_max,n_om),with_Sigma=False)
|
||||||
Gupf *= self.bz_weights[ik]
|
Gupf *= self.bz_weights[ik]
|
||||||
|
|
||||||
# non-projected DOS
|
# non-projected DOS
|
||||||
@ -227,19 +225,19 @@ class SumkLDATools(SumkLDA):
|
|||||||
if (mpi.is_master_node()):
|
if (mpi.is_master_node()):
|
||||||
for bn in self.block_names[self.SO]:
|
for bn in self.block_names[self.SO]:
|
||||||
f=open('DOS%s.dat'%bn, 'w')
|
f=open('DOS%s.dat'%bn, 'w')
|
||||||
for i in range(n_om): f.write("%s %s\n"%(mesh[i],DOS[bn][i]))
|
for i in range(n_om): f.write("%s %s\n"%(om_mesh[i],DOS[bn][i]))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
for ish in range(self.n_inequiv_corr_shells):
|
for ish in range(self.n_inequiv_corr_shells):
|
||||||
f=open('DOS%s_proj%s.dat'%(bn,ish),'w')
|
f=open('DOS%s_proj%s.dat'%(bn,ish),'w')
|
||||||
for i in range(n_om): f.write("%s %s\n"%(mesh[i],DOSproj[ish][bn][i]))
|
for i in range(n_om): f.write("%s %s\n"%(om_mesh[i],DOSproj[ish][bn][i]))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
for i in range(self.corr_shells[self.invshellmap[ish]][3]):
|
for i in range(self.corr_shells[self.invshellmap[ish]][3]):
|
||||||
for j in range(i,self.corr_shells[self.invshellmap[ish]][3]):
|
for j in range(i,self.corr_shells[self.invshellmap[ish]][3]):
|
||||||
Fname = 'DOS'+bn+'_proj'+str(ish)+'_'+str(i)+'_'+str(j)+'.dat'
|
Fname = 'DOS'+bn+'_proj'+str(ish)+'_'+str(i)+'_'+str(j)+'.dat'
|
||||||
f=open(Fname,'w')
|
f=open(Fname,'w')
|
||||||
for iom in range(n_om): f.write("%s %s\n"%(mesh[iom],DOSproj_orb[ish][bn][i,j,iom]))
|
for iom in range(n_om): f.write("%s %s\n"%(om_mesh[iom],DOSproj_orb[ish][bn][iom,i,j]))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
@ -274,7 +272,7 @@ class SumkLDATools(SumkLDA):
|
|||||||
for ish in xrange(self.n_shells)]
|
for ish in xrange(self.n_shells)]
|
||||||
for ish in range(self.n_shells): Gproj[ish].zero()
|
for ish in range(self.n_shells): Gproj[ish].zero()
|
||||||
|
|
||||||
Msh = [x for x in self.Sigma_imp[0].mesh]
|
Msh = [x.real for x in self.Sigma_imp[0].mesh]
|
||||||
n_om = len(Msh)
|
n_om = len(Msh)
|
||||||
|
|
||||||
DOS = {}
|
DOS = {}
|
||||||
@ -287,7 +285,7 @@ class SumkLDATools(SumkLDA):
|
|||||||
for bn in self.block_names[self.SO]:
|
for bn in self.block_names[self.SO]:
|
||||||
dl = self.shells[ish][3]
|
dl = self.shells[ish][3]
|
||||||
DOSproj[ish][bn] = numpy.zeros([n_om],numpy.float_)
|
DOSproj[ish][bn] = numpy.zeros([n_om],numpy.float_)
|
||||||
DOSproj_orb[ish][bn] = numpy.zeros([dl,dl,n_om],numpy.float_)
|
DOSproj_orb[ish][bn] = numpy.zeros([n_om,dl,dl],numpy.float_)
|
||||||
|
|
||||||
ikarray=numpy.array(range(self.n_k))
|
ikarray=numpy.array(range(self.n_k))
|
||||||
|
|
||||||
@ -344,7 +342,7 @@ class SumkLDATools(SumkLDA):
|
|||||||
for j in range(i,self.shells[ish][3]):
|
for j in range(i,self.shells[ish][3]):
|
||||||
Fname = './DOScorr'+bn+'_proj'+str(ish)+'_'+str(i)+'_'+str(j)+'.dat'
|
Fname = './DOScorr'+bn+'_proj'+str(ish)+'_'+str(i)+'_'+str(j)+'.dat'
|
||||||
f=open(Fname,'w')
|
f=open(Fname,'w')
|
||||||
for iom in range(n_om): f.write("%s %s\n"%(Msh[iom],DOSproj_orb[ish][bn][i,j,iom]))
|
for iom in range(n_om): f.write("%s %s\n"%(Msh[iom],DOSproj_orb[ish][bn][iom,i,j]))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
@ -515,39 +513,94 @@ class SumkLDATools(SumkLDA):
|
|||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
def constr_Sigma_ME(self, filename, beta, n_om, orb = 0):
|
def constr_Sigma_real_axis(self, filename, hdf=True, hdf_dataset='SigmaReFreq',n_om=0,orb=0, tol_mesh=1e-6):
|
||||||
"""Uses Data from files to construct a GF object on the real axis."""
|
"""Uses Data from files to construct Sigma (or GF) on the real axis."""
|
||||||
|
|
||||||
|
if not hdf:
|
||||||
|
# read sigma from text files
|
||||||
|
#first get the mesh out of one of the files:
|
||||||
|
if (len(self.gf_struct_solver[orb][0][1])==1):
|
||||||
|
Fname = filename+'_'+self.gf_struct_solver[orb][0][0]+'.dat'
|
||||||
|
else:
|
||||||
|
Fname = filename+'_'+self.gf_struct_solver[orb][0][0]+'/'+str(self.gf_struct_solver[orb][0][1][0])+'_'+str(self.gf_struct_solver[orb][0][1][0])+'.dat'
|
||||||
|
|
||||||
#first get the mesh out of one of the files:
|
R = read_fortran_file(Fname)
|
||||||
if (len(self.gf_struct_solver[orb][0][1])==1):
|
mesh = numpy.zeros([n_om],numpy.float_)
|
||||||
Fname = filename+'_'+self.gf_struct_solver[orb][0][0]+'.dat'
|
try:
|
||||||
else:
|
for i in xrange(n_om):
|
||||||
Fname = filename+'_'+self.gf_struct_solver[orb][0][0]+'/'+str(self.gf_struct_solver[orb][0][1][0])+'_'+str(self.gf_struct_solver[orb][0][1][0])+'.dat'
|
mesh[i] = R.next()
|
||||||
|
sk = R.next()
|
||||||
|
sk = R.next()
|
||||||
|
|
||||||
R = read_fortran_file(Fname)
|
except StopIteration : # a more explicit error if the file is corrupted.
|
||||||
mesh = numpy.zeros([n_om],numpy.float_)
|
raise "SumkLDA.read_Sigma_ME : reading mesh failed!"
|
||||||
try:
|
R.close()
|
||||||
|
|
||||||
|
# check whether the mesh is uniform
|
||||||
|
bin = (mesh[n_om-1]-mesh[0])/(n_om-1)
|
||||||
for i in xrange(n_om):
|
for i in xrange(n_om):
|
||||||
mesh[i] = R.next()
|
assert abs(i*bin+mesh[0]-mesh[i]) < tol_mesh, 'constr_Sigma_ME: real-axis mesh is non-uniform!'
|
||||||
sk = R.next()
|
|
||||||
sk = R.next()
|
|
||||||
|
|
||||||
except StopIteration : # a more explicit error if the file is corrupted.
|
# construct Sigma
|
||||||
raise "SumkLDA.read_Sigma_ME : reading file failed!"
|
a_list = [a for a,al in self.gf_struct_solver[orb]]
|
||||||
R.close()
|
glist = lambda : [ GfReFreq(indices = al, window=(mesh[0],mesh[n_om-1]),n_points=n_om) for a,al in self.gf_struct_solver[orb]]
|
||||||
|
SigmaME = BlockGf(name_list = a_list, block_list = glist(),make_copies=False)
|
||||||
|
|
||||||
# now initialize the GF with the mesh
|
#read Sigma
|
||||||
a_list = [a for a,al in self.gf_struct_solver[orb]]
|
|
||||||
glist = lambda : [ GfReFreq(indices = al, beta = beta, mesh_array = mesh) for a,al in self.gf_struct_solver[orb] ]
|
for i,g in SigmaME:
|
||||||
SigmaME = BlockGf(name_list = a_list, block_list = glist(),make_copies=False)
|
mesh=[w for w in g.mesh]
|
||||||
SigmaME.load(filename)
|
for iL in g.indices:
|
||||||
|
for iR in g.indices:
|
||||||
|
if (len(g.indices) == 1):
|
||||||
|
Fname = filename+'_%s'%(i)+'.dat'
|
||||||
|
else:
|
||||||
|
Fname = 'SigmaME_'+'%s'%(i)+'_%s'%(iL)+'_%s'%(iR)+'.dat'
|
||||||
|
R = read_fortran_file(Fname)
|
||||||
|
try:
|
||||||
|
for iom in xrange(n_om):
|
||||||
|
sk = R.next()
|
||||||
|
rsig = R.next()
|
||||||
|
isig = R.next()
|
||||||
|
g.data[iom,iL,iR]=rsig+1j*isig
|
||||||
|
except StopIteration : # a more explicit error if the file is corrupted.
|
||||||
|
raise "SumkLDA.read_Sigma_ME : reading Sigma from file failed!"
|
||||||
|
R.close()
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
# read sigma from hdf
|
||||||
|
omega_min=0.0
|
||||||
|
omega_max=0.0
|
||||||
|
n_om=0
|
||||||
|
if (mpi.is_master_node()):
|
||||||
|
ar = HDFArchive(filename)
|
||||||
|
SigmaME = ar[hdf_dataset]
|
||||||
|
del ar
|
||||||
|
# we need some parameters to construct Sigma on other nodes
|
||||||
|
omega_min=SigmaME.mesh.omega_min
|
||||||
|
omega_max=SigmaME.mesh.omega_max
|
||||||
|
n_om=len(SigmaME.mesh)
|
||||||
|
omega_min=mpi.bcast(omega_min)
|
||||||
|
omega_max=mpi.bcast(omega_max)
|
||||||
|
n_om=mpi.bcast(n_om)
|
||||||
|
mpi.barrier()
|
||||||
|
# construct Sigma on other nodes
|
||||||
|
if (not mpi.is_master_node()):
|
||||||
|
a_list = [a for a,al in self.gf_struct_solver[orb]]
|
||||||
|
glist = lambda : [ GfReFreq(indices = al, window=(omega_min,omega_max),n_points=n_om) for a,al in self.gf_struct_solver[orb]]
|
||||||
|
SigmaME = BlockGf(name_list = a_list, block_list = glist(),make_copies=False)
|
||||||
|
# pass SigmaME to other nodes
|
||||||
|
SigmaME = mpi.bcast(SigmaME)
|
||||||
|
mpi.barrier()
|
||||||
|
|
||||||
|
SigmaME.note='ReFreq'
|
||||||
|
|
||||||
return SigmaME
|
return SigmaME
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def partial_charges(self,beta=40):
|
def partial_charges(self,beta=40):
|
||||||
"""Calculates the orbitally-resolved density matrix for all the orbitals considered in the input.
|
"""Calculates the orbitally-resolved density matrix for all the orbitals considered in the input.
|
||||||
The theta-projectors are used, hence case.parproj data is necessary"""
|
The theta-projectors are used, hence case.parproj data is necessary"""
|
||||||
@ -622,4 +675,3 @@ class SumkLDATools(SumkLDA):
|
|||||||
return dens_mat
|
return dens_mat
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user