def read(cls, doscar='', efermi=0.0): print(doscar) if Path(doscar[0:(len(doscar)-7)]+'/pbe_bands/vasprun.xml' ).is_file(): try: band_structure = Vasprun(doscar[0:(len(doscar)-7)]+'/pbe_bands/vasprun.xml').get_band_structure() dos = DOS(file=doscar) dos._efermi = 0.0 dos.read_doscar(dos.file) dos.efermi = band_structure.efermi gap = band_structure.get_band_gap() dos.gap = gap['energy'] dos.is_directBG = gap['direct'] except ValueError: raise simulation.analysis.vasp.calculation.VaspError('Could not parse DOSCAR') return dos elif Path(doscar[0:(len(doscar)-7)]+'/hse_bands/vasprun.xml' ).is_file(): try: band_structure = Vasprun(doscar[0:(len(doscar)-7)]+'/hse_bands/vasprun.xml').get_band_structure() dos = DOS(file=doscar) dos._efermi = 0.0 dos.read_doscar(dos.file) dos.efermi = band_structure.efermi gap = band_structure.get_band_gap() dos.gap = gap['energy'] dos.is_directBG = gap['direct'] except ValueError: raise simulation.analysis.vasp.calculation.VaspError('Could not parse DOSCAR') return dos else: try: band_structure = Vasprun(doscar[0:(len(doscar) - 7)] + '/vasprun.xml').get_band_structure() dos = DOS(file=doscar) dos._efermi = 0.0 dos.read_doscar(dos.file) dos.efermi = band_structure.efermi gap = band_structure.get_band_gap() dos.gap = gap['energy'] dos.is_directBG = gap['direct'] except ValueError: raise simulation.analysis.vasp.calculation.VaspError('Could not parse DOSCAR') return dos
def plot_band_alignments(directories, run_type='PBE', fmt='pdf'): """ Plot CBM's and VBM's of all compounds together, relative to the band edges of H2O. Args: directories (list): list of the directory paths for materials to include in the plot. run_type (str): 'PBE' or 'HSE', so that the function knows which subdirectory to go into (pbe_bands or hse_bands). fmt (str): matplotlib format style. Check the matplotlib docs for options. """ if run_type == 'HSE': subdirectory = 'hse_bands' else: subdirectory = 'pbe_bands' band_gaps = {} for directory in directories: sub_dir = os.path.join(directory, subdirectory) if is_converged(sub_dir): os.chdir(sub_dir) band_structure = Vasprun('vasprun.xml').get_band_structure() band_gap = band_structure.get_band_gap() # Vacuum level energy from LOCPOT. locpot = Locpot.from_file('LOCPOT') evac = max(locpot.get_average_along_axis(2)) if not band_structure.is_metal(): is_direct = band_gap['direct'] cbm = band_structure.get_cbm() vbm = band_structure.get_vbm() else: cbm = None vbm = None is_direct = False band_gaps[directory] = {'CBM': cbm, 'VBM': vbm, 'Direct': is_direct, 'Metal': band_structure.is_metal(), 'E_vac': evac} os.chdir('../../') ax = plt.figure(figsize=(16, 10)).gca() x_max = len(band_gaps) * 1.315 ax.set_xlim(0, x_max) # Rectangle representing band edges of water. ax.add_patch(plt.Rectangle((0, -5.67), height=1.23, width=len(band_gaps), facecolor='#00cc99', linewidth=0)) ax.text(len(band_gaps) * 1.01, -4.44, r'$\mathrm{H+/H_2}$', size=20, verticalalignment='center') ax.text(len(band_gaps) * 1.01, -5.67, r'$\mathrm{O_2/H_2O}$', size=20, verticalalignment='center') x_ticklabels = [] y_min = -8 i = 0 # Nothing but lies. are_directs, are_indirects, are_metals = False, False, False for compound in [cpd for cpd in directories if cpd in band_gaps]: x_ticklabels.append(compound) # Plot all energies relative to their vacuum level. evac = band_gaps[compound]['E_vac'] if band_gaps[compound]['Metal']: cbm = -8 vbm = -2 else: cbm = band_gaps[compound]['CBM']['energy'] - evac vbm = band_gaps[compound]['VBM']['energy'] - evac # Add a box around direct gap compounds to distinguish them. if band_gaps[compound]['Direct']: are_directs = True linewidth = 5 elif not band_gaps[compound]['Metal']: are_indirects = True linewidth = 0 # Metals are grey. if band_gaps[compound]['Metal']: are_metals = True linewidth = 0 color_code = '#404040' else: color_code = '#002b80' # CBM ax.add_patch(plt.Rectangle((i, cbm), height=-cbm, width=0.8, facecolor=color_code, linewidth=linewidth, edgecolor="#e68a00")) # VBM ax.add_patch(plt.Rectangle((i, y_min), height=(vbm - y_min), width=0.8, facecolor=color_code, linewidth=linewidth, edgecolor="#e68a00")) i += 1 ax.set_ylim(y_min, 0) # Set tick labels ax.set_xticks([n + 0.4 for n in range(i)]) ax.set_xticklabels(x_ticklabels, family='serif', size=20, rotation=60) ax.set_yticklabels(ax.get_yticks(), family='serif', size=20) # Add a legend height = y_min if are_directs: ax.add_patch(plt.Rectangle((i*1.165, height), width=i*0.15, height=(-y_min*0.1), facecolor='#002b80', edgecolor='#e68a00', linewidth=5)) ax.text(i*1.24, height - y_min * 0.05, 'Direct', family='serif', color='w', size=20, horizontalalignment='center', verticalalignment='center') height -= y_min * 0.15 if are_indirects: ax.add_patch(plt.Rectangle((i*1.165, height), width=i*0.15, height=(-y_min*0.1), facecolor='#002b80', linewidth=0)) ax.text(i*1.24, height - y_min * 0.05, 'Indirect', family='serif', size=20, color='w', horizontalalignment='center', verticalalignment='center') height -= y_min * 0.15 if are_metals: ax.add_patch(plt.Rectangle((i*1.165, height), width=i*0.15, height=(-y_min*0.1), facecolor='#404040', linewidth=0)) ax.text(i*1.24, height - y_min * 0.05, 'Metal', family='serif', size=20, color='w', horizontalalignment='center', verticalalignment='center') # Who needs axes? ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['bottom'].set_visible(False) ax.spines['left'].set_visible(False) ax.yaxis.set_ticks_position('left') ax.xaxis.set_ticks_position('bottom') ax.set_ylabel('eV', family='serif', size=24) if fmt == "None": return ax else: plt.savefig('band_alignments.{}'.format(fmt), transparent=True) plt.close()
def plot_band_alignments(directories, run_type='PBE', fmt='pdf'): """ Plot CBM's and VBM's of all compounds together, relative to the band edges of H2O. Args: directories (list): list of the directory paths for materials to include in the plot. run_type (str): 'PBE' or 'HSE', so that the function knows which subdirectory to go into (pbe_bands or hse_bands). fmt (str): matplotlib format style. Check the matplotlib docs for options. """ if run_type == 'HSE': subdirectory = 'hse_bands' else: subdirectory = 'pbe_bands' band_gaps = {} for directory in directories: sub_dir = os.path.join(directory, subdirectory) if is_converged(sub_dir): os.chdir(sub_dir) band_structure = Vasprun('vasprun.xml').get_band_structure() band_gap = band_structure.get_band_gap() # Vacuum level energy from LOCPOT. locpot = Locpot.from_file('LOCPOT') evac = max(locpot.get_average_along_axis(2)) if not band_structure.is_metal(): is_direct = band_gap['direct'] cbm = band_structure.get_cbm() vbm = band_structure.get_vbm() else: cbm = None vbm = None is_direct = False band_gaps[directory] = { 'CBM': cbm, 'VBM': vbm, 'Direct': is_direct, 'Metal': band_structure.is_metal(), 'E_vac': evac } os.chdir('../../') ax = plt.figure(figsize=(16, 10)).gca() x_max = len(band_gaps) * 1.315 ax.set_xlim(0, x_max) # Rectangle representing band edges of water. ax.add_patch( plt.Rectangle((0, -5.67), height=1.23, width=len(band_gaps), facecolor='#00cc99', linewidth=0)) ax.text(len(band_gaps) * 1.01, -4.44, r'$\mathrm{H+/H_2}$', size=20, verticalalignment='center') ax.text(len(band_gaps) * 1.01, -5.67, r'$\mathrm{O_2/H_2O}$', size=20, verticalalignment='center') x_ticklabels = [] y_min = -8 i = 0 # Nothing but lies. are_directs, are_indirects, are_metals = False, False, False for compound in [cpd for cpd in directories if cpd in band_gaps]: x_ticklabels.append(compound) # Plot all energies relative to their vacuum level. evac = band_gaps[compound]['E_vac'] if band_gaps[compound]['Metal']: cbm = -8 vbm = -2 else: cbm = band_gaps[compound]['CBM']['energy'] - evac vbm = band_gaps[compound]['VBM']['energy'] - evac # Add a box around direct gap compounds to distinguish them. if band_gaps[compound]['Direct']: are_directs = True linewidth = 5 elif not band_gaps[compound]['Metal']: are_indirects = True linewidth = 0 # Metals are grey. if band_gaps[compound]['Metal']: are_metals = True linewidth = 0 color_code = '#404040' else: color_code = '#002b80' # CBM ax.add_patch( plt.Rectangle((i, cbm), height=-cbm, width=0.8, facecolor=color_code, linewidth=linewidth, edgecolor="#e68a00")) # VBM ax.add_patch( plt.Rectangle((i, y_min), height=(vbm - y_min), width=0.8, facecolor=color_code, linewidth=linewidth, edgecolor="#e68a00")) i += 1 ax.set_ylim(y_min, 0) # Set tick labels ax.set_xticks([n + 0.4 for n in range(i)]) ax.set_xticklabels(x_ticklabels, family='serif', size=20, rotation=60) ax.set_yticklabels(ax.get_yticks(), family='serif', size=20) # Add a legend height = y_min if are_directs: ax.add_patch( plt.Rectangle((i * 1.165, height), width=i * 0.15, height=(-y_min * 0.1), facecolor='#002b80', edgecolor='#e68a00', linewidth=5)) ax.text(i * 1.24, height - y_min * 0.05, 'Direct', family='serif', color='w', size=20, horizontalalignment='center', verticalalignment='center') height -= y_min * 0.15 if are_indirects: ax.add_patch( plt.Rectangle((i * 1.165, height), width=i * 0.15, height=(-y_min * 0.1), facecolor='#002b80', linewidth=0)) ax.text(i * 1.24, height - y_min * 0.05, 'Indirect', family='serif', size=20, color='w', horizontalalignment='center', verticalalignment='center') height -= y_min * 0.15 if are_metals: ax.add_patch( plt.Rectangle((i * 1.165, height), width=i * 0.15, height=(-y_min * 0.1), facecolor='#404040', linewidth=0)) ax.text(i * 1.24, height - y_min * 0.05, 'Metal', family='serif', size=20, color='w', horizontalalignment='center', verticalalignment='center') # Who needs axes? ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['bottom'].set_visible(False) ax.spines['left'].set_visible(False) ax.yaxis.set_ticks_position('left') ax.xaxis.set_ticks_position('bottom') ax.set_ylabel('eV', family='serif', size=24) if fmt == "None": return ax else: plt.savefig('band_alignments.{}'.format(fmt), transparent=True) plt.close()
def plot_band_alignments(directories, run_type="PBE", fmt="pdf"): """ Plot CBM's and VBM's of all compounds together, relative to the band edges of H2O. Args: directories (list): list of the directory paths for materials to include in the plot. run_type (str): 'PBE' or 'HSE', so that the function knows which subdirectory to go into (pbe_bands or hse_bands). fmt (str): matplotlib format style. Check the matplotlib docs for options. """ if run_type == "HSE": subdirectory = "hse_bands" else: subdirectory = "pbe_bands" band_gaps = {} for directory in directories: if is_converged("{}/{}".format(directory, subdirectory)): os.chdir("{}/{}".format(directory, subdirectory)) band_structure = Vasprun("vasprun.xml").get_band_structure() band_gap = band_structure.get_band_gap() # Vacuum level energy from LOCPOT. locpot = Locpot.from_file("LOCPOT") evac = max(locpot.get_average_along_axis(2)) try: is_metal = False is_direct = band_gap["direct"] cbm = band_structure.get_cbm() vbm = band_structure.get_vbm() except AttributeError: cbm = None vbm = None is_metal = True is_direct = False band_gaps[directory] = {"CBM": cbm, "VBM": vbm, "Direct": is_direct, "Metal": is_metal, "E_vac": evac} os.chdir("../../") ax = plt.figure(figsize=(16, 10)).gca() x_max = len(band_gaps) * 1.315 ax.set_xlim(0, x_max) # Rectangle representing band edges of water. ax.add_patch(plt.Rectangle((0, -5.67), height=1.23, width=len(band_gaps), facecolor="#00cc99", linewidth=0)) ax.text(len(band_gaps) * 1.01, -4.44, r"$\mathrm{H+/H_2}$", size=20, verticalalignment="center") ax.text(len(band_gaps) * 1.01, -5.67, r"$\mathrm{O_2/H_2O}$", size=20, verticalalignment="center") x_ticklabels = [] y_min = -8 i = 0 # Nothing but lies. are_directs, are_indirects, are_metals = False, False, False for compound in [cpd for cpd in directories if cpd in band_gaps]: x_ticklabels.append(compound) # Plot all energies relative to their vacuum level. evac = band_gaps[compound]["E_vac"] if band_gaps[compound]["Metal"]: cbm = -8 vbm = -2 else: cbm = band_gaps[compound]["CBM"]["energy"] - evac vbm = band_gaps[compound]["VBM"]["energy"] - evac # Add a box around direct gap compounds to distinguish them. if band_gaps[compound]["Direct"]: are_directs = True linewidth = 5 elif not band_gaps[compound]["Metal"]: are_indirects = True linewidth = 0 # Metals are grey. if band_gaps[compound]["Metal"]: are_metals = True linewidth = 0 color_code = "#404040" else: color_code = "#002b80" # CBM ax.add_patch( plt.Rectangle( (i, cbm), height=-cbm, width=0.8, facecolor=color_code, linewidth=linewidth, edgecolor="#e68a00" ) ) # VBM ax.add_patch( plt.Rectangle( (i, y_min), height=(vbm - y_min), width=0.8, facecolor=color_code, linewidth=linewidth, edgecolor="#e68a00", ) ) i += 1 ax.set_ylim(y_min, -2) # Set tick labels ax.set_xticks([n + 0.4 for n in range(i)]) ax.set_xticklabels(x_ticklabels, family="serif", size=20, rotation=60) ax.set_yticklabels(ax.get_yticks(), family="serif", size=20) # Add a legend height = y_min if are_directs: ax.add_patch( plt.Rectangle( (i * 1.165, height), width=i * 0.15, height=(-y_min * 0.1), facecolor="#002b80", edgecolor="#e68a00", linewidth=5, ) ) ax.text( i * 1.24, height - y_min * 0.05, "Direct", family="serif", color="w", size=20, horizontalalignment="center", verticalalignment="center", ) height -= y_min * 0.15 if are_indirects: ax.add_patch( plt.Rectangle((i * 1.165, height), width=i * 0.15, height=(-y_min * 0.1), facecolor="#002b80", linewidth=0) ) ax.text( i * 1.24, height - y_min * 0.05, "Indirect", family="serif", size=20, color="w", horizontalalignment="center", verticalalignment="center", ) height -= y_min * 0.15 if are_metals: ax.add_patch( plt.Rectangle((i * 1.165, height), width=i * 0.15, height=(-y_min * 0.1), facecolor="#404040", linewidth=0) ) ax.text( i * 1.24, height - y_min * 0.05, "Metal", family="serif", size=20, color="w", horizontalalignment="center", verticalalignment="center", ) # Who needs axes? ax.spines["top"].set_visible(False) ax.spines["right"].set_visible(False) ax.spines["bottom"].set_visible(False) ax.spines["left"].set_visible(False) ax.yaxis.set_ticks_position("left") ax.xaxis.set_ticks_position("bottom") ax.set_ylabel("eV", family="serif", size=24) plt.savefig("band_alignments.{}".format(fmt), transparent=True) plt.close()