示例#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)
示例#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
示例#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
示例#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")
示例#5
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)
示例#6
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")
示例#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")
     d = vasprun.as_dict()
     self.assertIn("eigenvalues", d["output"])
示例#8
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
示例#9
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}
示例#10
0
def plot(args):
    plt = None
    if args.band or args.bandcheck:
        bsp = BSPlotting(vasprun='vasprun.xml', kpoints='KPOINTS'
                         )  #line the path of vasprun.xml using the argument
        if args.bandcheck:
            bsp.printinform()
        elif args.band:
            para = _load_yaml("B")
            plt = bsp.get_plot(figsize=para["fig_size"],
                               zero_to_efermi=para["zero_to_efermi"],
                               fontsize=para["fontsize"],
                               spindownoff=True,
                               color=para["color"],
                               ylim=para["ylim"],
                               vbm_cbm_marker=para["vbm_cbm_marker"])

    elif args.dos or args.partial:
        para = _load_yaml("D")
        if args.dos:
            f = open(args.name, "r")
            filelist = f.readlines()[1:]
            dp = DOSPlotting(vasprun='vasprun.xml',
                             dos=filelist,
                             zero_to_efermi=para["zero_to_efermi"],
                             stack=para["stack"])
            plt = dp.get_plot(figsize=para["fig_size"],
                              xlim=para["xlim"],
                              ylim=para["ylim"],
                              fontsize=para["font_size"],
                              color=para["color"])
            plt.legend(frameon=False)
        if args.partial:
            if args.name:
                filelist = []
                ylim = []
                color = palettable.colorbrewer.qualitative.Set1_9.mpl_colors
                for e, i in enumerate(args.name):
                    f = open(i, "r")
                    filelist = f.readlines()[1:]
                    dp = DOSPlotting(vasprun='vasprun.xml',
                                     dos=filelist,
                                     zero_to_efermi=para["zero_to_efermi"],
                                     stack=para["stack"])
                    plt = dp.get_plot(figsize=para["fig_size"],
                                      xlim=para["xlim"],
                                      ylim=para["ylim"],
                                      fontsize=para["font_size"],
                                      color=color[e % 9],
                                      label=i.split(".")[0])
                    ax = plt.gca()
                    ylim.append(ax.get_ylim()[-1])
                ax.set_ylim(0, max(ylim))
                plt.legend(fontsize=para["font_size"] / 2,
                           loc="upper right",
                           frameon=False)
            else:
                print("Please use the -n argument")
                sys.exit(0)

            filelist = f.readlines()[1:]

    elif args.bdos:
        run = Vasprun('vasprun.xml', parse_dos=True)
        dos = run.complete_dos
        vrun = BSVasprun('vasprun.xml', parse_projected_eigen=True)
        bs = vrun.get_band_structure('KPOINTS', efermi=dos.efermi)

        bdpara = _load_yaml("BD")
        bsdosplot = BSDOSPlotter(bs_projection=bdpara['bs_projection'],
                                 dos_projection=bdpara['dos_projection'],
                                 vb_energy_range=bdpara['vb_energy_range'],
                                 cb_energy_range=bdpara['cb_energy_range'],
                                 fixed_cb_energy=bdpara['fixed_cb_energy'],
                                 egrid_interval=bdpara['egrid_interval'],
                                 font=bdpara['font'],
                                 axis_fontsize=bdpara['axis_fontsize'],
                                 tick_fontsize=bdpara['tick_fontsize'],
                                 legend_fontsize=bdpara['legend_fontsize'],
                                 bs_legend=bdpara['bs_legend'],
                                 dos_legend=bdpara['dos_legend'],
                                 rgb_legend=bdpara['rgb_legend'],
                                 fig_size=bdpara['fig_size'])
        plt = bsdosplot.get_plot(bs, dos=dos)

    if plt:
        if args.out_file:
            plt.savefig("%s.%s" % (args.out_file, args.format))
        else:
            plt.show()
示例#11
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
示例#12
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

示例#13
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
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))
示例#15
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()
示例#16
0
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)
#Element_dos = dosplotter.add_dos('Element DOS',element_dos)
#Element_spd_dos = dosplotter.add_dos('Element_spd DOS',element_spd_dos)
dos_dict = {
示例#17
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
示例#18
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()
示例#19
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")
示例#20
0
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)#这个代码有点错误,好像是跟类型有关,我还没有弄明白

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(
        dictio={'As': ['px', 'py', 'pz']},
示例#22
0
def bs_graph(rawdatadir, savedir, e_fermi, soc=False):
    run = BSVasprun("{}/vasprun.xml".format(rawdatadir),
                    parse_projected_eigen=True)
    bs = run.get_band_structure(efermi=e_fermi,
                                line_mode=True,
                                force_hybrid_mode=True)
    bsplot = BSPlotter(bs)

    # Get the plot
    bsplot.get_plot(vbm_cbm_marker=True, ylim=(-1.5, 1.5), zero_to_efermi=True)
    bs_graph.e_fermi = float(bs.efermi)
    bs_graph.band_gap = float(bs.get_band_gap()["energy"])
    ax = plt.gca()
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()
    ax.hlines(0, xlim[0], xlim[1], linestyle="--", color="black")
    ax.tick_params(labelsize=20)
    if not soc:
        ax.plot((), (), "r-", label="spin up")
        ax.plot((), (), "b-", label="spin down")
        ax.legend(fontsize=16, loc="upper left")
    plt.savefig("{}/BSGraph".format(savedir))
    plt.close()

    if not soc:
        # Print quick info about band gap (source: vasprun.xml)
        #print(bs_graph.e_fermi)
        #print(bs_graph.band_gap)

        # Get quick info about band gap (source: EIGENVAL)
        eigenval = Eigenval("{}/EIGENVAL".format(rawdatadir))
        bs_graph.band_properties = eigenval.eigenvalue_band_properties

        # Get detailed info about band gap and CB/VB in each spin channel
        # (source: EIGENVAL)
        bs_graph.eigenvalues = eigenval.eigenvalues
        bs_graph.kpoints = eigenval.kpoints
        poscar = Poscar.from_file("{}/POSCAR".format(rawdatadir))
        bs_graph.lattice = poscar.structure.lattice.reciprocal_lattice

        bs_graph.eigenvalues[Spin.up] = bs_graph.eigenvalues[
            Spin.up][:, :, :-1]
        bs_graph.eigenvalues[Spin.down] = bs_graph.eigenvalues[
            Spin.down][:, :, :-1]
        bs_graph.eigenvalues[Spin.up] = bs_graph.eigenvalues[Spin.up][:, :, 0]
        bs_graph.eigenvalues[Spin.down] = bs_graph.eigenvalues[Spin.down][:, :,
                                                                          0]

        bs_graph.eigenvalues[Spin.up] = \
            np.transpose(bs_graph.eigenvalues[Spin.up])
        bs_graph.eigenvalues[Spin.down] = \
            np.transpose(bs_graph.eigenvalues[Spin.down])

        bs = BandStructure(bs_graph.kpoints, bs_graph.eigenvalues,
                           bs_graph.lattice, bs_graph.e_fermi)
        bs_graph.vbm = bs.get_vbm()["energy"]
        bs_graph.cbm = bs.get_cbm()["energy"]
        bs_graph.electronic_gap = bs.get_band_gap()["energy"]
        bs_graph.direct = bs.get_band_gap()["direct"]
        if bs_graph.vbm and bs_graph.cbm and bs_graph.electronic_gap:
            bs_graph.gap_by_spin = bs.get_direct_band_gap_dict()
    return
#!/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()
示例#24
0
        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],
    #  )
    #  generate_kpoints(
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"))
示例#26
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()
示例#27
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
示例#28
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()
示例#29
0
文件: inputs.py 项目: lucydot/effmass
    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']
示例#30
0
dos = dosrun.complete_dos
print("E_Fermi=%f%3s" % (dosrun.efermi, 'eV'))
# print(dos.efermi)

dosplot1 = DosPlotter(sigma=0.05)
dosplot1.add_dos("Total DOS", dos)
plt = dosplot1.get_plot(xlim=(-18, 15))
plt.grid()
plt.savefig("pymatgen_DOS.eps", format="eps")
plt.show()

plt.close()

# bsrun = BSVasprun("Band/vasprun.xml", parse_projected_eigen=True)
bsrun = BSVasprun("Band/vasprun.xml")
bs = bsrun.get_band_structure("Band/KPOINTS")
bsplot = BSPlotter(bs)
plt = bsplot.get_plot(bs)
bsplot.plot_brillouin()
bsplot.get_plot(ylim=(-18, 15), zero_to_efermi=True)
plt.grid()
plt.savefig("pymatgen_Band.eps", format="eps")
plt.show()

plt.close()

# run = BSVasprun("Band/vasprun.xml", parse_projected_eigen=True)
# dosrun = Vasprun("DOS/vasprun.xml", parse_dos=True)
# dosrun = Vasprun("vasprun.xml", parse_dos=True)
# dos = dosrun.complete_dos