Exemplo n.º 1
0
 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
Exemplo n.º 2
0
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()
Exemplo n.º 3
0
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()
Exemplo n.º 4
0
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()