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
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)
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()
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)