Example #1
0
    def __init__(self, bandpath="./", dospath=None):
        """
        Init method. Read vasprun.xml for the band structure calculation
        and the DOS calculation if a path is provided. The band structure is
        extracted using the fermi level of the dos calculation if available.

        Args:
            bandpath (str): path to vasprun.xml file of the band structure
            dospath (str): path to vasprun.xml file of the dos
        """
        self.xmlbands = os.path.join(bandpath, "vasprun.xml")
        if os.path.exists(self.xmlbands):
            run = BSVasprun(self.xmlbands, parse_projected_eigen=True)
        else:
            raise FileNotFoundError("File {0} not found".format(self.xmlbands))

        kpoints_file = os.path.join(bandpath, "KPOINTS")
        if dospath:
            self.xmldos = os.path.join(dospath, "vasprun.xml")
            if os.path.exists(self.xmldos):
                self.dosrun = Vasprun(self.xmldos)
            else:
                raise FileNotFoundError("File {0} not found".format(self.xmldos))
            self.bands = run.get_band_structure(kpoints_file, line_mode=True,
                                                efermi=self.dosrun.efermi)
        else:
            self.xmldos = None
            self.dosrun = None
            self.bands = run.get_band_structure(kpoints_file, line_mode=True)
Example #2
0
def readgap(vasprun, kpoints):
    run = BSVasprun(vasprun)
    bs = run.get_band_structure(kpoints)
    if (bs.is_metal()==False):
        return bs.get_cbm()['energy']-bs.get_vbm()['energy']
    else:
        return 0
Example #3
0
def brillplot(filenames=None,
              prefix=None,
              directory=None,
              width=6,
              height=6,
              fonts=None,
              image_format="pdf",
              dpi=400):
    """Generate plot of first brillouin zone from a band-structure calculation.
    Args:
        filenames (:obj:`str` or :obj:`list`, optional): Path to input files.
            Vasp:
                Use vasprun.xml or vasprun.xml.gz file.
        image_format (:obj:`str`, optional): The image file format. Can be any
            format supported by matplotlib, including: png, jpg, pdf, and svg.
            Defaults to pdf.
        dpi (:obj:`int`, optional): The dots-per-inch (pixel density) for the
            image.
    """
    if not filenames:
        filenames = find_vasprun_files()
    elif isinstance(filenames, str):
        filenames = [filenames]
    bandstructures = []
    for vr_file in filenames:
        vr = BSVasprun(vr_file)
        bs = vr.get_band_structure(line_mode=True)
        bandstructures.append(bs)
    bs = get_reconstructed_band_structure(bandstructures)

    labels = {}
    for k in bs.kpoints:
        if k.label:
            labels[k.label] = k.frac_coords

    lines = []
    for b in bs.branches:
        lines.append([
            bs.kpoints[b['start_index']].frac_coords,
            bs.kpoints[b['end_index']].frac_coords
        ])

    plt = pretty_plot_3d(width, height, dpi=dpi, fonts=fonts)
    fig = plot_brillouin_zone(bs.lattice_rec,
                              lines=lines,
                              labels=labels,
                              ax=plt.gca())

    basename = "brillouin.{}".format(image_format)
    filename = "{}_{}".format(prefix, basename) if prefix else basename
    if directory:
        filename = os.path.join(directory, filename)
    fig.savefig(filename, format=image_format, dpi=dpi, bbox_inches="tight")
    return plt
Example #4
0
 def test_get_band_structure(self):
     filepath = os.path.join(test_dir, "vasprun_Si_bands.xml")
     vasprun = BSVasprun(filepath, parse_potcar_file=False)
     bs = vasprun.get_band_structure(kpoints_filename=os.path.join(test_dir, "KPOINTS_Si_bands"))
     cbm = bs.get_cbm()
     vbm = bs.get_vbm()
     self.assertEqual(cbm["kpoint_index"], [13], "wrong cbm kpoint index")
     self.assertAlmostEqual(cbm["energy"], 6.2301, "wrong cbm energy")
     self.assertEqual(cbm["band_index"], {Spin.up: [4], Spin.down: [4]}, "wrong cbm bands")
     self.assertEqual(vbm["kpoint_index"], [0, 63, 64])
     self.assertAlmostEqual(vbm["energy"], 5.6158, "wrong vbm energy")
     self.assertEqual(vbm["band_index"], {Spin.up: [1, 2, 3], Spin.down: [1, 2, 3]}, "wrong vbm bands")
     self.assertEqual(vbm["kpoint"].label, "\Gamma", "wrong vbm label")
     self.assertEqual(cbm["kpoint"].label, None, "wrong cbm label")
def band_gap(args):
    v = BSVasprun(args.vasprun)
    try:
        band_gap_value, vbm_info, cbm_info = band_gap_properties(v)
        print(f"CBM info {cbm_info}")
        print(f"VBM info {vbm_info}")
        print(f"band gap info {band_gap_value}")
    except TypeError:
        print("Metallic system")
Example #6
0
def plot_orbital_projected_band_structure(filename='vasprun.xml',
                                          ylim=[-5, 5],
                                          orbitals=None,
                                          color_codes=None,
                                          spin=Spin.up,
                                          save_filename=None):
    if orbitals is None:
        plot_simple_smoothed_band_structure(filename=filename, ylim=ylim)
    else:
        v = BSVasprun(filename, parse_projected_eigen=True)
        print('read in vasprun xml file')
        bs = v.get_band_structure(line_mode=True)
        get_projected_plot_dots_local(bs,
                                      orbitals,
                                      color_codes=color_codes,
                                      ylim=ylim,
                                      spin=spin,
                                      filename=save_filename)
Example #7
0
 def test_get_band_structure(self):
     filepath = os.path.join(test_dir, 'vasprun_Si_bands.xml')
     vasprun = BSVasprun(filepath, parse_potcar_file=False)
     bs = vasprun.get_band_structure(kpoints_filename=
                                     os.path.join(test_dir,
                                                  'KPOINTS_Si_bands'))
     cbm = bs.get_cbm()
     vbm = bs.get_vbm()
     self.assertEqual(cbm['kpoint_index'], [13], "wrong cbm kpoint index")
     self.assertAlmostEqual(cbm['energy'], 6.2301, "wrong cbm energy")
     self.assertEqual(cbm['band_index'], {Spin.up: [4], Spin.down: [4]},
                      "wrong cbm bands")
     self.assertEqual(vbm['kpoint_index'], [0, 63, 64])
     self.assertAlmostEqual(vbm['energy'], 5.6158, "wrong vbm energy")
     self.assertEqual(vbm['band_index'], {Spin.up: [1, 2, 3],
                                          Spin.down: [1, 2, 3]},
                      "wrong vbm bands")
     self.assertEqual(vbm['kpoint'].label, "\Gamma", "wrong vbm label")
     self.assertEqual(cbm['kpoint'].label, None, "wrong cbm label")
Example #8
0
 def test_get_band_structure(self):
     filepath = os.path.join(test_dir, 'vasprun_Si_bands.xml')
     vasprun = BSVasprun(filepath, parse_potcar_file=False)
     bs = vasprun.get_band_structure(kpoints_filename=
                                     os.path.join(test_dir,
                                                  'KPOINTS_Si_bands'))
     cbm = bs.get_cbm()
     vbm = bs.get_vbm()
     self.assertEqual(cbm['kpoint_index'], [13], "wrong cbm kpoint index")
     self.assertAlmostEqual(cbm['energy'], 6.2301, "wrong cbm energy")
     self.assertEqual(cbm['band_index'], {Spin.up: [4], Spin.down: [4]},
                      "wrong cbm bands")
     self.assertEqual(vbm['kpoint_index'], [0, 63, 64])
     self.assertAlmostEqual(vbm['energy'], 5.6158, "wrong vbm energy")
     self.assertEqual(vbm['band_index'], {Spin.up: [1, 2, 3],
                                          Spin.down: [1, 2, 3]},
                      "wrong vbm bands")
     self.assertEqual(vbm['kpoint'].label, "\\Gamma", "wrong vbm label")
     self.assertEqual(cbm['kpoint'].label, None, "wrong cbm label")
     d = vasprun.as_dict()
     self.assertIn("eigenvalues", d["output"])
Example #9
0
    def __init__(self,
                 folder,
                 projected=False,
                 hse=False,
                 spin='up',
                 kpath=None,
                 n=None):
        """
        Initialize parameters upon the generation of this class

        Inputs:
        ----------
        folder: (str) This is the folder that contains the VASP files
        projected: (bool) Determined wheter of not to parte the projected
            eigenvalues from the vasprun.xml file. Making this true
            increases the computational time, so only use if a projected
            band structure is required.
        hse: (bool) Determines if the KPOINTS file is in the form of HSE
            or not. Only make true if the band structure was calculated
            using a hybrid functional.
        spin: (str) Choose which spin direction to parse. ('up' or 'down')
        """

        self.vasprun = BSVasprun(f'{folder}/vasprun.xml',
                                 parse_projected_eigen=projected)
        self.poscar = Poscar.from_file(f'{folder}/POSCAR',
                                       check_for_POTCAR=False,
                                       read_velocities=False)
        self.projected = projected
        self.hse = hse
        self.kpath = kpath
        self.n = n
        self.folder = folder
        self.spin = 'up'
        self.spin_dict = {'up': Spin.up, 'dowm': Spin.down}
        self.bands_dict = self.load_bands()
        self.color_dict = {
            0: '#FF0000',
            1: '#0000FF',
            2: '#008000',
            3: '#800080',
            4: '#E09200',
            5: '#FF5C77',
            6: '#778392',
            7: '#07C589',
            8: '#40BAF2',
        }

        if projected:
            self.projected_dict = self.load_projected_bands()

        if not hse:
            self.kpoints = Kpoints.from_file(f'{folder}/KPOINTS')
Example #10
0
def get_band_gap(directory):
    vasp_out = BSVasprun(directory + "/vasprun.xml")
    band_str = vasp_out.get_band_structure(line_mode=True)
    band_gap = band_str.get_band_gap()
    print(band_gap)
    return band_gap
Example #11
0
from pymatgen.io.vasp.outputs import BSVasprun
from pymatgen.electronic_structure.plotter import BSPlotter
from pymatgen.electronic_structure.core import Spin
from pymatgen.electronic_structure.bandstructure import BandStructure
import os

# vaspout = BSVasprun("./hubbard/hub_Mn-5_Fe-5/vasprun.xml")
vaspout = BSVasprun("../calc_seq_test/bands-mag/vasprun.xml")
# 50 k-points = 0.3863000000000012 eV
# 100 k-points = 0.38480000000000114 eV
# 8x8x8 50 k-points = 0.39029999999999987 eV
# 50 k-points with LASPH = 0.3932000000000002 eV
bandstr = vaspout.get_band_structure(line_mode=True)

print(bandstr.get_band_gap())
# print(bandstr.get_direct_band_gap_dict())

plt = BSPlotter(bandstr).get_plot(ylim=[-10, 5])
plt.show()


# get band gap for all directories

def get_band_gap(directory):
    vasp_out = BSVasprun(directory + "/vasprun.xml")
    band_str = vasp_out.get_band_structure(line_mode=True)
    band_gap = band_str.get_band_gap()
    print(band_gap)
    return band_gap

Example #12
0
class BSPlotting :
    def __init__(self, vasprun='vasprun.xml',kpoints='KPOINTS'):
        self.bsrun = BSVasprun(vasprun, parse_potcar_file=False,parse_projected_eigen=True)
        self.bs = self.bsrun.get_band_structure(kpoints)
        self.bsdict = self.bs.as_dict()

    def _xlabels(self):
        steps=[];uniq_d=[];uniq_l=[]

        for br in self.bs.branches :
            s, e = br['start_index'], br['end_index']
            labels = br['name'].split("-")

            steps.append(e+1)

            if labels[0] == labels[1] :
                continue

            for i,l in enumerate(labels) :
                if l.startswith("\\") or "_" in l :
                    labels[i] = "$"+l+"$"

            if uniq_d != [] and labels[0] != uniq_l[-1] :
                uniq_l[-1] += "$\\mid$" + labels[0]
                uniq_l.append(labels[1])
                uniq_d.append(self.bs.distance[e])
            else :
                uniq_l.extend(labels)
                uniq_d.extend([self.bs.distance[s], self.bs.distance[e]])
        del steps[-1]

        uniq=defaultdict(list)
        uniq['steps'].extend(steps)
        uniq['distance'].extend(uniq_d)
        uniq['labels'].extend(uniq_l)

        return uniq

    def _bandinform(self):
        band_inform = dict()

        # the number of the bands and kpoints
        band_inform['NB'] = self.bs.nb_bands
        band_inform['NK'] = len(self.bs.kpoints)

        # Fermi energy & band gap & CBM and VBM

        band_inform['E_f'] = self.bs.efermi
        eg = self.bsdict['band_gap']['energy']
        cbm = self.bsdict['cbm']
        vbm = self.bsdict['vbm']

        cbm_kindex=cbm['kpoint_index'] ; vbm_kindex = vbm['kpoint_index']
        cbm_bindex =cbm['band_index'] ; vbm_bindex = vbm['band_index']

        if eg != 0 :
            cbm1 = [(self.bs.distance[index], cbm['energy']) for index in cbm_kindex]
            vbm1 = [(self.bs.distance[index], vbm['energy']) for index in vbm_kindex]
            
            if self.bsdict['band_gap']['direct'] :
                direct_eg = eg
                indirect_eg = eg
                
                cbm2 = cbm1 ; vbm2 = vbm1
            else :
                direct_dict = self.bs.get_direct_band_gap_dict()[Spin.up]
                indirect_eg = eg
                direct_eg = direct_dict['value']
                direct_kindex = direct_dict['kpoint_index']
                
                vbm2 = [(self.bs.distance[direct_kindex], self.bs.bands[Spin.up][direct_dict['band_indices'][0],direct_kindex])]
                cbm2 = [(self.bs.distance[direct_kindex], self.bs.bands[Spin.up][direct_dict['band_indices'][1],direct_kindex])]
                
            band_inform['E_g'] = {"Direct":direct_eg,"Indirect":indirect_eg}
            band_inform['CBM'] = {"Direct":cbm2, "Indirect": cbm1}
            band_inform['VBM'] = {"Direct":vbm2, "Indirect": vbm1}
        else :
            band_inform['E_g'] = {"Direct":0, "Indirect" : 0}
            band_inform['CBM'] = {"Direct":None,"Indirect":None}
            band_inform['VBM'] = {"Direct":None,"Indirect":None}

        # Energies and distances
        steps = [br["end_index"] + 1 for br in self.bs.branches][:-1]
        energies={}
        for sp in self.bs.bands.keys():
            energies[str(sp)]=np.hsplit(self.bs.bands[sp], steps)
        distances = np.split(self.bs.distance, steps)

        band_inform['energies'] = energies
        band_inform['distances'] = distances

        return band_inform
    
    def printinform(self,path=os.getcwd()):
        bi = self._bandinform()
        fi = open("{}/band_inform.log".format(path),"w") 
        fi.write("gmd plot options\n")
            
        bandgap = "%.3f(Indirect)"%(self.bsdict['band_gap']['energy'])
        if self.bsdict['band_gap']['direct']:
            bandgap = "%.3f(Direct)"%(self.bsdict['band_gap']['energy'])

        print("\nnumber of bands : {}".format(bi['NB']))
        print("number of kpoints : {}".format(bi['NK']))
        print("fermi energy : %.3f"%(bi['E_f']))
        print("band gap : {}".format(bandgap))
        fi.write("number of bands : %i\n"%(bi['NB']))
        fi.write("number of kpoints : %i\n"%(bi['NK']))
        fi.write("fermi energy : %i\n"%(bi['E_f']))
        fi.write("band gpa : %s\n"%(bandgap))
        print("Label positions :")
        fi.write("Label positions :\n")
        sum1 = 0 ; name , distance = '', '' 
        for d,l in zip(self._xlabels()['distance'],self._xlabels()['labels']):
            if sum1 == 0 or sum1 == len(self._xlabels()['distance'])-1 :
                print("\t%.5f : %s"%(d,l))
                fi.write("\t%.5f : %s\n"%(d,l))
            else :
                if name == l and distance == d :
                    print("\t%.5f : %s"%(d,l))
                    fi.write("\t%.5f : %s\n"%(d,l))
                else :
                    name = l ; distance = d
            sum1 += 1
        fi.close()

    def get_plot(self, figsize=(12,8), zero_to_efermi=True,color='b',ylim=(-4,6), fontsize=32, spindownoff=True, vbm_cbm_marker=True):
        # Figure 
        plt.rcParams['figure.figsize'] = figsize
        plt.rcParams['font.size']=fontsize
        plt.rcParams['font.family'] = 'Arial'

        plt.figure(figsize=figsize)
        # get information from def
        bi = self._bandinform()
        label = self._xlabels()

        # consider the vbm energy
        zero_energy = 0
        if zero_to_efermi :
            if self.bsdict['vbm']['energy'] == None :
                zero_energy = 0
            else :
                zero_energy = self.bsdict['vbm']['energy']
                plt.axhline(0,color='k',lw=1,ls='--')

        # Plotting energies
        for ib in range(self.bs.nb_bands) :
                for sp in self.bs.bands.keys():
                    for xpath, epath in zip(bi['distances'], bi['energies'][str(sp)]):
                            if str(sp) == '-1' and spindownoff == False :
                                plt.plot(xpath, epath[ib] - zero_energy,color='r')
                            else :
                                plt.plot(xpath, epath[ib] - zero_energy,color=color)

        # decorating the plot
        plt.xticks(label['distance'],label['labels'])
        plt.xlim(min(label['distance']),max(label['distance']))
        plt.xlabel(r'$\mathrm{Wave\ Vector}$', fontsize=30)
        if zero_to_efermi : 
            ylabel = r'$\mathrm{E\ -\ E_{VBM}\ (eV)}$' 
            if self.bsdict['vbm']['energy'] == None : 
                ylabel = r'$\mathrm{Energy\ (eV)}$'
        else :
            ylabel = r'$\mathrm{Energy\ (eV)}$'
        plt.ylabel(ylabel, fontsize=30)
        for i in range(len(label['distance'])):
            plt.axvline(label['distance'][i],color='k',lw=1)
        plt.ylim(ylim)
        
        # cbm and vbm
        eg = self.bsdict['band_gap']['energy']
        if eg != 0 and vbm_cbm_marker :
            if self.bsdict['band_gap']['direct'] :
                for c in bi['CBM']['Direct'] :
                    plt.scatter(c[0],c[1]-zero_energy,color='g',s=(fontsize*5))
                for v in bi['VBM']['Direct'] :
                    plt.scatter(v[0], v[1]-zero_energy,color='#FF0000',s=(fontsize*5))
            else :
                for c in bi['CBM']['Indirect'] :
                    plt.scatter(c[0],c[1]-zero_energy,color='g',s=(fontsize*5))
                for v in bi['VBM']['Indirect'] :
                    plt.scatter(v[0], v[1]-zero_energy,color='#FF0000',s=(fontsize*5))

                for c in bi['CBM']['Direct'] :
                    plt.scatter(c[0],c[1]-zero_energy,color='purple',s=(fontsize*5))
                for v in bi['VBM']['Direct'] :
                    plt.scatter(v[0], v[1]-zero_energy,color='y',s=(fontsize*5))
        plt.tight_layout()
        return plt
from pymatgen.io.vasp.outputs import BSVasprun
from pymatgen.electronic_structure.plotter import BSPlotterProjected

import os
import pickle

vasp_dir = os.path.dirname(os.path.abspath(__file__))
vasp_run = BSVasprun(os.path.join(vasp_dir,"vasprun.xml"),parse_projected_eigen=True)

bs = vasp_run.get_band_structure(line_mode=True)

bsp = BSPlotterProjected(bs)

p = bsp.get_color_grouped([{'elements':['Ag','Se'],'color':[255,140,0]},
                           {'elements':['C','H'],'color':[0,0,0]}],ylim=[-3,4])
p.savefig('color_band.pdf')

#pickle.dump(bs, open("band_structure.dat", "w"))
#!/usr/bin/env python3
from pymatgen.io.vasp.outputs import BSVasprun

raw = BSVasprun("vasprun.xml")
bandstructure = raw.get_band_structure("KPOINTS")
bandstructure.get_band_gap()
import pymatgen as mg
from pymatgen.io.vasp.outputs import Vasprun, Procar, BSVasprun
from pymatgen.symmetry.bandstructure import HighSymmKpath
from pymatgen.electronic_structure.core import Spin, Orbital
from pymatgen.electronic_structure.plotter import BSPlotter
from pymatgen.electronic_structure.plotter import BSPlotterProjected

mpl.rc('text', usetex=True)
mpl.rc('font', weight='bold')
mpl.rcParams['text.latex.unicode'] = True
mpl.rcParams['text.latex.preamble'] = [r"\usepackage{amsmath}"]

if __name__ == "__main__":

    # bands object prepared using pymatgen library. contains eigenvalue information
    v = BSVasprun("./vasprun.xml", parse_projected_eigen=True)
    bs = v.get_band_structure(line_mode=True)
    #print (bs.is_metal())
    #print (bs.get_band_gap())
    #print (bs.get_direct_band_gap())

    #print (bs.get_projections_on_elements_and_orbitals({'As':['s','p','d']}))
    #promenade = HighSymmKpath.get_kpoints
    #print promenade
    #get_kpoints(bs,line_density=20, coords_are_cartesian=True)
    BSPlotter(bs).show()

    #BSPlotter(bs).plot_brillouin()
    #BSPlotter(bs).save_plot(filename="normal-bandstructure.pdf",img_format="pdf",zero_to_efermi=True)

    bsproj = BSPlotterProjected(bs).get_projected_plots_dots_patom_pmorb(
Example #16
0
    def deltaBand(self):
        ispin_hse, nbands_hse, nkpts_hse = self.readInfo(self.vasprun_hse)
        ispin_dftu, nbands_dftu, nkpts_dftu = self.readInfo(self.vasprun_dftu)

        if nbands_hse != nbands_dftu:
            raise Exception('The band number of HSE and GGA+U are not match!')

        kpoints = [line for line in open(self.kpoints_hse) if line.strip()]
        kpts_diff = 0
        for ii, line in enumerate(kpoints[3:]):
            if line.split()[3] != '0':
                kpts_diff += 1

        if nkpts_hse - kpts_diff != nkpts_dftu:
            raise Exception('The kpoints number of HSE and GGA+U are not match!')
        
        run_hse = BSVasprun(self.vasprun_hse)
        bs_hse = run_hse.get_band_structure(self.kpoints_hse)

        run_dftu = BSVasprun(self.vasprun_dftu)
        bs_dftu = run_dftu.get_band_structure(self.kpoints_dftu)

        v_hse = []
        v_dftu = []
        v = {}

        if ispin_hse == 1 and ispin_dftu == 1:
            v_hse.append(self.access_eigen(run_hse,1)[kpts_diff:,:,0])
            v_dftu.append(self.access_eigen(run_dftu,1)[:,:,0])


        elif ispin_hse == 2 and ispin_dftu == 2:
            v_hse.append(self.access_eigen(run_hse,1)[kpts_diff:,:,0])
            v_hse.append(self.access_eigen(run_hse,-1)[kpts_diff:,:,0])

            v_dftu.append(self.access_eigen(run_dftu,1)[:,:,0])
            v_dftu.append(self.access_eigen(run_dftu,-1)[:,:,0])

        else:
            raise Exception('The spin number of HSE and GGA+U are not match!')
        
        v['hse'] = np.array(v_hse)
        v['dftu'] = np.array(v_dftu)

        edge = {}
        loc = {}
        efermi = {}
        efermi['hse'] = run_hse.efermi
        efermi['dftu'] = run_dftu.efermi

        for m in 'hse','dftu':
            spin = {}
            i = {}
            for s in range(ispin_hse):
                vbm = self.get_vbm(v[m][s],efermi[m])
                cbm = self.get_cbm(v[m][s],efermi[m])
                vbm_loc = max(np.where(v[m][s] == vbm)[1])
                cbm_loc = min(np.where(v[m][s] == cbm)[1])
                spin[s] = [vbm,cbm]
                i[s] = [vbm_loc,cbm_loc]
            edge[m] = spin
            loc[m] = i
        shifted_hse = np.concatenate(((v['hse'][0] - edge['hse'][0][0])[:,loc['hse'][0][0]-self.br+1:loc['hse'][0][0]+1],
                                  (v['hse'][0] - edge['hse'][0][1])[:,loc['hse'][0][1]:loc['hse'][0][1]+self.br]),
                                   axis = 1)

        if ispin_hse == 2:
            shifted_hse = np.concatenate((shifted_hse,
                                        (v['hse'][1] - edge['hse'][0][0])[:,loc['hse'][1][0]-self.br+1:loc['hse'][1][0]+1],
                                        (v['hse'][1] - edge['hse'][0][1])[:,loc['hse'][1][1]:loc['hse'][1][1]+self.br]),
                                        axis = 1)
        if ispin_dftu == 1:
            continuous = (loc['dftu'][0][1] - loc['dftu'][0][0]) == 1
        elif ispin_dftu == 2:
            continuous = (loc['dftu'][0][1] - loc['dftu'][0][0]) == 1 & (loc['dftu'][1][1] - loc['dftu'][1][0]) == 1
        else:
            raise Exception('Check your ISPIN for GGA+U')
        

        if bs_dftu.is_metal() == False or continuous == True:

            shifted_dftu = np.concatenate(((v['dftu'][0] - edge['dftu'][0][0])[:,loc['dftu'][0][0]-self.br+1:loc['dftu'][0][0]+1],
                                        (v['dftu'][0] - edge['dftu'][0][1])[:,loc['dftu'][0][1]:loc['dftu'][0][1]+self.br]),
                                            axis = 1)
            if ispin_dftu == 2:
                shifted_dftu = np.concatenate((shifted_dftu,
                                            (v['dftu'][1] - edge['dftu'][0][0])[:,loc['dftu'][1][0]-self.br+1:loc['dftu'][1][0]+1],
                                            (v['dftu'][1] - edge['dftu'][0][1])[:,loc['dftu'][1][1]:loc['dftu'][1][1]+self.br]),
                                            axis = 1)
        else:
            shifted_dftu = (v['dftu'][0] - edge['dftu'][0][0])[:,loc['dftu'][0][0]-self.br+1:loc['dftu'][0][0]+1+self.br]
            if ispin_dftu == 2:
                shifted_dftu = np.concatenate((shifted_dftu,
                                            (v['dftu'][1] - edge['dftu'][0][0])[:,loc['dftu'][1][0]-self.br+1:loc['dftu'][1][0]+1+self.br]),
                                            axis = 1)
        n = shifted_hse.shape[0] * shifted_hse.shape[1]

        delta_band = sum((1/n)*sum((shifted_hse - shifted_dftu)**2))**(1/2)
        
        if bs_dftu.is_metal()==False:
            gap = edge['dftu'][0][1] - edge['dftu'][0][0]
        else:
            gap = 0

        incar = Incar.from_file('./dftu/band/INCAR')
        u = incar['LDAUU']
        u.append(gap)
        u.append(delta_band)
        output = ' '.join(str(x) for x in u) 

        with open('u.txt','a+') as f:
            f.write(output + '\n')
            f.close

        return delta_band
Example #17
0
def plot(locs, parse=False, figsize=None, dpi=300, lw=1.0, save=False):

    for p in (My_Axes_X, My_Axes_Y):
        mpl.projections.register_projection(p)

    def setDos(axis, minor, spin=[Spin.up], lim=None):
        """ Set up plotting area for DOS. If bands are plotted, set y-axis to vertical"""
        def spines(zero, hide):
            for z in zero:
                axD.spines[z].set_position('zero')
            for h in hide:
                axD.spines[h].set_visible(False)

        if len(spin) == 1:
            if spin[0].value == 1:
                axD.set_title(u'DOS $\u2191$', **title)
                if axis == 'y':
                    axD.set_xlim(0, lim[1])
                    spines(zero=['left', 'top'], hide=['right', 'bottom'])
                    axD.yaxis.tick_left()
                else:
                    axD.set_ylim(0, lim[1])
                    spines(zero=['right', 'bottom'], hide=['left', 'top'])
                    axD.xaxis.tick_bottom()
            else:
                axD.set_title(u'DOS $\u2193$', **title)
                if axis == 'y':
                    axD.set_xlim(lim[0], 0)
                    spines(zero=['right', 'top'], hide=['left', 'bottom'])
                    axD.yaxis.tick_right()
                else:
                    axD.set_ylim(lim[0], 0)
                    spines(zero=['right', 'top'], hide=['left', 'bottom'])
                    axD.xaxis.tick_top()
                    axD.xaxis.set_label_coords(0.5, -0.1)
        else:
            axD.set_title('DOS', **title)
            if axis == 'y':
                axD.set_xlim(lim)
                spines(zero=['left', 'top'], hide=['right', 'bottom'])
                axD.set_xlabel(u'$\u2193$     $\u2191$', **arrows)
            else:
                axD.set_ylim(lim)
                spines(zero=['right', 'bottom'], hide=['left', 'top'])
                axD.set_ylabel(u'$\u2190$     $\u2192$', **arrows)
            axD.xaxis.set_label_coords(0.5, -0.04)

        # define tick labels for density (in arbitrary units)
        if 'DOSticks' in dosopt:
            func = lambda x, pos: "" \
                if np.isclose(x,0) else "%d" % x if np.equal(np.mod(x, 1), 0) else x
        else:
            func = lambda x, pos: ""

        if axis == 'y':  # if bands are plotted...
            axD.xaxis.tick_top()
            axD.xaxis.set_major_formatter(FuncFormatter(func))
            axD.yaxis.set_minor_locator(MultipleLocator(minor))
            plt.subplots_adjust(top=0.92,
                                bottom=0.08,
                                left=0.12,
                                right=0.96,
                                hspace=0.2,
                                wspace=0.2)
        else:
            axD.yaxis.tick_right()
            axD.set_xlabel("E - E$\mathrm{_f}$ (eV)", **axes)
            axD.yaxis.set_major_formatter(FuncFormatter(func))
            axD.xaxis.set_minor_locator(MultipleLocator(minor))
            plt.tight_layout()
            plt.subplots_adjust(top=0.85,
                                bottom=0.21,
                                left=0.08,
                                right=0.91,
                                hspace=0.2,
                                wspace=0.2)

        global _axes
        _axes = [axD]
        if 'zoom' in dosopt and dosopt['zoom']:
            if len(dosopt['zoom']) > 2:
                axz = axD.inset_axes(dosopt['zoom'][2])
            elif axis == 'y':
                axz = axD.inset_axes([0.5, 0., 0.5, 0.25])
            else:
                axz = axD.inset_axes([0., 0.5, 0.25, 0.6])
            axz.set_xlim(dosopt['zoom'][0])
            axz.set_ylim(dosopt['zoom'][1])
            axz.set_xticklabels('')
            axz.set_yticklabels('')
            axz.set_label('zoom')
            _axes.append(axz)
            axD.indicate_inset_zoom(axz)

    ###########################################################################

    # set general linewidth for plot borders
    for i in [
            'axes.linewidth', 'xtick.major.width', 'xtick.minor.width',
            'ytick.major.width', 'ytick.minor.width'
    ]:
        mpl.rcParams[i] = lw

    # define plot axes
    global bandruns, dosruns, bands

    if parse:
        bandruns = []
        dosruns = []

    for i, loc in enumerate(locs):

        #        proj = bandopt['projections'] if 'projections' in bandopt else False

        if 'bands' in plots or 'BZ' in plots:

            if parse:
                bandruns.append(
                    BSVasprun(loc + "/bands.xml", parse_projected_eigen=True))

            bands = bandruns[i].get_band_structure(loc + "/KPOINTS",
                                                   line_mode=True,
                                                   efermi=bandruns[i].efermi)

        if 'bands' in plots:
            figsize = figsize if figsize else (7, 8)
            fig = plt.figure(figsize=figsize)
            gs = fig.add_gridspec(1,5, wspace=0.3) if 'dos' in plots \
                                                    else fig.add_gridspec(1,2)

            #            axB = fig.add_subplot(gs[0:3], projection='My_Axes_Y')
            axB = fig.add_subplot(gs[0:3])
            axB.set_title('Band Structure', **title)
            axB.set_xlabel(r'Symmetry Points', **axes)
            axB.set_ylabel("E - E$\mathrm{_f}$ (eV)", **axes)
            axB.tick_params(axis='x', which='both', length=0, pad=5)
            axB.tick_params(axis='y',
                            which='both',
                            labelsize=ticks['fontsize'])

            plotBands(axB, bandruns[i], **bandopt)

        if 'dos' in plots:

            if parse: dosruns.append(Vasprun(loc + "\..\dos.xml"))

            if 'spin' in dosopt:
                spin = dosopt['spin']
            else:
                if dosruns[i].is_spin:
                    spin = [Spin.up, Spin.down]
                else:
                    spin = [Spin.up]

            xlim = dosopt['xlim'] if 'xlim' in dosopt else (-4, 4)
            ylim = dosopt['ylim'] if 'ylim' in dosopt else (-15, 15)
            shift = dosopt['shift'] if 'shift' in dosopt else 0.
            if 'ylim' in dosopt:
                ylim = dosopt['ylim']
            else:
                e = dosruns[-1].tdos.energies - \
                    dosruns[-1].tdos.get_cbm_vbm()[1] - shift
                ind = [
                    e.tolist().index(i)
                    for i in e[(e > xlim[0]) & (e < xlim[1])]
                ]
                lim = max([
                    max(a[ind[0]:ind[-1]])
                    for a in dosruns[-1].tdos.densities.values()
                ])
                ylim = (-lim, lim)

            vertical = dosopt['vertical'] if 'vertical' in dosopt else None

            if 'bands' in plots:
                #                axD = fig.add_subplot(gs[3:5], sharey=axB, projection='My_Axes_Y')
                axD = fig.add_subplot(gs[3:5], sharey=axB)
                axD.tick_params(labelleft=False)
                setDos('y', 0.25, spin=spin, lim=ylim)
                plotDOS(fig, dosruns[i], **dosopt)
            else:
                if figsize:
                    figsize = figsize
                elif vertical:
                    figsize = (5, 10)
                else:
                    figsize = (14, 5)
                fig = plt.figure(figsize=figsize)

                if vertical:
                    #                    axD = fig.add_subplot(111,projection='My_Axes_Y')
                    axD = fig.add_subplot(111)
                    axD.set_ylim(xlim)
                    setDos('y', 0.25, spin=spin, lim=ylim)
                    plotDOS(fig, dosruns[i], orient='y', **dosopt)
                else:
                    #                    axD = fig.add_subplot(111, projection='My_Axes_X')
                    axD = fig.add_subplot(111)
                    axD.set_xlim(xlim)
                    setDos('x', 0.25, spin=spin, lim=ylim)
                    plotDOS(fig, dosruns[i], orient='x', **dosopt)

        if 'BZ' in plots: plotBZ()

        if save:
            plt.savefig(loc + '/%s' % '_'.join(plots) + \
                        '.png', format='png', dpi=dpi)
Example #18
0
def bandplot_func(
        filenames=None,
        code='vasp',
        prefix=None,
        directory=None,
        vbm_cbm_marker=False,
        projection_selection=None,
        mode='rgb',
        pred=None,
        interpolate_factor=4,
        circle_size=150,
        dos_file=None,
        cart_coords=False,
        scissor=None,
        ylabel='Energy (eV)',
        dos_label=None,
        elements=None,
        lm_orbitals=None,
        atoms=None,
        spin=None,
        total_only=False,
        plot_total=True,
        legend_cutoff=3,
        gaussian=None,
        height=None,
        width=None,
        ymin=-6.,
        ymax=6.,
        colours=None,
        yscale=1,
        style=None,
        no_base_style=False,
        image_format='pdf',
        dpi=400,
        plt=None,
        fonts=None,
        boltz={
            "ifinter": "T",
            "lpfac": "10",
            "energy_range": "50",
            "curvature": "",
            "load": "T",
            'ismetaltolerance': '0.01'
        },
        nelec=0):
    if not filenames:
        filenames = find_vasprun_files()
    elif isinstance(filenames, str):
        filenames = [filenames]

    # only load the orbital projects if we definitely need them
    parse_projected = True if projection_selection else False

    # now load all the band structure data and combine using the
    # get_reconstructed_band_structure function from pymatgen
    bandstructures = []
    if code == 'vasp':
        for vr_file in filenames:
            vr = BSVasprun(vr_file, parse_projected_eigen=parse_projected)
            print("BSVasprun", type(vr), vr)
            print("vr.eigenvalues.keys()", type(vr.eigenvalues.keys()),
                  vr.eigenvalues.keys())
            if pred.any():
                # Fill in Model prediction
                model = BSVasprun(vr_file,
                                  parse_projected_eigen=parse_projected)
                print("pred", type(pred), pred.shape)
                pred = np.expand_dims(pred, axis=-1)
                for key in model.eigenvalues.keys():
                    key_last = key
                    print("model.eigenvalues[key][:, :, :].shape[0]", key,
                          type(model.eigenvalues[key][:, :, :]),
                          model.eigenvalues[key][:, :, :].shape,
                          pred[:, :, :].shape)
                    bands = min(model.eigenvalues[key][:, :, :].shape[1],
                                pred.shape[1])
                    print(
                        "bands", bands, "attention! max: ",
                        max(model.eigenvalues[key][:, :, :].shape[1],
                            pred.shape[1]))
                    print(
                        "equel False?",
                        np.sum(model.eigenvalues[key][:, :bands, :] -
                               pred[:, :bands, :]))
                    model.eigenvalues[key][:, :bands, :] = pred[:, :bands, :]
                    print(
                        "equel True?",
                        np.sum(model.eigenvalues[key][:, :bands, :] -
                               pred[:, :bands, :]))
                    print(
                        "equel model vr?",
                        np.sum(model.eigenvalues[key][:, :bands, :] -
                               vr.eigenvalues[key][:, :bands, :]))
                    # spin = 1  # for only plotting spin up oder down 1, -1
                # model.eigenvalues[key_last][:, :bands, :] = pred[:, :bands, :]

            #boltztrap={'ifinter':False,'lpfac':10,'energy_range':50,'curvature':False}):

            if bool(boltz['ifinter']):
                b_data = VasprunBSLoader(vr)
                model_data = VasprunBSLoader(model)
                print("BSVasprunLoader", type(b_data), b_data)
                b_inter = BztInterpolator(b_data,
                                          lpfac=int(boltz['lpfac']),
                                          energy_range=float(
                                              boltz['energy_range']),
                                          curvature=bool(boltz['curvature']),
                                          save_bztInterp=True,
                                          load_bztInterp=bool(boltz['load']))
                model_inter = BztInterpolator(
                    model_data,
                    lpfac=int(boltz['lpfac']),
                    energy_range=float(boltz['energy_range']),
                    curvature=bool(boltz['curvature']),
                    save_bztInterp=True,
                    load_bztInterp=bool(boltz['load']))

                try:
                    kpath = json.load(open('./kpath', 'r'))
                    kpaths = kpath['path']
                    kpoints_lbls_dict = {}
                    for i in range(len(kpaths)):
                        for j in [0, 1]:
                            if 'GAMMA' == kpaths[i][j]:
                                kpaths[i][j] = '\Gamma'
                    for k, v in kpath['kpoints_rel'].items():
                        if k == 'GAMMA':
                            k = '\Gamma'
                        kpoints_lbls_dict[k] = v
                except:
                    kpaths = None
                    kpoints_lbls_dict = None

                print(kpaths, kpoints_lbls_dict)
                bs = b_inter.get_band_structure(
                    kpaths=kpaths, kpoints_lbls_dict=kpoints_lbls_dict)
                model_bs = model_inter.get_band_structure(
                    kpaths=kpaths, kpoints_lbls_dict=kpoints_lbls_dict)

                #bs_uniform = b_inter.get_band_structure()
                gap = bs.get_band_gap()
                nvb = int(np.ceil(nelec / (int(bs.is_spin_polarized) + 1)))
                vbm = -100
                print("WHC interpolated gap: %s" % gap)
                for spin, v in bs.bands.items():
                    vbm = max(vbm, max(v[nvb - 1]))
                print(
                    'WHC WARNNING vasp fermi %s interpolation vbm %s nelec %s nvb %s'
                    % (bs.efermi, vbm, nelec, nvb))
                if vbm < bs.efermi:
                    bs.efermi = vbm
                    print("if vbm <")
                if vbm < model_bs.efermi:
                    model_bs.efermi = vbm
                    print("if vbm <")
                print(bs.bands.keys())
                band_keys = list(bs.bands.keys())
                print("Band shapes", bs.bands[band_keys[0]].shape,
                      model_bs.bands[band_keys[0]].shape)
                print(
                    "equel bands?",
                    np.sum((bs.bands[band_keys[0]] - bs.efermi) -
                           model_bs.bands[band_keys[0]]))
                bs.bands[band_keys[0]] = (
                    bs.bands[band_keys[0]] - bs.efermi
                )  # why??????????????????????????????????????????????????
                # bs.bands[band_keys[1]] = (bs.bands[band_keys[1]] - bs.efermi)  # why??????????????????????????????????????????????????
                print(
                    "equel bands fermi shifted?",
                    np.sum((bs.bands[band_keys[0]] - bs.efermi) -
                           model_bs.bands[band_keys[0]]))

                # bandstructures.append(bs)
                # bandstructures.append(model_bs)
            bs = get_reconstructed_band_structure([bs])
            model_bs = get_reconstructed_band_structure([model_bs])

            if bool(boltz['ifinter']):
                bs.nvb = nvb
                bs.ismetaltolerance = float(boltz['ismetaltolerance'])
                model_bs.nvb = nvb
                model_bs.ismetaltolerance = float(boltz['ismetaltolerance'])

            print("dft bands", bs.bands[band_keys[0]])
            print("dft ktps", len(bs.kpoints), kpts.shape)
            print("dft labels", bs.labels_dict)

            for key in bs.labels_dict.keys():
                print(bs.labels_dict[key].label, bs.labels_dict[key].as_dict(),
                      bs.labels_dict[key].a, bs.labels_dict[key].b,
                      bs.labels_dict[key].c, bs.labels_dict[key].frac_coords)
            labels = []
            for i in range(len(bs.kpoints)):
                # print(i, bs.kpoints[i])
                for key in bs.labels_dict.keys():
                    if bs.labels_dict[key].label == bs.kpoints[
                            i].label and bs.labels_dict[
                                key].label != bs.kpoints[i - 1].label:
                        # print("Labels!!!!!", i, bs.labels_dict[key].label)
                        labels.append([i, bs.labels_dict[key].label])
            print(labels)

            print("dft efermi", bs.efermi)
            print("dft lattice_rec", bs.lattice_rec)
            print("dft structure", bs.structure)

            print("model bands", model_bs.bands[band_keys[0]])
            print("model ktps", len(model_bs.kpoints), kpts.shape)
            print("model labels", model_bs.labels_dict)
            print("model efermi", model_bs.efermi)
            print("model lattice_rec", model_bs.lattice_rec)
            print("model structure", model_bs.structure)

            return bs.bands[band_keys[0]], model_bs.bands[band_keys[0]], labels

            save_files = False if plt else True
            dos_plotter = None
            dos_opts = None
            if dos_file:
                dos, pdos = load_dos(dos_file, elements, lm_orbitals, atoms,
                                     gaussian, total_only)
                dos_plotter = SDOSPlotter(dos, pdos)
                dos_opts = {
                    'plot_total': plot_total,
                    'legend_cutoff': legend_cutoff,
                    'colours': colours,
                    'yscale': yscale
                }

            model_and_dft_bs = [bs, model_bs]
            plotter = SBSPlotter(model_bs)
            print("spin", spin)
            if len(vr.eigenvalues.keys()) == 1:
                spin = None
            print("spin", spin)
            plt = plotter.get_plot(zero_to_efermi=True,
                                   ymin=ymin,
                                   ymax=ymax,
                                   height=height,
                                   width=width,
                                   vbm_cbm_marker=vbm_cbm_marker,
                                   ylabel=ylabel,
                                   plt=plt,
                                   dos_plotter=dos_plotter,
                                   dos_options=dos_opts,
                                   dos_label=dos_label,
                                   fonts=fonts,
                                   style=style,
                                   no_base_style=no_base_style,
                                   spin=spin)

        # don't save if pyplot object provided
        save_files = False if plt else True
        if save_files:
            basename = 'band.{}'.format(image_format)
            filename = '{}_{}'.format(prefix, basename) if prefix else basename
            if directory:
                filename = os.path.join(directory, filename)
            plt.savefig(filename,
                        format=image_format,
                        dpi=dpi,
                        bbox_inches='tight')

            written = [filename]
            written += save_data_files(bs, prefix=prefix, directory=directory)
            return written

        else:
            return plt
Example #19
0
from pymatgen.io.vasp.outputs import BSVasprun
from pymatgen.electronic_structure.plotter import BSPlotter
import pylab
pylab.rcParams.update({'font.size': 48, 'text.usetex': True})


bs = BSVasprun('vasprun.xml')
bst = bs.get_band_structure()

plotter = BSPlotter(bst)
plt = plotter.get_plot()
plt.ylabel("$E - E_f$ (eV)")
plt.xlabel("")
plt.tight_layout()
plt.show()
Example #20
0
def bands_plot(bandpath, dospath, make_bs_plot, make_dos_plot, title=None,
               figsize=(11.69, 8.27), ylim=(-10, 10), bandopt={}, dosopt={},
               legendopt={}):
    """
    Plot the band structure.

    The function assumes a KPOINTS file is present in bandpath folder and the
    band structure calculation was done in line mode.

    Args:
        bandpath (str): path to the vasprun.xml file of the band structure
        dospath (str): path to the vasprun.xml file of the DOS
        make_bs_plot (function): function in order to make the band structure plot
        make_dos_plot (function): function in order to make the DOS plot
        title (str): title of the plot
        figsize (tuple): figure size
        ylim (tuple): y boundaries of the plot
        bandopt (dict): options for the band plot given to make_bs_plot()
        dosopt (dict): options for the dos plot, that are : s, p, d, xlim and linewidth
        legendprop (dict): legend options
    """

    # density of states
    xmldos = os.path.join(dospath, "vasprun.xml")
    print("Reading in file : {0}".format(xmldos))
    dosrun = Vasprun(xmldos)

    # bands
    xmlbands = os.path.join(bandpath, "vasprun.xml")
    print("Reading in file : {0}".format(xmlbands))
    kpoints_file = os.path.join(bandpath, "KPOINTS")
    bandrun = BSVasprun(xmlbands, parse_projected_eigen=True)
    print("Building band structure object")
    bands = bandrun.get_band_structure(kpoints_file,
                                       line_mode=True,
                                       efermi=dosrun.efermi)

    fig = plt.figure(figsize=figsize)
    if not title:
        fig.suptitle("Band structure diagram")
    else:
        fig.suptitle(title)
    if dosrun.is_spin:
        gs = GridSpec(1, 3, width_ratios=[2, 5, 2])
        ax0 = plt.subplot(gs[0])
        ax1 = plt.subplot(gs[1])
        ax2 = plt.subplot(gs[2])
        yticklabels = False
    else:
        gs = GridSpec(1, 2, width_ratios=[2, 1])
        ax1 = plt.subplot(gs[0])
        ax2 = plt.subplot(gs[1])
        yticklabels = True
    gs.update(wspace=0)

    # band structure plot
    print("Making band structure plot")
    make_bs_plot(ax1, bands, yticklabels=yticklabels, **bandopt)

    # Density of states plot
    print("Making DOS plot")
    make_dos_plot(ax2, dosrun, Spin.up, **dosopt)
    if dosrun.is_spin:
        make_dos_plot(ax0, dosrun, Spin.down, **dosopt, reverse=True)

    # plot boundaries and legend
    if dosrun.is_spin:
        ax0.set_ylim(ylim)
        ax0.set_ylabel(r"$E - E_f$   /   eV")
    else:
        ax1.set_ylabel(r"$E - E_f$   /   eV")
    ax1.set_ylim(ylim)
    ax2.set_ylim(ylim)

    ax2.legend(**legendopt)

    print("save fig bsplot.pdf")
    plt.savefig("bsplot.pdf", format="pdf")
Example #21
0
def bandstats(
    filenames=None,
    num_sample_points=3,
    temperature=None,
    degeneracy_tol=1e-4,
    parabolic=True,
):
    """Calculate the effective masses of the bands of a semiconductor.

    Args:
        filenames (:obj:`str` or :obj:`list`, optional): Path to vasprun.xml
            or vasprun.xml.gz file. If no filenames are provided, the code
            will search for vasprun.xml or vasprun.xml.gz files in folders
            named 'split-0*'. Failing that, the code will look for a vasprun in
            the current directory. If a :obj:`list` of vasprun files is
            provided, these will be combined into a single band structure.
        num_sample_points (:obj:`int`, optional): Number of k-points to sample
            when fitting the effective masses.
        temperature (:obj:`int`, optional): Find band edges within kB * T of
            the valence band maximum and conduction band minimum. Not currently
            implemented.
        degeneracy_tol (:obj:`float`, optional): Tolerance for determining the
            degeneracy of the valence band maximum and conduction band minimum.
        parabolic (:obj:`bool`, optional): Use a parabolic fit of the band
            edges. If ``False`` then nonparabolic fitting will be attempted.
            Defaults to ``True``.

    Returns:
        dict: The hole and electron effective masses. Formatted as a
        :obj:`dict` with keys: ``'hole_data'`` and ``'electron_data'``. The
        data is a :obj:`list` of :obj:`dict` with the keys:

        'effective_mass' (:obj:`float`)
            The effective mass in units of electron rest mass, :math:`m_0`.

        'energies' (:obj:`numpy.ndarray`)
            Band eigenvalues in eV.

        'distances' (:obj:`numpy.ndarray`)
            Distances of the k-points in reciprocal space.

        'band_id' (:obj:`int`)
            The index of the band,

        'spin' (:obj:`~pymatgen.electronic_structure.core.Spin`)
            The spin channel

        'start_kpoint' (:obj:`int`)
            The index of the k-point at which the band extrema occurs

        'end_kpoint' (:obj:`int`)
    """
    if not filenames:
        filenames = find_vasprun_files()
    elif isinstance(filenames, str):
        filenames = [filenames]

    bandstructures = []
    for vr_file in filenames:
        vr = BSVasprun(vr_file, parse_projected_eigen=False)
        bs = vr.get_band_structure(line_mode=True)
        bandstructures.append(bs)
    bs = get_reconstructed_band_structure(bandstructures)

    if bs.is_metal():
        logging.error("ERROR: System is metallic!")
        sys.exit()

    _log_band_gap_information(bs)

    vbm_data = bs.get_vbm()
    cbm_data = bs.get_cbm()

    logging.info("\nValence band maximum:")
    _log_band_edge_information(bs, vbm_data)

    logging.info("\nConduction band minimum:")
    _log_band_edge_information(bs, cbm_data)

    if parabolic:
        logging.info("\nUsing parabolic fitting of the band edges")
    else:
        logging.info("\nUsing nonparabolic fitting of the band edges")

    if temperature:
        logging.error("ERROR: This feature is not yet supported!")

    else:
        # Work out where the hole and electron band edges are.
        # Fortunately, pymatgen does this for us. Points at which to calculate
        # the effective mass are identified as a tuple of:
        # (spin, band_index, kpoint_index)
        hole_extrema = []
        for spin, bands in vbm_data["band_index"].items():
            hole_extrema.extend([(spin, band, kpoint) for band in bands
                                 for kpoint in vbm_data["kpoint_index"]])

        elec_extrema = []
        for spin, bands in cbm_data["band_index"].items():
            elec_extrema.extend([(spin, band, kpoint) for band in bands
                                 for kpoint in cbm_data["kpoint_index"]])

        # extract the data we need for fitting from the band structure
        hole_data = []
        for extrema in hole_extrema:
            hole_data.extend(
                get_fitting_data(bs,
                                 *extrema,
                                 num_sample_points=num_sample_points))

        elec_data = []
        for extrema in elec_extrema:
            elec_data.extend(
                get_fitting_data(bs,
                                 *extrema,
                                 num_sample_points=num_sample_points))

    # calculate the effective masses and log the information
    logging.info("\nHole effective masses:")
    for data in hole_data:
        eff_mass = fit_effective_mass(data["distances"],
                                      data["energies"],
                                      parabolic=parabolic)
        data["effective_mass"] = eff_mass
        _log_effective_mass_data(data, bs.is_spin_polarized, mass_type="m_h")

    logging.info("\nElectron effective masses:")
    for data in elec_data:
        eff_mass = fit_effective_mass(data["distances"],
                                      data["energies"],
                                      parabolic=parabolic)
        data["effective_mass"] = eff_mass
        _log_effective_mass_data(data, bs.is_spin_polarized)

    return {"hole_data": hole_data, "electron_data": elec_data}
Example #22
0
def bandplot(filenames=None,
             prefix=None,
             directory=None,
             vbm_cbm_marker=False,
             projection_selection=None,
             mode='rgb',
             interpolate_factor=4,
             circle_size=150,
             dos_file=None,
             ylabel='Energy (eV)',
             dos_label=None,
             elements=None,
             lm_orbitals=None,
             atoms=None,
             total_only=False,
             plot_total=True,
             legend_cutoff=3,
             gaussian=None,
             height=6.,
             width=6.,
             ymin=-6.,
             ymax=6.,
             colours=None,
             yscale=1,
             image_format='pdf',
             dpi=400,
             plt=None,
             fonts=None):
    """Plot electronic band structure diagrams from vasprun.xml files.

    Args:
        filenames (:obj:`str` or :obj:`list`, optional): Path to vasprun.xml
            or vasprun.xml.gz file. If no filenames are provided, the code
            will search for vasprun.xml or vasprun.xml.gz files in folders
            named 'split-0*'. Failing that, the code will look for a vasprun in
            the current directory. If a :obj:`list` of vasprun files is
            provided, these will be combined into a single band structure.
        prefix (:obj:`str`, optional): Prefix for file names.
        directory (:obj:`str`, optional): The directory in which to save files.
        vbm_cbm_marker (:obj:`bool`, optional): Plot markers to indicate the
            VBM and CBM locations.
        projection_selection (list): A list of :obj:`tuple` or :obj:`string`
            identifying which elements and orbitals to project on to the
            band structure. These can be specified by both element and
            orbital, for example, the following will project the Bi s, p
            and S p orbitals::

                [('Bi', 's'), ('Bi', 'p'), ('S', 'p')]

            If just the element is specified then all the orbitals of
            that element are combined. For example, to sum all the S
            orbitals::

                [('Bi', 's'), ('Bi', 'p'), 'S']

            You can also choose to sum particular orbitals by supplying a
            :obj:`tuple` of orbitals. For example, to sum the S s, p, and
            d orbitals into a single projection::

                [('Bi', 's'), ('Bi', 'p'), ('S', ('s', 'p', 'd'))]

            If ``mode = 'rgb'``, a maximum of 3 orbital/element
            combinations can be plotted simultaneously (one for red, green
            and blue), otherwise an unlimited number of elements/orbitals
            can be selected.
        mode (:obj:`str`, optional): Type of projected band structure to
            plot. Options are:

                "rgb"
                    The band structure line color depends on the character
                    of the band. Each element/orbital contributes either
                    red, green or blue with the corresponding line colour a
                    mixture of all three colours. This mode only supports
                    up to 3 elements/orbitals combinations. The order of
                    the ``selection`` :obj:`tuple` determines which colour
                    is used for each selection.
                "stacked"
                    The element/orbital contributions are drawn as a
                    series of stacked circles, with the colour depending on
                    the composition of the band. The size of the circles
                    can be scaled using the ``circle_size`` option.
        circle_size (:obj:`float`, optional): The area of the circles used
            when ``mode = 'stacked'``.
        dos_file (:obj:'str', optional): Path to vasprun.xml file from which to
            read the density of states information. If set, the density of
            states will be plotted alongside the bandstructure.
        elements (:obj:`dict`, optional): The elements and orbitals to extract
            from the projected density of states. Should be provided as a
            :obj:`dict` with the keys as the element names and corresponding
            values as a :obj:`tuple` of orbitals. For example, the following
            would extract the Bi s, px, py and d orbitals::

                {'Bi': ('s', 'px', 'py', 'd')}

            If an element is included with an empty :obj:`tuple`, all orbitals
            for that species will be extracted. If ``elements`` is not set or
            set to ``None``, all elements for all species will be extracted.
        lm_orbitals (:obj:`dict`, optional): The orbitals to decompose into
            their lm contributions (e.g. p -> px, py, pz). Should be provided
            as a :obj:`dict`, with the elements names as keys and a
            :obj:`tuple` of orbitals as the corresponding values. For example,
            the following would be used to decompose the oxygen p and d
            orbitals::

                {'O': ('p', 'd')}

        atoms (:obj:`dict`, optional): Which atomic sites to use when
            calculating the projected density of states. Should be provided as
            a :obj:`dict`, with the element names as keys and a :obj:`tuple` of
            :obj:`int` specifying the atomic indices as the corresponding
            values. The elemental projected density of states will be summed
            only over the atom indices specified. If an element is included
            with an empty :obj:`tuple`, then all sites for that element will
            be included. The indices are 0 based for each element specified in
            the POSCAR. For example, the following will calculate the density
            of states for the first 4 Sn atoms and all O atoms in the
            structure::

                {'Sn': (1, 2, 3, 4), 'O': (, )}

            If ``atoms`` is not set or set to ``None`` then all atomic sites
            for all elements will be considered.
        total_only (:obj:`bool`, optional): Only extract the total density of
            states. Defaults to ``False``.
        plot_total (:obj:`bool`, optional): Plot the total density of states.
            Defaults to ``True``.
        legend_cutoff (:obj:`float`, optional): The cut-off (in % of the
            maximum density of states within the plotting range) for an
            elemental orbital to be labelled in the legend. This prevents
            the legend from containing labels for orbitals that have very
            little contribution in the plotting range.
        gaussian (:obj:`float`, optional): Broaden the density of states using
            convolution with a gaussian function. This parameter controls the
            sigma or standard deviation of the gaussian distribution.
        height (:obj:`float`, optional): The height of the plot.
        width (:obj:`float`, optional): The width of the plot.
        ymin (:obj:`float`, optional): The minimum energy on the y-axis.
        ymax (:obj:`float`, optional): The maximum energy on the y-axis.
        colours (:obj:`dict`, optional): Use custom colours for specific
            element and orbital combinations. Specified as a :obj:`dict` of
            :obj:`dict` of the colours. For example::

                {
                    'Sn': {'s': 'r', 'p': 'b'},
                    'O': {'s': '#000000'}
                }

            The colour can be a hex code, series of rgb value, or any other
            format supported by matplotlib.
        yscale (:obj:`float`, optional): Scaling factor for the y-axis.
        image_format (:obj:`str`, optional): The image file format. Can be any
            format supported by matplotlib, including: png, jpg, pdf, and svg.
            Defaults to pdf.
        dpi (:obj:`int`, optional): The dots-per-inch (pixel density) for
            the image.
        plt (:obj:`matplotlib.pyplot`, optional): A
            :obj:`matplotlib.pyplot` object to use for plotting.
        fonts (:obj:`list`, optional): Fonts to use in the plot. Can be a
            a single font, specified as a :obj:`str`, or several fonts,
            specified as a :obj:`list` of :obj:`str`.

    Returns:
        If ``plt`` set then the ``plt`` object will be returned. Otherwise, the
        method will return a :obj:`list` of filenames written to disk.
    """
    if not filenames:
        filenames = find_vasprun_files()
    elif type(filenames) == str:
        filenames = [filenames]

    # only load the orbital projects if we definitely need them
    parse_projected = True if projection_selection else False

    # now load all the vaspruns and combine them together using the
    # get_reconstructed_band_structure function from pymatgen
    bandstructures = []
    for vr_file in filenames:
        vr = BSVasprun(vr_file, parse_projected_eigen=parse_projected)
        bs = vr.get_band_structure(line_mode=True)
        bandstructures.append(bs)
    bs = get_reconstructed_band_structure(bandstructures)

    # currently not supported as it is a pain to make subplots within subplots,
    # although need to check this is still the case
    if 'split' in mode and dos_file:
        logging.error('ERROR: Plotting split projected band structure with DOS'
                      ' not supported.\nPlease use --projected-rgb or '
                      '--projected-stacked options.')
        sys.exit()

    if (projection_selection and mode == 'rgb'
            and len(projection_selection) > 3):
        logging.error('ERROR: RGB projected band structure only '
                      'supports up to 3 elements/orbitals.'
                      '\nUse alternative --mode setting.')
        sys.exit()

    # don't save if pyplot object provided
    save_files = False if plt else True

    dos_plotter = None
    dos_opts = None
    if dos_file:
        dos, pdos = load_dos(dos_file, elements, lm_orbitals, atoms, gaussian,
                             total_only)
        dos_plotter = SDOSPlotter(dos, pdos)
        dos_opts = {
            'plot_total': plot_total,
            'legend_cutoff': legend_cutoff,
            'colours': colours,
            'yscale': yscale
        }

    plotter = SBSPlotter(bs)
    if projection_selection:
        plt = plotter.get_projected_plot(projection_selection,
                                         mode=mode,
                                         interpolate_factor=interpolate_factor,
                                         circle_size=circle_size,
                                         zero_to_efermi=True,
                                         ymin=ymin,
                                         ymax=ymax,
                                         height=height,
                                         width=width,
                                         vbm_cbm_marker=vbm_cbm_marker,
                                         ylabel=ylabel,
                                         plt=plt,
                                         dos_plotter=dos_plotter,
                                         dos_options=dos_opts,
                                         dos_label=dos_label,
                                         fonts=fonts)
    else:
        plt = plotter.get_plot(zero_to_efermi=True,
                               ymin=ymin,
                               ymax=ymax,
                               height=height,
                               width=width,
                               vbm_cbm_marker=vbm_cbm_marker,
                               ylabel=ylabel,
                               plt=plt,
                               dos_plotter=dos_plotter,
                               dos_options=dos_opts,
                               dos_label=dos_label,
                               fonts=fonts)

    if save_files:
        basename = 'band.{}'.format(image_format)
        filename = '{}_{}'.format(prefix, basename) if prefix else basename
        if directory:
            filename = os.path.join(directory, filename)
        plt.savefig(filename,
                    format=image_format,
                    dpi=dpi,
                    bbox_inches='tight')

        written = [filename]
        written += save_data_files(vr, bs, prefix=prefix, directory=directory)
        return written

    else:
        return plt
Example #23
0
from pymatgen.electronic_structure.plotter import DosPlotter, BSPlotter, BSDOSPlotter
from pymatgen.electronic_structure.dos import Dos, CompleteDos
from pymatgen.electronic_structure.bandstructure import BandStructure, BandStructureSymmLine
from pymatgen.io.vasp.outputs import Vasprun, BSVasprun
from pymatgen.core.structure import Structure
vasp = Vasprun('vasprun.xml')
bsvasp = BSVasprun('vasprun.xml', parse_projected_eigen=True)
structure = Structure.from_file('POSCAR')
#el = structure.composition.elements
#print el
cdos = vasp.complete_dos
#print cdos.get_densities()
tdos = vasp.tdos  #Total dos calculated at the end of run
idos = vasp.idos  # Integrated dos calculated at the end of run
pdos = vasp.pdos  # List of list of PDos objects. Access as pdos[atomindex][orbitalindex]
efermi = vasp.efermi
eigenvalues = vasp.eigenvalues
projected_eigenvalues = vasp.projected_eigenvalues
bs = bsvasp.get_band_structure(line_mode=True)
total_dos = tdos
pdoss = pdos
#CDOS = CompleteDos(structure,total_dos,pdoss)
spd_dos = cdos.get_spd_dos
#print spd_dos
element_dos = cdos.get_element_dos
#element_spd_dos = cdos.get_element_spd_dos(el)
dosplotter = DosPlotter()
Totaldos = dosplotter.add_dos('Total DOS', tdos)
Integrateddos = dosplotter.add_dos('Integrated DOS', idos)
#Pdos = dosplotter.add_dos('Partial DOS',pdos)
#Spd_dos =  dosplotter.add_dos('spd DOS',spd_dos)
Example #24
0
def get_Wif_from_WSWQ(
        wswqs: List,
        initial_vasprun: str,
        def_index: int,
        bulk_index: Sequence[int],
        spin: int = 0,
        kpoint: int = 1,
        fig=None
) -> List:
    """Compute the electron-phonon matrix element using the WSWQ files.

    Read in the WSWQ files to obtain the overlaps. Then compute the electron-
    phonon matrix elements from the overlaps as a function of Q.

    Parameters
    ----------
    wswqs : list((Q, wswq_path))
        a list of tuples where the first value is the Q and the second is the
        path to the directory that contains the WSWQ file
    initial_vasprun : string
        path to the initial vasprun.xml to extract the eigenvalue difference
    def_index : int
        index corresponding to the defect wavefunction (1-based indexing)
    bulk_index : int, list(int)
        index or list of indices corresponding to the bulk wavefunction
        (1-based indexing)
    spin : int
        spin channel to read from (0 - up, 1 - down)
    kpoint : int
        kpoint to read from (defaults to the first kpoint)
    fig : matplotlib.figure.Figure
        optional figure object to plot diagnostic information

    Returns
    -------
    list((bulk_index, Wif))
        electron-phonon matrix element Wif in units of
        eV amu^{-1/2} Angstrom^{-1} for each bulk_index
    """
    bulk_index = np.array(bulk_index)

    Nw, Nbi = (len(wswqs), len(bulk_index))
    Q, matels, deig = (np.zeros(Nw+1), np.zeros((Nbi, Nw+1)), np.zeros(Nbi))

    # first compute the eigenvalue differences
    bvr = BSVasprun(initial_vasprun)
    sp = Spin.up if spin == 0 else Spin.down
    def_eig = bvr.eigenvalues[sp][kpoint-1][def_index-1][0]
    for i, bi in enumerate(bulk_index):
        deig[i] = bvr.eigenvalues[sp][kpoint-1][bi-1][0] - def_eig
    deig = np.abs(deig)

    # now compute for each Q
    for i, (q, fname) in enumerate(wswqs):
        Q[i] = q
        wswq = _read_WSWQ(fname)
        for j, bi in enumerate(bulk_index):
            matels[j, i] = np.sign(q) * \
                np.abs(wswq[(spin+1, kpoint)][(bi, def_index)])

    if fig is not None:
        ax = fig.subplots(1, Nbi)
        ax = np.array(ax)
        for a, i in zip(ax, range(Nbi)):
            tq = np.linspace(np.min(Q), np.max(Q), 100)
            a.scatter(Q, matels[i, :])
            a.plot(tq, np.polyval(np.polyfit(Q, matels[i, :], 1), tq))
            a.set_title(f'{bulk_index[i]}')

    return [(bi, deig[i] * np.polyfit(Q, matels[i, :], 1)[0])
            for i, bi in enumerate(bulk_index)]
Example #25
0
from pymatgen.io.vasp.outputs import BSVasprun
from pymatgen.electronic_structure.plotter import BSPlotter
import os

os.chdir('/home/jinho93/half-metal/1.CrO2/3.band')
vrun = BSVasprun('vasprun.xml')
bs = vrun.get_band_structure('KPOINTS', line_mode=True)
bsp = BSPlotter(bs)

bsp.show()
import pymatgen as mg
from pymatgen.io.vasp.outputs import BSVasprun, Vasprun
from pymatgen import Spin
from pymatgen.electronic_structure.plotter import BSPlotter, BSDOSPlotter, DosPlotter

import matplotlib.pyplot as plt

#The file "vasprun.xml" is in aim_data. Rename it after unzip.
run = BSVasprun("vasprun.xml", parse_projected_eigen=True)

bs = run.get_band_structure("KPOINTS")

print("number of bands", bs.nb_bands)
print("number of kpoints", len(bs.kpoints))
import pymatgen as mg
from pymatgen.io.vasp.outputs import BSVasprun, Vasprun
from pymatgen import Spin
from pymatgen.electronic_structure.plotter import BSPlotter, BSDOSPlotter, DosPlotter

import matplotlib.pyplot as plt



#The file "vasprun.xml" is in aim_data. Rename it after unzip.
run = BSVasprun("vasprun.xml", parse_projected_eigen=True)

bs = run.get_band_structure("KPOINTS")#得到计算能带,(我只查到这个计算能带是vasp中的内容,kpoint是对应的坐标,具体对于VASP我也不是很了解)

print("number of bands", bs.nb_bands)
print("number of kpoints", len(bs.kpoints))

print(bs.is_metal())
print(bs.is_spin_polarized)

print(bs.bands)

print(bs.bands[Spin.up].shape)
print(bs.bands[Spin.down][163,:])
for kpoints,e in zip(bs.kpoints,bs.bands[Spin.down][163,:]):
   print("kx = %5.3f ky = %5.3f kz = %5.3f eps(k) = %8.4f" % (tuple(kpoints.frac_coords) + (e,)))


bsplot = BSPlotter(bs)#这个代码有点错误,好像是跟类型有关,我还没有弄明白

Example #28
0
from pymatgen.electronic_structure.plotter import BSPlotterProjected
from pymatgen.io.vasp.outputs import BSVasprun, Element
path = '/home/jinho93/interface/pzt-bso/loose/opti/band/'
vrun = BSVasprun(path + 'vasprun.xml', True, True)
bs = vrun.get_band_structure(path + 'KPOINTS')
plotter = BSPlotterProjected(bs)
#plt = plotter.get_elt_projected_plots_color(elt_ordered=[Element.O, Element.Hf])
#plt = plotter.get_plot(ylim=(-8, 5), vbm_cbm_marker=True)
plt = plotter.get_elt_projected_plots_color(
    elt_ordered=[Element.Ti, Element.Sn, Element.O])
plt.ylim((-5, 6))
plt.show()
Example #29
0
 def __init__(self, vasprun='vasprun.xml',kpoints='KPOINTS'):
     self.bsrun = BSVasprun(vasprun, parse_potcar_file=False,parse_projected_eigen=True)
     self.bs = self.bsrun.get_band_structure(kpoints)
     self.bsdict = self.bs.as_dict()
Example #30
0
def bandplot(
    filenames=None,
    code="vasp",
    prefix=None,
    directory=None,
    vbm_cbm_marker=False,
    projection_selection=None,
    mode="rgb",
    normalise="all",
    interpolate_factor=4,
    circle_size=150,
    dos_file=None,
    cart_coords=False,
    scissor=None,
    ylabel="Energy (eV)",
    dos_label=None,
    elements=None,
    lm_orbitals=None,
    atoms=None,
    spin=None,
    total_only=False,
    plot_total=True,
    legend_cutoff=3,
    gaussian=None,
    height=None,
    width=None,
    ymin=-6.0,
    ymax=6.0,
    colours=None,
    yscale=1,
    style=None,
    no_base_style=False,
    image_format="pdf",
    dpi=400,
    plt=None,
    fonts=None,
):
    """Plot electronic band structure diagrams from vasprun.xml files.

    Args:
        filenames (:obj:`str` or :obj:`list`, optional): Path to input files:

            Vasp:
                Use vasprun.xml or vasprun.xml.gz file.
            Questaal:
                Path to a bnds.ext file. The extension will also be used to
                find site.ext and syml.ext files in the same directory.
            Castep:
                Path to a seedname.bands file. The prefix ("seedname") is used
                to locate a seedname.cell file in the same directory and read
                in the positions of high-symmetry points.

            If no filenames are provided, sumo
            will search for vasprun.xml or vasprun.xml.gz files in folders
            named 'split-0*'. Failing that, the code will look for a vasprun in
            the current directory. If a :obj:`list` of vasprun files is
            provided, these will be combined into a single band structure.

        code (:obj:`str`, optional): Calculation type. Default is 'vasp';
            'questaal' and 'castep' also supported (with a reduced
            feature-set).
        prefix (:obj:`str`, optional): Prefix for file names.
        directory (:obj:`str`, optional): The directory in which to save files.
        vbm_cbm_marker (:obj:`bool`, optional): Plot markers to indicate the
            VBM and CBM locations.
        projection_selection (list): A list of :obj:`tuple` or :obj:`string`
            identifying which elements and orbitals to project on to the
            band structure. These can be specified by both element and
            orbital, for example, the following will project the Bi s, p
            and S p orbitals::

                [('Bi', 's'), ('Bi', 'p'), ('S', 'p')]

            If just the element is specified then all the orbitals of
            that element are combined. For example, to sum all the S
            orbitals::

                [('Bi', 's'), ('Bi', 'p'), 'S']

            You can also choose to sum particular orbitals by supplying a
            :obj:`tuple` of orbitals. For example, to sum the S s, p, and
            d orbitals into a single projection::

                [('Bi', 's'), ('Bi', 'p'), ('S', ('s', 'p', 'd'))]

            If ``mode = 'rgb'``, a maximum of 3 orbital/element
            combinations can be plotted simultaneously (one for red, green
            and blue), otherwise an unlimited number of elements/orbitals
            can be selected.
        mode (:obj:`str`, optional): Type of projected band structure to
            plot. Options are:

                "rgb"
                    The band structure line color depends on the character
                    of the band. Each element/orbital contributes either
                    red, green or blue with the corresponding line colour a
                    mixture of all three colours. This mode only supports
                    up to 3 elements/orbitals combinations. The order of
                    the ``selection`` :obj:`tuple` determines which colour
                    is used for each selection.
                "stacked"
                    The element/orbital contributions are drawn as a
                    series of stacked circles, with the colour depending on
                    the composition of the band. The size of the circles
                    can be scaled using the ``circle_size`` option.

        normalise (:obj:`str`, optional): Normalisation the projections.
            Options are:

              * ``'all'``: Projections normalised against the sum of all
                   other projections.
              * ``'select'``: Projections normalised against the sum of the
                   selected projections.
              * ``None``: No normalisation performed.

        circle_size (:obj:`float`, optional): The area of the circles used
            when ``mode = 'stacked'``.
        cart_coords (:obj:`bool`, optional): Whether the k-points are read as
            cartesian or reciprocal coordinates. This is only required for
            Questaal output; Vasp output is less ambiguous. Defaults to
            ``False`` (fractional coordinates).
        scissor (:obj:`float`, optional): Apply a scissor operator (rigid shift
            of the CBM), use with caution if applying to metals.
        dos_file (:obj:'str', optional): Path to vasprun.xml file from which to
            read the density of states information. If set, the density of
            states will be plotted alongside the bandstructure.
        elements (:obj:`dict`, optional): The elements and orbitals to extract
            from the projected density of states. Should be provided as a
            :obj:`dict` with the keys as the element names and corresponding
            values as a :obj:`tuple` of orbitals. For example, the following
            would extract the Bi s, px, py and d orbitals::

                {'Bi': ('s', 'px', 'py', 'd')}

            If an element is included with an empty :obj:`tuple`, all orbitals
            for that species will be extracted. If ``elements`` is not set or
            set to ``None``, all elements for all species will be extracted.
        lm_orbitals (:obj:`dict`, optional): The orbitals to decompose into
            their lm contributions (e.g. p -> px, py, pz). Should be provided
            as a :obj:`dict`, with the elements names as keys and a
            :obj:`tuple` of orbitals as the corresponding values. For example,
            the following would be used to decompose the oxygen p and d
            orbitals::

                {'O': ('p', 'd')}

        atoms (:obj:`dict`, optional): Which atomic sites to use when
            calculating the projected density of states. Should be provided as
            a :obj:`dict`, with the element names as keys and a :obj:`tuple` of
            :obj:`int` specifying the atomic indices as the corresponding
            values. The elemental projected density of states will be summed
            only over the atom indices specified. If an element is included
            with an empty :obj:`tuple`, then all sites for that element will
            be included. The indices are 0 based for each element specified in
            the POSCAR. For example, the following will calculate the density
            of states for the first 4 Sn atoms and all O atoms in the
            structure::

                {'Sn': (1, 2, 3, 4), 'O': (, )}

            If ``atoms`` is not set or set to ``None`` then all atomic sites
            for all elements will be considered.
        spin (:obj:`Spin`, optional): Plot only one spin channel from a
            spin-polarised calculation; "up" or "1" for spin up only, "down" or
            "-1" for spin down only. Defaults to ``None``.
        total_only (:obj:`bool`, optional): Only extract the total density of
            states. Defaults to ``False``.
        plot_total (:obj:`bool`, optional): Plot the total density of states.
            Defaults to ``True``.
        legend_cutoff (:obj:`float`, optional): The cut-off (in % of the
            maximum density of states within the plotting range) for an
            elemental orbital to be labelled in the legend. This prevents
            the legend from containing labels for orbitals that have very
            little contribution in the plotting range.
        gaussian (:obj:`float`, optional): Broaden the density of states using
            convolution with a gaussian function. This parameter controls the
            sigma or standard deviation of the gaussian distribution.
        height (:obj:`float`, optional): The height of the plot.
        width (:obj:`float`, optional): The width of the plot.
        ymin (:obj:`float`, optional): The minimum energy on the y-axis.
        ymax (:obj:`float`, optional): The maximum energy on the y-axis.
        style (:obj:`list` or :obj:`str`, optional): (List of) matplotlib style
            specifications, to be composed on top of Sumo base style.
        no_base_style (:obj:`bool`, optional): Prevent use of sumo base style.
            This can make alternative styles behave more predictably.
        colours (:obj:`dict`, optional): Use custom colours for specific
            element and orbital combinations. Specified as a :obj:`dict` of
            :obj:`dict` of the colours. For example::

                {
                    'Sn': {'s': 'r', 'p': 'b'},
                    'O': {'s': '#000000'}
                }

            The colour can be a hex code, series of rgb value, or any other
            format supported by matplotlib.
        yscale (:obj:`float`, optional): Scaling factor for the y-axis.
        image_format (:obj:`str`, optional): The image file format. Can be any
            format supported by matplotlib, including: png, jpg, pdf, and svg.
            Defaults to pdf.
        dpi (:obj:`int`, optional): The dots-per-inch (pixel density) for
            the image.
        plt (:obj:`matplotlib.pyplot`, optional): A
            :obj:`matplotlib.pyplot` object to use for plotting.
        fonts (:obj:`list`, optional): Fonts to use in the plot. Can be a
            a single font, specified as a :obj:`str`, or several fonts,
            specified as a :obj:`list` of :obj:`str`.

    Returns:
        If ``plt`` set then the ``plt`` object will be returned. Otherwise, the
        method will return a :obj:`list` of filenames written to disk.
    """
    if not filenames:
        filenames = find_vasprun_files()
    elif isinstance(filenames, str):
        filenames = [filenames]

    # only load the orbital projects if we definitely need them
    parse_projected = True if projection_selection else False

    # now load all the band structure data and combine using the
    # get_reconstructed_band_structure function from pymatgen
    bandstructures = []
    if code == "vasp":
        for vr_file in filenames:
            vr = BSVasprun(vr_file, parse_projected_eigen=parse_projected)
            bs = vr.get_band_structure(line_mode=True)
            bandstructures.append(bs)
        bs = get_reconstructed_band_structure(bandstructures)
    elif code == "castep":
        for bands_file in filenames:
            cell_file = _replace_ext(bands_file, "cell")
            if os.path.isfile(cell_file):
                logging.info(f"Found cell file {cell_file}...")
            else:
                logging.info(f"Did not find cell file {cell_file}...")
                cell_file = None
            bs = castep_band_structure(bands_file, cell_file=cell_file)
            bandstructures.append(bs)
        bs = get_reconstructed_band_structure(bandstructures)
    elif code == "questaal":
        bnds_file = filenames[0]
        ext = bnds_file.split(".")[-1]
        bnds_folder = os.path.join(bnds_file, os.path.pardir)

        site_file = os.path.abspath(os.path.join(bnds_folder, f"site.{ext}"))

        if os.path.isfile(site_file):
            logging.info("site file found, reading lattice...")
            site_data = QuestaalSite.from_file(site_file)
            bnds_lattice = site_data.structure.lattice
            alat = site_data.alat
        else:
            raise OSError(
                "Site file {} not found: "
                "needed to determine lattice".format(site_file)
            )

        syml_file = os.path.abspath(os.path.join(bnds_folder, f"syml.{ext}"))
        if os.path.isfile(syml_file):
            logging.info("syml file found, reading special-point labels...")
            bnds_labels = labels_from_syml(syml_file)
        else:
            logging.info("syml file not found, band structure lacks labels")
            bnds_labels = {}

        bs = questaal_band_structure(
            bnds_file,
            bnds_lattice,
            alat=alat,
            labels=bnds_labels,
            coords_are_cartesian=cart_coords,
        )

    # currently not supported as it is a pain to make subplots within subplots,
    # although need to check this is still the case
    if "split" in mode and dos_file:
        logging.error(
            "ERROR: Plotting split projected band structure with DOS"
            " not supported.\nPlease use --projected-rgb or "
            "--projected-stacked options."
        )
        sys.exit()

    if projection_selection and mode == "rgb" and len(projection_selection) > 3:
        logging.error(
            "ERROR: RGB projected band structure only "
            "supports up to 3 elements/orbitals."
            "\nUse alternative --mode setting."
        )
        sys.exit()

    # don't save if pyplot object provided
    save_files = False if plt else True

    dos_plotter = None
    dos_opts = None
    if dos_file:
        if code == "vasp":
            dos, pdos = load_dos(
                dos_file, elements, lm_orbitals, atoms, gaussian, total_only
            )
        elif code == "castep":
            pdos_file = None
            if cell_file:
                pdos_file = _replace_ext(cell_file, "pdos_bin")
                if not os.path.isfile(pdos_file):
                    pdos_file = None
                    logging.info(
                        f"PDOS file {pdos_file} does not exist, "
                        "falling back to TDOS."
                    )
                else:
                    logging.info(f"Found PDOS file {pdos_file}")
            else:
                logging.info(
                    f"Cell file {cell_file} does not exist, " "cannot plot PDOS."
                )

            dos, pdos = read_castep_dos(
                dos_file,
                pdos_file=pdos_file,
                cell_file=cell_file,
                gaussian=gaussian,
                lm_orbitals=lm_orbitals,
                elements=elements,
                efermi_to_vbm=True,
            )

        dos_plotter = SDOSPlotter(dos, pdos)
        dos_opts = {
            "plot_total": plot_total,
            "legend_cutoff": legend_cutoff,
            "colours": colours,
            "yscale": yscale,
        }

    if scissor:
        bs = bs.apply_scissor(scissor)

    spin = string_to_spin(spin)  # Convert spin name to pymatgen Spin object
    plotter = SBSPlotter(bs)
    if projection_selection:
        plt = plotter.get_projected_plot(
            projection_selection,
            mode=mode,
            normalise=normalise,
            interpolate_factor=interpolate_factor,
            circle_size=circle_size,
            zero_to_efermi=True,
            ymin=ymin,
            ymax=ymax,
            height=height,
            width=width,
            vbm_cbm_marker=vbm_cbm_marker,
            ylabel=ylabel,
            plt=plt,
            dos_plotter=dos_plotter,
            dos_options=dos_opts,
            dos_label=dos_label,
            fonts=fonts,
            style=style,
            no_base_style=no_base_style,
            spin=spin,
        )
    else:
        plt = plotter.get_plot(
            zero_to_efermi=True,
            ymin=ymin,
            ymax=ymax,
            height=height,
            width=width,
            vbm_cbm_marker=vbm_cbm_marker,
            ylabel=ylabel,
            plt=plt,
            dos_plotter=dos_plotter,
            dos_options=dos_opts,
            dos_label=dos_label,
            fonts=fonts,
            style=style,
            no_base_style=no_base_style,
            spin=spin,
        )

    if save_files:
        basename = f"band.{image_format}"
        filename = f"{prefix}_{basename}" if prefix else basename
        if directory:
            filename = os.path.join(directory, filename)
        plt.savefig(filename, format=image_format, dpi=dpi, bbox_inches="tight")

        written = [filename]
        written += save_data_files(bs, prefix=prefix, directory=directory)
        return written

    else:
        return plt
Example #31
0
import os
from pymatgen.io.vasp.outputs import BSVasprun,Vasprun
from pymatgen.electronic_structure.plotter import BSDOSPlotter

os.chdir('/home/jinho93/oxides/amorphous/igzo/band')
vrun = BSVasprun('vasprun.xml')
vrun2 = Vasprun('vasprun.xml')
bsp = BSDOSPlotter()
plt = bsp.get_plot(vrun.get_band_structure('KPOINTS', line_mode=True),dos=vrun2.complete_dos)
plt.show()
Example #32
0
    def __init__(self, path): 
        r"""
        Initialises an instance of the :class:`~effmass.inputs.Data` class and 
        checks data using :meth:`check_data`.

        Args:
            path (str): Path to vasprun.xml. If the calculation was split along 
            the k-path, the path should be to the folder which contains the 
            splits. i.e. for mapi/split-01/vasprun.xml, mapi/split-02/vasprun.xml
            you would specify path=mapi 
            

        Returns: 
            None.
        """

        super().__init__()

        # read in vasprun
        if path.endswith('vasprun.xml'): 
            if os.path.exists(path):
                vr = BSVasprun(path)
                bs = vr.get_band_structure(line_mode=True)
        
        # read in vaspruns from multiple splits, parse_potcar is false because  
        # it generates useless warnings, parse_projected is false because we
        # don't need projected eigenstates
        else: 
            filenames = []
            for fol in sorted(os.listdir(path)): 
                vr_file = os.path.join(path, fol, "vasprun.xml")
                if os.path.exists(vr_file):
                    filenames.append(vr_file)
            
            bandstructures = []
            for vr_file in filenames:
                vr = BSVasprun(vr_file, parse_projected_eigen=False, 
                parse_potcar_file=False)
                bs = vr.get_band_structure(line_mode=True)
                bandstructures.append(bs)
                
            bs = get_reconstructed_band_structure(bandstructures)

        bs_dict = bs.as_dict()

        # set occupancies below fermi as 0, above fermi as 1
        occupancy = np.array(bs_dict['bands']['1'])
        occupancy[occupancy < bs_dict['efermi']] = 1
        occupancy[occupancy > bs_dict['efermi']] = 0

        # set spin channels 
        spin = 2 if bs_dict['is_spin_polarized'] else 1

        self.spin_channels = spin
        self.number_of_bands = len(bs_dict['bands']['1'])
        self.number_of_kpoints = len(bs_dict['kpoints'])
        self.energies = np.array(bs_dict['bands']['1'])
        self.occupancy = occupancy
        self.kpoints = np.array(bs_dict['kpoints'])
        self.fermi_energy = bs_dict['efermi']
        self.reciprocal_lattice = bs_dict['lattice_rec']['matrix']
        self.CBM = bs_dict['cbm']['energy']
        self.VBM = bs_dict['vbm']['energy']
Example #33
0
        band_gap = _get_bandgap(eigenvalues=eigenvalues_bg)

        band_data = np.append(
            eigenvalues,
            np.tile(kpoints, (eigenvalues.shape[0], 1, 1)),
            axis=2,
        )

        np.save(os.path.join(folder, 'eigenvalues.npy'), band_data)

    return band_gap


if __name__ == "__main__":
    get_bandgap(folder='../../vaspvis_data/band_InAs')
    run = BSVasprun('../../vaspvis_data/band_InAs/vasprun.xml')
    bs = run.get_band_structure('../../vaspvis_data/band_InAs/KPOINTS')
    print(bs.get_vbm()['energy'] - bs.efermi)
    print(bs.get_cbm()['energy'] - bs.efermi)
    print(bs.get_band_gap())
    #  get_bandgap2(folder='../../vaspvis_data/hseInAs')
    #  high_symmetry_points = [
    #  [0.5,0,0.5],
    #  [0,0,0],
    #  [0.5,0,0.5],
    #  ]
    #  M = convert_slab(
    #  bulk_path='./unfold/POSCAR_bulk',
    #  slab_path='./unfold/POSCAR_sub_9_0_orientation_0',
    #  index=[1,1,1],
    #  )