From 41b3b637441ade3a5ba32de468c27748998ac6a0 Mon Sep 17 00:00:00 2001 From: "Oleg E. Peil" Date: Fri, 11 Dec 2015 10:54:51 +0100 Subject: [PATCH] Modified input of eigenvalues and Fermi weights In the new version of VASP LOCPROJ contains the eigenvalues and Fermi weights. Also, during a charge self-consistency calculation the file EIGENVAL is not written at intermediate iterations. It is, thus, preferential to use LOCPROJ to get the named data. At the moment, EIGENVAL will still be used if it is complete but in the future this dependence should be removed completely. --- python/converters/plovasp/elstruct.py | 36 +++++++++++++--------- python/converters/plovasp/vaspio.py | 44 ++++++++++++++++++++------- 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/python/converters/plovasp/elstruct.py b/python/converters/plovasp/elstruct.py index 0131ba83..c90c92ee 100644 --- a/python/converters/plovasp/elstruct.py +++ b/python/converters/plovasp/elstruct.py @@ -36,7 +36,7 @@ class ElectronicStructure: self.kmesh = {'nktot': self.nktot} self.kmesh['kpoints'] = vasp_data.kpoints.kpts - self.kmesh['kweights'] = vasp_data.eigenval.kwghts + self.kmesh['kweights'] = vasp_data.kpoints.kwghts try: self.kmesh['ntet'] = vasp_data.kpoints.ntet self.kmesh['itet'] = vasp_data.kpoints.itet @@ -51,34 +51,40 @@ class ElectronicStructure: # Note that the number of spin-components of projectors might be different from those # of bands in case of non-collinear calculations - self.nspin = vasp_data.eigenval.ispin + self.nspin = vasp_data.plocar.nspin self.nc_flag = vasp_data.doscar.ncdij == 4 - self.nband = vasp_data.eigenval.nband + self.nband = vasp_data.plocar.nband - self.eigvals = vasp_data.eigenval.eigs +# Check that the number of k-points is the same in all files + _, ns_plo, nk_plo, nb_plo = vasp_data.plocar.plo.shape + assert nk_plo == self.nktot, "PLOCAR is inconsistent with IBZKPT (number of k-points)" + + if not vasp_data.eigenval.eigs is None: + print "eigvals from EIGENVAL" + self.eigvals = vasp_data.eigenval.eigs + self.ferw = vasp_data.eigenval.ferw.transpose((2, 0, 1)) + + nk_eig = vasp_data.eigenval.nktot + assert nk_eig == self.nktot, "PLOCAR is inconsistent with EIGENVAL (number of k-points)" + +# Check that the number of band is the same in PROJCAR and EIGENVAL + assert nb_plo == self.nband, "PLOCAR is inconsistent with EIGENVAL (number of bands)" + else: + print "eigvals from LOCPROJ" + self.eigvals = vasp_data.plocar.eigs + self.ferw = vasp_data.plocar.ferw.transpose((2, 0, 1)) # For later use it is more convenient to use a different order of indices # [see ProjectorGroup.orthogonalization()] self.proj_raw = vasp_data.plocar.plo self.proj_params = vasp_data.plocar.proj_params - self.ferw = vasp_data.eigenval.ferw.transpose((2, 0, 1)) - # Not needed any more since PROJCAR contains projectors only for a subset of sites # Check that the number of atoms is the same in PLOCAR and POSCAR # natom_plo = vasp_data.plocar.params['nion'] # assert natom_plo == self.natom, "PLOCAR is inconsistent with POSCAR (number of atoms)" -# Check that the number of k-points is the same in all files - _, ns_plo, nk_plo, nb_plo = vasp_data.plocar.plo.shape - assert nk_plo == self.nktot, "PLOCAR is inconsistent with IBZKPT (number of k-points)" - nk_eig = vasp_data.eigenval.nktot - assert nk_eig == self.nktot, "PLOCAR is inconsistent with EIGENVAL (number of k-points)" - -# Check that the number of band is the same in PROJCAR and EIGENVAL - assert nb_plo == self.nband, "PLOCAR is inconsistent with EIGENVAL (number of bands)" - def debug_density_matrix(self): """ Calculate and output the density and overlap matrix out of projectors defined in el_struct. diff --git a/python/converters/plovasp/vaspio.py b/python/converters/plovasp/vaspio.py index eb58e261..10b4cb4b 100644 --- a/python/converters/plovasp/vaspio.py +++ b/python/converters/plovasp/vaspio.py @@ -53,7 +53,13 @@ class VaspData: self.plocar.from_file(vasp_dir) self.poscar.from_file(vasp_dir) self.kpoints.from_file(vasp_dir) - self.eigenval.from_file(vasp_dir) + try: + self.eigenval.from_file(vasp_dir) + except (IOError, StopIteration): + self.eigenval.eigs = None + self.eigenval.ferw = None + print "!!! WARNING !!!: Error reading from EIGENVAL, trying LOCPROJ" + pass self.doscar.from_file(vasp_dir) ################################################################################ @@ -196,9 +202,9 @@ class Plocar: with open(locproj_filename, 'rt') as f: line = f.readline() line = line.split("#")[0] - nspin, nk, nband, nproj = map(int, line.split()) + self.nspin, nk, self.nband, nproj = map(int, line.split()) - plo = np.zeros((nproj, nspin, nk, nband), dtype=np.complex128) + plo = np.zeros((nproj, self.nspin, nk, self.nband), dtype=np.complex128) proj_params = [{} for i in xrange(nproj)] iproj_site = 0 @@ -225,16 +231,23 @@ class Plocar: assert ip == nproj, "Number of projectors in the header is wrong in LOCPROJ" -# TODO: one can read eigenvalues and Fermi weights from lines starting with "orbital" -# at the moment we ignore them + self.eigs = np.zeros((nk, self.nband, self.nspin)) + self.ferw = np.zeros((nk, self.nband, self.nspin)) + patt = re.compile("^orbital") - for ispin in xrange(nspin): + for ispin in xrange(self.nspin): for ik in xrange(nk): - for ib in xrange(nband): + for ib in xrange(self.nband): + line = "" + while not line: + line = f.readline().strip() + sline = line.split() + isp_, ik_, ib_ = map(int, sline[1:4]) + assert isp_ == ispin + 1 and ik_ == ik + 1 and ib_ == ib + 1, "Inconsistency in reading LOCPROJ" + self.eigs[ik, ib, ispin] = float(sline[4]) + self.ferw[ik, ib, ispin] = float(sline[5]) for ip in xrange(nproj): - line = "" - while not line or not re.match(patt, line) is None: - line = f.readline().strip() + line = f.readline() sline = line.split() ctmp = complex(float(sline[1]), float(sline[2])) plo[ip, ispin, ik, ib] = ctmp @@ -432,12 +445,17 @@ class Kpoints: print " {0:>26} {1:d}".format("Total number of k-points:", self.nktot) self.kpts = np.zeros((self.nktot, 3)) + self.kwghts = np.zeros((self.nktot)) # Skip comment line line = ibz_file.next() for ik in xrange(self.nktot): line = ibz_file.next() - self.kpts[ik, :] = map(float, line.strip().split()[:3]) + sline = line.strip().split() + self.kpts[ik, :] = map(float, sline[:3]) + self.kwghts[ik] = float(sline[3]) + + self.kwghts /= self.nktot # Attempt to read tetrahedra # Skip comment line ("Tetrahedra") @@ -481,6 +499,10 @@ class Eigenval: """ Class containing Kohn-Sham-eigenvalues data from VASP (EIGENVAL file). """ + def __init__(self): + self.eigs = None + self.ferw = None + def from_file(self, vasp_dir='./', eig_filename='EIGENVAL'): """ Reads eigenvalues from EIGENVAL. Note that the file also