Esempio n. 1
0
def yaeh_ReadBand(stFileName):
    '''
    Read k-points and band from yaeh band result.
    Fermi energy is not calculated.
    @todo spin is always 1
    '''
    f = open(stFileName)
    ar_stLine = f.readlines()

    list_kp = []
    list_band = []

    nbnd = int(ar_stLine[4].split()[0])  #Number of bands in each kpt
    nStart = 0  #Start position of band data
    for i in range(0, len(ar_stLine)):
        if ("Begin band data" in ar_stLine[i]):
            nStart = i + 1  #line count that not band data
            break

    for i in range(0, (len(ar_stLine) - nStart) / (nbnd + 1)):
        i2 = (nbnd + 1) * i + nStart
        list_kp.append([float(x) for x in ar_stLine[i2][10:].split()])
        list_band.append([float(x) for x in ar_stLine[i2 + 1:i2 + nbnd + 1]])

    #write
    aKPT = KPointsT()
    aKPT.ReadFromList(list_kp)

    #   return aKPT,list_band,0,0,0
    band = BandsT(aKPT, list_band)
    band.num_spin = 1
    return band
Esempio n. 2
0
def bdf_read_band(filename):
    '''
    Read a band structure from bdf output
    '''
    f = open(filename)
    #Read reciporocal vectors
    lines = f.readlines()
    f.close()
    mK = [[float(y) for y in x.split()[1:4]] for x in lines[2:5]]
    eig_fermi = float(lines[6].split()[-1])
    print(eig_fermi)
    list_kpt = []
    list_eig = []
    for line in lines[7:]:
        ar = line.split()
        #"A" is marked as non-special k-points
        if (ar[1] == "A"):
            ar[1] = ""
        list_kpt.append(ar[1:2] + [float(x) for x in ar[2:5]] + [1.0])
        list_eig.append([float(x) for x in ar[5:]])
    kpt = KPointsT()
    kpt.stMode = "crystal"
    kpt.ReadFromList(list_kpt)
    kpt.ConvertUnit("cart", mLatt=f_GetReciprocalLattice(mK))
    band = BandsT(kpt, list_eig, eig_fermi, eig_fermi)
    band.b_metal = True  #Just set to plot fermi
    return band
Esempio n. 3
0
def read_eigs(filename):
    '''
    Read eigenvalues only as a band structure
    '''
    list_eig = f_Data_ReadMultiCol(filename, func=float)
    kpt = KPointsT()
    kpt.listKPt = [["", 0, 0, x, 0] for x in xrange(len(list_eig))]
    band = BandsT(kpt=kpt, list_eig=list_eig)
    return band
Esempio n. 4
0
def abi_ReadBand_EIG(stFileName):
    '''
    Read band structure from _EIG file
    '''
    f = open(stFileName)
    stLine = f.readline()
    if ("hartree" in stLine):  # "(hartree) ="
        energy_unit = Ha2eV
    else:
        energy_unit = 1.0  # energy unit; if it is hartree then convert to eV
    if ("Fermi" in stLine):  # Find the first equal
        ixEqual = stLine.index("=")
        dFermi = float(stLine[ixEqual + 1:ixEqual + 10])
        stLine = f.readline()
    else:
        dFermi = None
    nKPt = int(stLine[32:36])
    listKPt = []
    listBand = []
    listB1 = []
    #    for i in xrange(0,nKPt):
    while True:
        stLine = f.readline()
        if not stLine:
            break
        stLine = stLine[:-1]  #Remove \cr for splitting
        if ("kpt" in stLine):
            listKPt.append([
                float(stLine[41:49]),
                float(stLine[49:57]),
                float(stLine[58:65]),
                float(stLine[26:35])
            ])
            if (len(listB1) > 0):
                listBand.append(listB1)
            listB1 = []
        else:
            #To avoid two maximum length float recognized as one
            #           listB1 += [float(x) if not "*" in x else 0.0 * energy_unit for x in stLine.split()]
            n = 10
            listB1 += [
                float(x) if not "*" in x else 0.0
                for x in [stLine[i:i + n] for i in xrange(0, len(stLine), n)]
            ]
    #Find band
    listBand.append(listB1)

    aKPt = KPointsT()
    aKPt.ReadFromList(listKPt)

    #   return aKPt, listBand, dFermi, None, 1
    return BandsT(aKPt, listBand, dFermi, None, None, 1)
Esempio n. 5
0
    def load(self,st_program):
        '''
        Load external content with given parameters
        Note : the program-related input object should be initilized manually
        '''
        self.st_program = st_program
#Customize
        if (st_program == "tbgwpw"):
           self.calcIn = TBGWInput(self.stInputFile)
           self.calcIn.b_warn_write = False
        elif (st_program == "yaeh" or st_program == "yaehg"):
            self.calcIn = yaeh_input(self.stInputFile)

#End Customize

        self.bandRef = f_Band_ReadFromFile(self.stBandRefFile)
        self.listBandWeight = [0.001 for x in range(0,self.nBandStartIndex)] + [ 1.0 for x in range(self.nBandStartIndex,self.nBandStartIndex+self.nBandFitCount)]
        #Additional weight for VBM and CBM if range we considered include VBM and CBM 
        if ( len(self.listBandWeight) >= self.nElectron /2 + 1):
            print("Unoccupied states included in calculation, use different weight for H**O and LUMO")
            if ( self.dBandHighWeight == None):
                self.dBandHighWeight = 10
            for i in xrange(0,-self.nBandHighVB):
                self.listBandWeight[self.nElectron/2-1-i] = self.dBandHighWeight
            for i in xrange(0, self.nBandHighCB):
                self.listBandWeight[self.nElectron/2] = self.dBandHighWeight - self.dCBMLessWeight 

        if ( self.nBandTotal == None): #Not specified
            #Additional very small weight to make result not fluctuate too much
            self.listBandWeight.append(0.001)
        else:
            #Add all additional band to make result stabilize
            self.listBandWeight = self.listBandWeight + [0.001 for x in range(0,self.nBandTotal-len(self.listBandWeight))]

        self.dVBMRef = f_Band_GetVBMFromElectron(self.bandRef,self.nElectron)
        self.dGapRef,dt,nt = f_Band_GetGap(self.bandRef,self.dVBMRef,False)

#Use weights 
        if (self.bUseKPtWeight):
            self.band = BandsT.load_xml(self.stDataRefFile)
            self.listKPtWeight = [kpt[4] for kpt in self.band.kpt.listKPt]
#Normalize to each k, each band = 1
            d_total = sum(self.listKPtWeight)
            n_len = len(self.listKPtWeight)
            self.listKPtWeight = [ x / d_total * n_len for x in self.listKPtWeight]
Esempio n. 6
0
def abi_ReadBand_GW(stFileName):
    '''
    Read band structure from _GW file
    '''
    f = open(stFileName)
    nKPt, nSpin = [int(x) for x in f.readline().split()]
    listKPt = []
    listBand = []
    for i in xrange(0, nKPt):
        listKPt.append([float(x) for x in f.readline().split()])
        n = int(f.readline())
        listB = []
        for j in xrange(0, n):
            listB.append(float(f.readline().split()[1]))
        listBand.append(listB)

    aKPt = KPointsT()
    aKPt.ReadFromList(listKPt)

    #   return aKPt, listBand, None, None, nSpin
    return BandsT(aKPt, listBand, None, None, None, nSpin)
Esempio n. 7
0
def uni_ReadBand(stProgram="auto", para=[]):
    '''
    Read band structure from specific program result
    :param stProgram: program name, "auto" means automatically detected
    :param para: arguments for specific programs
    :return: BandsT object
    '''
    #   :param nElectron: electron number, default 0. If specified, then VBM will be calculated for plot
    #   :param bPlot: Whether plot bandstructure
    #   :param bAlign: Whether shift band energy to make VBM = 0 in plot
    #    :return:  k-points,eigenvalues,VBM,Electron count,Spin count
    #    '''

    stProgram = uni_Package_Detect(stProgram, para)

    dicFunc = {\
            "auto":[(0,),None],\
            "w2k":[(0,1,),w2k_ReadBand],\
            "yaeh":[(1,),yaeh_ReadBand],\
            "siesta":[(3,),siesta_read_band],\
            "vasp":[(0,),vasp_ReadBand],\
            "vasp_out":[(1,),vasp_ReadBand],\
            "qe":[(1,), qesp_read_band],\
            "abinit":[(2,),abi_ReadBand],\
            "gap":[(1,),w2k_ReadBand],\
            "w90":[(1,),wann_read_band],\
            "bdf":[(1,),bdf_read_band],\
            "yambo":[(1,2,),yambo_read_band],\
            "raw":[(1,),lambda x:BandsT(dirname=x)],\
            "band":[(1,),read_eigs]\
            }

    if (not dicFunc.has_key(stProgram)):
        raise ValueError, "Package %s is not supported!" % stProgram

    if (not len(para) in dicFunc[stProgram][0]):
        raise ValueError, "incorrect number of arguments : %i" % len(para)

    #(aKPt,listBand,dVBM) = dicFunc[stProgram][1](*para)
    return dicFunc[stProgram][1](*para)
Esempio n. 8
0
def siesta_read_band(stFDFFileName, stOutputfile, stBandFileName):
    '''
    Read band structure of siesta
    Number of electrons is deduced from fermi energy, which may give wrong value when system is a metal
    @todo when spin=2 , two bands does not seperate
    '''

    dicScale = {"pi/a": "piba", "ReciprocalLatticeVectors": "crystal"}

    aKPt = KPointsT()

    f = open(stFDFFileName)
    list_stLine = f.readlines()
    nInfoLine = 0  #The information line in .bands file is 3 if BandLines is used, 2 if BandPoints is used
    f.close()
    for i in range(0, len(list_stLine)):
        stLine = list_stLine[i].strip()
        if (len(stLine) == 0):  #Skip empty line
            continue
        if (stLine[0] == '#'):  #Skip comments
            continue
        if ("BandLinesScale " in stLine):
            aKPt.stMode = dicScale[stLine.split()[1]]
        if ("%block BandLines" in stLine):
            j = 1
            listPt = []
            listCount = []
            arLine = list_stLine[i + j].split()
            while (not "%endblock" in arLine[0]):
                listPt.append(arLine[1:])
                listCount.append(int(arLine[0]))
                j += 1
                arLine = list_stLine[i + j].split()
            aKPt.CreateFromPointLine(listPt, listCount[1:])
            nInfoLine = 3
            break
        elif ("%block BandPoints" in stLine):
            j = 1
            listPt = []
            arLine = list_stLine[i + j].split()
            while (not "%endblock" in arLine[0]):
                listPt.append([float(x) for x in arLine[:3]])
                j += 1
                arLine = list_stLine[i + j].split()
            aKPt.ReadFromList(listPt)
            nInfoLine = 2
            break

    #Convert aKPt to tpiba mode data if it is piba
    if (aKPt.stMode == "piba"):
        aKPt.stMode = "tpiba"
        for ar in aKPt.listKPt:
            ar[1:4] = [x * 0.5 for x in ar[1:4]]

    nElectron = siesta_read_electron(stOutputfile)

    #read band structure
    f = open(stBandFileName)
    list_stLine = f.readlines()
    f.close()

    fFermi = float(list_stLine[0])
    (nBand, nSpin, nKPt) = [int(x) for x in list_stLine[nInfoLine].split()]

    if (nKPt != len(aKPt.listKPt)):
        raise ValueError, "k-points in %s and %s are not same!" % (
            stFDFFileName, stBandFileName)

    listBand = []
    (dVBM, fCBM) = [float(x) for x in list_stLine[nInfoLine - 1].split()]

    #read energy until the count of energy reaches nBand
    arLine = []
    i = nInfoLine + 1
    nSkip = 1 if nInfoLine == 3 else 3  # Skip first term( band line) if BandLines is used, Skip first three term (k-pt coord) if BandPoints is used
    delta = 0.0002
    #nHOIndex = -1
    while (len(listBand) < nKPt):
        arLineNow = [float(x) for x in list_stLine[i].split()
                     ]  #the first 10 is preserved for k-point coordinate
        if (len(arLine) != 0):  #a start one k-point
            arLine += arLineNow
        else:
            arLine = arLineNow[nSkip:]


#Cut
        if (len(arLine) == nBand * nSpin):  #Read one k-point end
            listBand.append(arLine)
            dVBM = max([x for x in arLine if x < fFermi + delta] + [dVBM])
            fCBM = min([x for x in arLine if x > fFermi - delta] + [fCBM])
            arLine = []
            #if ( dVBM in listBand[-1]):
            #nHOIndex = listBand[-1].index(dVBM)
            #print("VBM:%i %f" % ( nHOIndex,dVBM))

        i += 1

    #use VBM as zero point; if either VBM or CBM is very close to fFermi, then use fFermi
    if (abs(dVBM - fFermi) < delta / 2 or abs(fCBM - fFermi) < delta / 2):
        dVBM = fFermi

    print("Detect VBM from SIESTA Fermi: %f" % dVBM)

    #    return aKPt,listBand,dVBM,nElectron,nSpin
    return BandsT(aKPt, listBand, dVBM, None, nElectron, nSpin)
Esempio n. 9
0
def Main(ArgList):
    description = '''Plot band strcture of specific package in specific format, also create plain tabular seperated text of band structure data and k-points list.
    File required:
        SIESTA : .fdf , stdout, .bands
        VASP : none, require to run in the case folder
        WIEN2K :  none , require to run in the case folder
        FHI-GAP : energy file name suffix (_gw-band or _gw0-band) , require to run in the WIEN2k case folder
        QE : data-file.xml in the save folder, or pw.x output
        ABINIT : _EIG output or _GW output
        Wannier90: _w90_band.dat file ( other files are necessary but will be selected according to this file name)
        Yambo : o-*.qp file
        RAW: folder name contains all files generated by %prog 
    By default, output folder is current folder, so it is sugguested to run this in an empty folder to avoid overwritten as it will create plenty of files.
    Band characteres can also be plotted. To do this add "--plotinfo File". The input file contains extra format informations.
    '''
    parser = ArgumentParser(description=description,
                            formatter_class=RawDescriptionHelpFormatter)

    parser.add_argument("extra_args",
                        type=str,
                        nargs="*",
                        help="Arguments passed to package-specific procedures")
    parser.add_argument("-i",
                        dest="Program",
                        default="auto",
                        help="The package name")
    parser.add_argument("-g",
                        dest="Align",
                        default=False,
                        action="store_true",
                        help="Shift band position to make VBM = 0 in graph")
    parser.add_argument(
        "--electron",
        dest="Electron",
        default="0",
        help=
        "The number of electrons in the system of the band structure. This is used to determine VBM/Fermi energy. If not specified, this program will try to find from input files"
    )
    parser.add_argument(
        "-s",
        dest="FormatOnly",
        default=False,
        action="store_true",
        help=
        "Do not plot band structure, just write band structure data and k-point list in space-seperated format"
    )
    parser.add_argument("-d",
                        dest="OutputDir",
                        default="band",
                        help="The name of folder used to store output files")
    parser.add_argument(
        "-k",
        dest="KPointsUnit",
        default="cart",
        help=
        "The unit of k-points in the output, also determine x-axis distance. Possible options include 'cart','crystal' and 'default', where default means use what the program read."
    )
    parser.add_argument(
        "-f",
        dest="ForceOverwrite",
        default=False,
        action="store_true",
        help=
        "Control whether to overwrite if the output directory already exists, default is not "
    )
    parser.add_argument(
        "--cross",
        dest="ResolveCorssing",
        default=False,
        action="store_true",
        help="Contrl whether to resolving band-crossing by derivatives")
    parser.add_argument(
        "--plotinfo",
        dest="FilePlotInfo",
        default=None,
        help=
        "The input file for plotting parameters, include band structure with band characters indicated"
    )
    parser.add_argument(
        "--copyk",
        dest="CopyKPoints",
        default=None,
        help=
        "Copy k-points information from given band.xml, instead of use what is read. This to make two plots have the same x-coord"
    )
    parser.add_argument(
        "--removek",
        dest="RemoveKPoints",
        type=int,
        default=0,
        help=
        "Remove the first N k-points in the bandstructure, especially useful when plotting HSE / metaGGA bands that must be calculated with full M-P k-points self-consistently"
    )
    parser.add_argument(
        "--kname",
        dest="NameK",
        default=None,
        help=
        "Provide a list of names of k-points that will be plotted, in format \" 1 Gamma 30 X 50 L\", indicies start from 1, this works before --removek"
    )
    parser.add_argument(
        "--alignenergy",
        dest="AlignEnergy",
        default=None,
        help=
        "Manually specify the energy to align instead of using VBM/Fermi energy automatically read. The unit must be the same as what the package outputs."
    )

    options = parser.parse_args()

    stProgram = uni_Package_Detect(options.Program, options.extra_args)
    band = uni_ReadBand(stProgram, options.extra_args)
    #Read k-points
    if (options.CopyKPoints is not None):
        band_copyk = BandsT.load_xml(options.CopyKPoints)
        band.kpt = band_copyk.kpt

    if (options.NameK is not None):
        list_name = options.NameK.split()
        for i in xrange(len(list_name) / 2):
            ix1 = int(list_name[i * 2]) - 1
            name1 = list_name[i * 2 + 1]
            band.kpt.listKPt[ix1][0] = name1

#Read character informations
    info_plot = None
    if (options.FilePlotInfo is not None):
        with open(options.FilePlotInfo) as f:
            info_plot = json.loads(f.read())
        if (info_plot.has_key("orb_map")):
            list_orb, list_character = uni_read_band_character(stProgram)
            if (stProgram == "w2k"):  #Wien2K qtl is not good for plotting
                list_character = w2k_rescale_character(band.list_orb,
                                                       band.list_character)
#Add to band object
            for prop, orb, character in zip(band.prop, list_orb,
                                            list_character):
                prop.orb = orb
                prop.character = character

#Remove extra k-points
    if (options.RemoveKPoints > 0):
        band = f_band_remove_k(band, options.RemoveKPoints)

#Resolving crossing
    if (options.ResolveCorssing):
        band.resolve_crossing()

#Unit conversion
    unit_k = options.KPointsUnit.lower()
    if (unit_k != "default" and band.kpt.stMode != unit_k):
        print("Convert k-point unit from %s to %s" % (band.kpt.stMode, unit_k))
        #band.kpt.ConvertUnit(unit_k,band.kpt.latt.PrimitiveCellVector)
        band.kpt.ConvertUnit(unit_k)

    nElectronInput = int(options.Electron)
    if (nElectronInput != 0):
        band.num_electron = nElectronInput

#Align energy
    if (options.AlignEnergy is not None):
        e1 = float(options.AlignEnergy)
        band.fermi = e1
        band.vbm = e1


#   f_Band_Analyse(listBand)
    band.show_info((
        band.fermi if band.b_metal else band.vbm) if options.Align else None)

    #   f_Band_SaveData(aKPt,listBand,dVBM,options.OutputDir,nElectron,not options.FormatOnly,options.Align)
    if (os.path.exists(options.OutputDir) and not options.ForceOverwrite):
        print(
            "Warning:Directory %s already exists, band structure information will not be saved!"
            % options.OutputDir)
        return

    band.save(options.OutputDir,
              b_plot=not options.FormatOnly,
              align=BandsT.align_auto if options.Align else BandsT.align_none,
              plotinfo=info_plot)
Esempio n. 10
0
def vasp_ReadBand(stFileName="EIGENVAL",filetype=None):
    '''
    Read k-point and band from vasp EIGENVAL file or OUTCAR file
    WARNING: EIGENVAL does not handle non-integer electrons! Use OUTCAR or vasprun.xml if it is that case
    Note the structure is always read from vasprun.xml

    Another problem is the occuptation numbers are 1 in vasprun.xml  and 2 in OUTCAR, if spin unpolarized

    :param stFileName: the file to read bandstructure
    :param filetype: the file type to read, can be OUTCAR or EIGENVAL. Automatically inferred from stFileName if set to None
    '''
    if (filetype is None):
        if ("EIGENVAL" in stFileName):
            filetype = "EIGENVAL"
        elif ("vasprun.xml" in stFileName):
            filetype = "vasprun.xml"
        else:
            filetype = "OUTCAR"

    f = open(stFileName)
    ar_stLine = f.readlines()
    f.close()

    list_kp = []
    list_band = []
    list_band2 = []
    list_occ = None
    bElectronFraction = False

    if (filetype == "EIGENVAL"):
#Note we cannot determine LNONCOLLINEAR in EIGENVAL, assume false
        b_noncoll = False

        num_spin = int(ar_stLine[0].split()[3])

        (nElectron,nKPt,nbnd) = [int(x) for x in ar_stLine[5].split()]

        for i in range(0,nKPt):
            i2 = i * (nbnd+2) + 7
            list_kp.append([float(x) for x in ar_stLine[i2].split()])
            ar2 =[x.split() for x in ar_stLine[i2+1:i2+nbnd+1]]
            list_band.append([float(x[1]) for x in ar2])
            if (num_spin == 2):
                list_band2.append([float(x[2]) for x in ar2])
        if (num_spin == 2):
            list_band = [list_band,list_band2]
    elif (filetype == "OUTCAR"):

        def read_tag(tag, i0):
            val = None
            for i in xrange(i0, len(ar_stLine)):
                line = ar_stLine[i]
                if (tag in line):
                    val = line.split()[2]
                    break
            if (val is None):
                raise ValueError("Cannot find tag %s" % tag)

            return val, i


        list_occ = []
        list_occ2 = []

        i = 0
        num_spin, i = read_tag("ISPIN", i)
        num_spin = int(num_spin)
        b_noncoll, i = read_tag("LNONCOLLINEAR", i)
        b_noncoll = b_noncoll == "T"
        nElectron, i = read_tag("NELECT", i)
        dElectron = float(nElectron)
        nElectron = int(dElectron)
        bElectronFraction = abs(dElectron != nElectron) > 1e-7
#       if (bElectronFraction):
#           print("The number of electrons is not an integer.")

        efermi, i = read_tag("E-fermi", i)
        efermi = float(efermi)
        i += 2
        if (num_spin != 1):
            i += 2
        list_band_now = list_band
        list_occ_now = list_occ
        while (len(ar_stLine[i+1])>4):
            i += 1
            if (list_band_now == list_band):
                list_kp.append([float(x) for x in ar_stLine[i].split()[-3:]])
            i += 2
            ar2 = []
            ar_occ = []
            line = ar_stLine[i]
            while (len(line) > 4):
                ar_line = line.split()
                ar2.append(float(ar_line[1]))
                ar_occ.append(float(ar_line[2]))
                i += 1
                line = ar_stLine[i]
            list_band_now.append(ar2)
            list_occ_now.append(ar_occ)
            if (num_spin != 1 and "spin" in ar_stLine[i+1]):
                list_band_now = list_band2
                list_occ_now = list_occ2
                i += 2

        nKPt = len(list_band)
        nbnd = len(list_band[0])
#       print(nElectron, nKPt, nbnd)
        if (num_spin == 2):
            list_band = [list_band, list_band2]
            list_occ = [list_occ, list_occ2]
    elif (filetype == "vasprun.xml"):
#Read from vasprun.xml
        for event, elem in ET.iterparse(stFileName,events=('end',)):
            if (elem.tag == "parameters"):
                node_parameters = elem
            elif (elem.tag == "eigenvalues"):
                node_eigenvalues = elem
            elif (elem.tag == "kpoints"):
                node_kpoints = elem
            elif (elem.tag == "dos"):
                node_dos = elem 
                break

#Read LNONCOLLINEAR
        b_noncoll = node_parameters.find('./separator[@name="electronic"]/separator[@name="electronic spin"]/i[@name="LNONCOLLINEAR"]').text
        b_noncoll = b_noncoll.strip() == "T"

#Read NELECT
        
        dElectron = float(node_parameters.find('./separator[@name="electronic"]/i[@name="NELECT"]').text)
        nElectron = int(dElectron)
        bElectronFraction = abs(dElectron != nElectron) > 1e-7

#Read band
        node_band = node_eigenvalues
        list_band = []
        list_occ = []
        list_occ2 = []
#3-level nested , hard to read so split them
        for node1 in node_band.findall("./array/set/set"): #Spin
            band_spin = []
            occ_spin = []
            for node2 in node1.findall("./set"): #Kpt
                data_kpt = [node3.text.split() for node3 in node2.findall("./r")]
                band_spin.append([float(x[0]) for x in data_kpt])
                occ_spin.append([float(x[1]) for x in data_kpt])
            list_band.append(band_spin)
            list_occ.append(occ_spin)
#       list_band = reduce(lambda x,y: x+y, list_band)
#       list_occ = reduce(lambda x,y: x+y, list_occ)
#Read kpoints coordinates
        list_kp = [[float(x) for x in nodek.text.split()] for nodek in node_kpoints.findall('./varray[@name="kpointlist"]/v')]

#Read other properties
        num_spin = int(node_parameters.find('./separator[@name="electronic"]/separator[@name="electronic spin"]/i[@name="ISPIN"]').text)
        efermi = float(node_dos.find('./i[@name="efermi"]').text)
#Do not use array for each spin if only 1 spin
        if (num_spin == 1):
            list_band = list_band[0]
            list_occ = list_occ[0]

    aKPT = KPointsT()
    aKPT.ReadFromList(list_kp)
    aKPT.stMode = "crystal"
    
    #OUTCAR is not necasseary, it is used to convert k-point unit
    try:
        latt = vasp_read_latt("initialpos","vasprun.xml")
    except ET.ParseError:
        matR,matK = vasp_ReadLattVec("OUTCAR")
        latt = Lattice()
        latt.ReadFromRawCellVector(matR)

    aKPT.latt = latt

#   aKPT.ConvertUnit("cart",matR)
    aKPT.ConvertUnit("cart")

#Each band is assumed to be double occupied in BandsT
#So we use 2 times electron in NONCOLLINEAR where only single occupied
    if (b_noncoll):
        print("Noncollinear calculation, band.electron = 2*actual electrons")
        nElectron *= 2 

    band = BandsT(aKPT,list_band,None,None,nElectron,num_spin, list_occ=list_occ)

    #Calculate VBM
#Only do if the number of electrons is an integer
    if (bElectronFraction):
        band.fermi = efermi
    else:
        if (not band.guess_vbm()):
            band.fermi = vasp_getout("efer")
    

#   return aKPT,list_band,dVBM,nElectron,1
    return band
Esempio n. 11
0
def yambo_read_band(filename, filename_pw_xml=None):
    '''
    Read band structure from yambo o-*.qp file
    Additional data-file.xml can be used to indicate information
    Lattice is a fake and not used
    '''
    with open(filename, 'r') as f:
        lines = f.readlines()

    ar = [[float(x) for x in line.split()] for line in lines if line[0] != "#"]
    for a1 in ar:
        a1[0] = int(a1[0])
        a1[1] = int(a1[1])
    ix_k = [x[0] for x in ar]
    ix_b = [x[1] for x in ar]
    ix_k_min = min(ix_k)
    ix_k_max = max(ix_k)
    ix_b_min = min(ix_b)
    ix_b_max = max(ix_b)

    #If spin=2, there is 6th column for spin
    #If not, only 5 columns
    if (len(ar[0]) == 5):
        num_spin = 1
    elif (len(ar[0]) == 6):
        num_spin = 2
    else:
        raise ValueError("Unknown number of columns %i" % len(ar[0]))

    if (filename_pw_xml is not None):
        band = qesp_read_band(filename_pw_xml)
        if (band.num_spin != num_spin):
            raise ValueError("Inconsistent spin for QE file and Yambo file")
        #Modify bands
#Set spin
        if (num_spin == 1):
            for a1 in ar:
                a1.append(0)
        else:
            for a1 in ar:
                a1[-1] = int((1 - a1[-1]) / 2)
#Set GW eigenvalues
#Note yambo make a shift to input DFT bands to make KS VBM=0,
#We shuold get it back
#Method 1 : calc shift and apply it to Yambo data
#       a = ar[0]
#       shift = a[2] - band.prop[a[-1]].eig[a[0]-1][a[1]-1]

#       for a in ar:
#           band.prop[a[-1]].eig[a[0]-1][a[1]-1] = a[2] + a[3] - shift

#Method 2 : add the correction to DFT instead of reading yambo DFT
        for a in ar:
            band.prop[a[-1]].eig[a[0] - 1][a[1] - 1] += a[3]

#Calculate properties
        if (band.vbm is not None):
            #Clear and recalculate
            band.vbm = None
            band.guess_vbm()

    else:
        if (num_spin == 1):
            list_eig = [[None] * (ix_b_max - ix_b_min + 1)
                        for x in range(ix_k_max - ix_k_min + 1)]
            for x in ar:  #Eo + (E-Eo)
                list_eig[x[0] - ix_k_min][x[1] - ix_b_min] = x[2] + x[3]
        elif (num_spin == 2):
            num_spin = 2
            list_eig = [[[None] * (ix_b_max - ix_b_min + 1)
                         for x in range(ix_k_max - ix_k_min + 1)],
                        [[None] * (ix_b_max - ix_b_min + 1)
                         for x in range(ix_k_max - ix_k_min + 1)]]
            for x in ar:  #Eo + (E-Eo)
                list_eig[int(
                    (1 - x[5]) / 2)][x[0] - ix_k_min][x[1] -
                                                      ix_b_min] = x[2] + x[3]

#Dummy kpt
        latt = Lattice()
        latt.ReadFromRawCellVector([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
        kpt = KPointsT()
        kpt.ReadFromList([[x, 0, 0] for x in range(len(list_eig))])
        kpt.unit = "crystal"
        kpt.latt = latt

        band = BandsT(kpt, list_eig, num_spin=num_spin)

    return band
Esempio n. 12
0
def wann_read_band(filename_band,
                   filename_kpt=None,
                   filename_gnu=None,
                   filename_out=None):
    '''
    Read band structure information from wannier90 output
    Indeed wannier90 output can be directly plotted but sometimes we need to combine two picture!
    :param filename_band: the name of eigenvalues ( normally seedname_band.dat )
    :param filename_kpt: the name of eigenvalues ( normally seedname_band.kpt;if not provided treated same as filename_band )
    :param filename_gnu: the name of gnuplot script ( if not provided treated same as band filename)
    :param filename_out: the name of stdout ( if not provided deduced from band filename)
    '''
    seedname = filename_band[:-9]
    if (filename_kpt == None):
        filename_kpt = seedname + "_band.kpt"
    if (filename_gnu == None):
        filename_gnu = seedname + "_band.gnu"
    if (filename_out == None):
        filename_out = seedname + ".wout"

    unit = wann_read_length_unit(filename_out)

    #K-points
    kpt1 = KPointsT()
    f = open(filename_kpt)
    n = int(f.readline())
    list_k = []
    for i in xrange(n):
        #Weight is ignored
        list_k.append([float(x) for x in f.readline().split()][0:3])
    f.close()
    kpt1.ReadFromList(list_k)
    #Bands
    list_band = f_Data_ReadTwoCol(filename_band)
    list_kcoord = [float(x[0]) for x in list_band]
    list_band = [[float(y) for y in x[1:]] for x in list_band]

    #Special k-points from gnuplot
    f = open(filename_gnu)
    for line in f:
        if ("xtics" in line):
            line2 = line[line.index("(") + 1:line.index(")")]
            ar = line2.split(",")
            for spec in ar:
                kcoord_last = 0.0
                kcoord_now = 0.0
                spec_name = spec[spec.index('"') + 1:spec.rindex('"')].strip()
                spec_value = float(spec[spec.rindex('"') + 1:])
                #               print(spec_name,spec_value)
                #Search nearest point
                for i, value in enumerate(list_kcoord):
                    #                   print(value)
                    if (spec_value <= value):  #
                        if (abs(spec_value - value) <=
                                abs(kcoord_last - spec_value)):
                            kpt1.listKPt[i][0] = spec_name
                        else:
                            kpt1.listKPt[i - 1][0] = spec_name
                        break
                    kcoord_last = value
                    #Detect the last one if not used
                    if (i == len(list_kcoord) - 1):
                        kpt1.listKPt[-1][0] = spec_name
#               print("Set kpt%i to %s" % ( i,spec_name))
            break
#Convert unit to Bohr
#However list_kcoord is not used later, maybe useful later
    if (unit == "Ang"):
        print("Convert unit from Angstrom to Bohr")
        list_kcoord = [x * Ang2Bohr for x in list_kcoord]

    return BandsT(kpt1, list_band, None, None, None, 1)