Example #1
0
    def calculate_band_energy(self, band='d', atomtype=None, atomindex=None,
                              exclude=None, include=None):
        if (atomtype is not None) and (atomindex is not None):
            raise RuntimeError('atomtype and atomindex are mutually exclusive!')

        if (atomtype is None) and (atomindex is None):
            print 'Analyzing the %s-band for the whole system' % band.lower()
            atomtype = 'all'

        if (atomtype is not 'all') and (not self.pdos):
            raise RuntimeError('Cannot analyze %s atom(s), PDOS data not found.' % atomtype)

        atomlist = convert2list(atomtype)
        excludelist = convert2list(exclude)
        includelist = convert2list(include)

        allowed_bands = ['s', 'p', 'd']  # List of allowed bands
        nbands = len(band)  # nbands is the number of bands to be analyzed
        bandlist = list()  # List of bands to be analyzed

        for ban in band:
            if (ban.lower() not in allowed_bands):
                raise RuntimeError('Unknown band type: %s' % ban)
            else:
                bandlist.append(ban.lower())

        statesum = 0.0  # stores the sum of the states
        esum = 0.0  # stores the sum of the energy weighted by the number of states

        if (atomtype == 'all'):
            energy, dos = self.get_total_dos()
            esum, statesum = self.calculate_weighted_average(energy, dos, band)
        else:
            if (not atomlist) and (not includelist):
                raise RuntimeError('No atoms specified!')
            elif (not atomlist) and (includelist):
                dos = self.get_total_atom_dos(atomtype=None, exclude=excludelist,
                                                      include=includelist)
                es, ss = self.calculate_weighted_average(dos, band)
                esum += es
                statesum += ss
            else:
                for atom in atomlist:
                    dos = self.get_total_atom_dos(atomtype=atom, exclude=excludelist,
                                                  include=includelist)
                    es, ss = self.calculate_weighted_average(dos, band)
                    esum += es
                    statesum += ss

#        print 'Total:', esum, statesum
        return esum / statesum
Example #2
0
    def __dos_integrate(self, band='d', atomtype=None, exclude=None,
                         include=None, erange=None, rank=0):
        labels = {'s': 0, 'p': 1, 'd': 2}
        spinlabels = {'s': [0, 1], 'p': [2, 3], 'd': [4, 5]}
        allowed_bands = ['s', 'p', 'd']  # List of allowed bands
        bandlist = list()  # List of bands to be analyzed

        if (self.spin):
            totaldos = np.zeros((self.npoints, 6))
        elif (not self.spin):
            totaldos = np.zeros((self.npoints, 3)) 

        dosband = np.zeros((self.npoints))

        atomlist = convert2list(atomtype)
        excludelist = convert2list(exclude)
        includelist = convert2list(include)

        for ban in band:
            if (ban.lower() not in allowed_bands):
                raise RuntimeError('Unknown band type: %s' % ban)
            else:
                bandlist.append(ban.lower())

# Here we get the totaldos for each atom in the system
        for label in self.atom_labels:
            for atom in atomlist:
                if ((atom in label) or (label in includelist)) and (label not in excludelist):
                    totaldos += self.get_total_atom_dos(atomtype=atom,
                                                        exclude=excludelist,
                                                        include=includelist)

        if (erange == None):
            emin = self.energies[0]
            emax = self.energies[-1]
        elif (erange == 'fermi'):
            emin = self.energies[0]
            emax = 0.0
        else:
            emin = erange[0]
            emax = erange[1]

        energylist = list()
        indexlist = list()

        for n,e in enumerate(self.energies):
            if (e > emin) and (e < emax):
                energylist.append(e)
                indexlist.append(n)

        start = indexlist[0]
        finish = indexlist[-1]
        if (self.spin):
            for b in band:
                colup = spinlabels[b][0]
                coldown = spinlabels[b][1]
                dosband += (totaldos[:, colup] + totaldos[:, coldown]) 
        elif (not self.spin):
            for b in band:
                col = labels[b]
                dosband += totaldos[:, col]

        if (rank == 0):
            trimdos = dosband[start:finish+1]
        elif (rank == 1):
            trimdos = dosband[start:finish+1] * energylist
        elif (rank == 2):
            trimdos = dosband[start:finish+1] * energylist *energylist
        else:
            raise RuntimeError('Rank %i not recognized' % rank)

        return integrate(grid=energylist, data=trimdos)
Example #3
0
def dosplot(filename=None, energies=list(), dos=list(), plottype='chemist',
            legend=list(), location=1, erange=list(), staterange=list(), add_plot=False):
    """
    Wrapper for plotting the DOS with Matplotlib

    For the legend location guide, see:
        http://matplotlib.org/users/legend_guide.html#legend-location
    """

    doslist = convert2list(dos)
    legendlist = convert2list(legend)

    if (len(doslist) != len(legendlist)):
        print 'Number of DOS: ', len(doslist)
        print 'Number of legends: ', len(legendlist)
        raise RuntimeError('Number of legends does not match number of lines')

    if (plottype == 'chemist'):
        x = energies
        plt.xlabel('Energy (eV)')
        plt.ylabel('States (ab. units)')

        plotlist = list()

        for i in range(len(doslist)):
            tmp = plt.plot(x, doslist[i], label=legendlist[i])
            plotlist.append(tmp)

        if (erange):
            plt.xlim(erange)
            minimum = erange[0]
            maximum = erange[1]
        else:
            minimum = math.ceil(energies.min())
            maximum = math.ceil(energies.max())

        if (staterange):
            plt.ylim(staterange)

        ticks = np.arange(minimum, maximum+1, 2)
        plt.xticks(ticks)

    elif (plottype == 'physicist'):
        y = energies
        plt.xlabel('States (ab. units)')
        plt.ylabel('Energy (eV)')

        plotlist = list()

        for i in range(len(doslist)):
            tmp = plt.plot(doslist[i], y, label=legendlist[i])
            plotlist.append(tmp)

        if (erange):
            plt.ylim(erange)

        if (staterange):
            plt.xlim(staterange)

    plt.legend(loc=location)
    plt.savefig(filename)
    if (not add_plot):
        plt.close()
Example #4
0
    def get_band_width(self, band='d', atomtype=None, exclude=None,
                         include=None, erange=None):
# Yes I'm lazy, sue me.
        labels = {'s': 0, 'p': 1, 'd': 2}
        spinlabels = {'s': [0, 1], 'p': [2, 3], 'd': [4, 5]}
        allowed_bands = ['s', 'p', 'd']  # List of allowed bands
        bandlist = list()  # List of bands to be analyzed

        if (self.spin):
            totaldos = np.zeros((self.npoints, 6))
        elif (not self.spin):
            totaldos = np.zeros((self.npoints, 3)) 

        dosband = np.zeros((self.npoints))

        atomlist = convert2list(atomtype)
        excludelist = convert2list(exclude)
        includelist = convert2list(include)

        for ban in band:
            if (ban.lower() not in allowed_bands):
                raise RuntimeError('Unknown band type: %s' % ban)
            else:
                bandlist.append(ban.lower())

# Here we get the totaldos for each atom in the system
        for label in self.atom_labels:
            for atom in atomlist:
                if ((atom in label) or (label in includelist)) and (label not in excludelist):
                    totaldos += self.get_total_atom_dos(atomtype=atom,
                                                        exclude=excludelist,
                                                        include=includelist)

        if (erange == None):
#            print 'Integrating over whole range up to the Fermi level.'
            emin = self.energies[0]
            emax = 0.0
        elif (erange[1] == 'fermi'):
            emin = erange[0]
            emax = 0.0
        else:
            emin = erange[0]
            emax = erange[1]

        energylist = list()
        indexlist = list()

        for n,e in enumerate(self.energies):
            if (e > emin) and (e < emax):
                energylist.append(e)
                indexlist.append(n)

        start = indexlist[0]
        finish = indexlist[-1]
        if (self.spin):
            for b in band:
                colup = spinlabels[b][0]
                coldown = spinlabels[b][1]
                dosband += (totaldos[:, colup] + totaldos[:, coldown]) 
        elif (not self.spin):
            for b in band:
                col = labels[b]
                dosband += totaldos[:, col]

        trimdos = dosband[start:finish+1] * energylist * energylist

        filling = self.get_band_filling(band=band, atomtype=atomtype,
                                      include=include, exclude=exclude, erange=erange)

        return math.sqrt(integrate(grid=energylist, data=trimdos) / filling)