Пример #1
0
    encut=240,
    ismear=0,
    sigma=0.1,
    nbands=20,
    icharg=11,
    lorbit=11,
    kspacing=1)

Si3.set_calculator(calc3)
en3 = Si2.get_potential_energy()

# ***************************************************************************************************

os.chdir('..')

dosrun = Vasprun("DOS/vasprun.xml", parse_dos=True)
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")
Пример #2
0
    def constrained_opt_run(cls,
                            vasp_cmd,
                            lattice_direction,
                            initial_strain,
                            atom_relax=True,
                            max_steps=20,
                            algo="bfgs",
                            **vasp_job_kwargs):
        """
        Returns a generator of jobs for a constrained optimization run. Typical
        use case is when you want to approximate a biaxial strain situation,
        e.g., you apply a defined strain to a and b directions of the lattice,
        but allows the c-direction to relax.

        Some guidelines on the use of this method:
        i.  It is recommended you do not use the Auto kpoint generation. The
            grid generated via Auto may fluctuate with changes in lattice
            param, resulting in numerical noise.
        ii. Make sure your EDIFF/EDIFFG is properly set in your INCAR. The
            optimization relies on these values to determine convergence.

        Args:
            vasp_cmd (str): Command to run vasp as a list of args. For example,
                if you are using mpirun, it can be something like
                ["mpirun", "pvasp.5.2.11"]
            lattice_direction (str): Which direction to relax. Valid values are
                "a", "b" or "c".
            initial_strain (float): An initial strain to be applied to the
                lattice_direction. This can usually be estimated as the
                negative of the strain applied in the other two directions.
                E.g., if you apply a tensile strain of 0.05 to the a and b
                directions, you can use -0.05 as a reasonable first guess for
                initial strain.
            atom_relax (bool): Whether to relax atomic positions.
            max_steps (int): The maximum number of runs. Defaults to 20 (
                highly unlikely that this limit is ever reached).
            algo (str): Algorithm to use to find minimum. Default is "bfgs",
                which is fast, but can be sensitive to numerical noise
                in energy calculations. The alternative is "bisection",
                which is more robust but can be a bit slow. The code does fall
                back on the bisection when bfgs gives a non-sensical result,
                e.g., negative lattice params.
            \*\*vasp_job_kwargs: Passthrough kwargs to VaspJob. See
                :class:`custodian.vasp.jobs.VaspJob`.

        Returns:
            Generator of jobs. At the end of the run, an "EOS.txt" is written
            which provides a quick look at the E vs lattice parameter.
        """
        nsw = 99 if atom_relax else 0

        incar = Incar.from_file("INCAR")

        # Set the energy convergence criteria as the EDIFFG (if present) or
        # 10 x EDIFF (which itself defaults to 1e-4 if not present).
        if incar.get("EDIFFG") and incar.get("EDIFFG") > 0:
            etol = incar["EDIFFG"]
        else:
            etol = incar.get("EDIFF", 1e-4) * 10

        if lattice_direction == "a":
            lattice_index = 0
        elif lattice_direction == "b":
            lattice_index = 1
        else:
            lattice_index = 2

        energies = {}

        for i in range(max_steps):
            if i == 0:
                settings = [{
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISIF": 2,
                            "NSW": nsw
                        }
                    }
                }]
                structure = Poscar.from_file("POSCAR").structure
                x = structure.lattice.abc[lattice_index]
                backup = True
            else:
                backup = False
                v = Vasprun("vasprun.xml")
                structure = v.final_structure
                energy = v.final_energy
                lattice = structure.lattice

                x = lattice.abc[lattice_index]

                energies[x] = energy

                if i == 1:
                    x *= 1 + initial_strain
                else:
                    # Sort the lattice parameter by energies.
                    min_x = min(energies.keys(), key=lambda e: energies[e])
                    sorted_x = sorted(energies.keys())
                    ind = sorted_x.index(min_x)
                    if ind == 0:
                        other = ind + 1
                    elif ind == len(sorted_x) - 1:
                        other = ind - 1
                    else:
                        other = (ind + 1 if energies[sorted_x[ind + 1]] <
                                 energies[sorted_x[ind - 1]] else ind - 1)
                    if abs(energies[min_x] - energies[sorted_x[other]]) < etol:
                        logger.info("Stopping optimization! Final %s = %f" %
                                    (lattice_direction, min_x))
                        break

                    if ind == 0 and len(sorted_x) > 2:
                        # Lowest energy lies outside of range of lowest value.
                        # we decrease the lattice parameter in the next
                        # iteration to find a minimum. This applies only when
                        # there are at least 3 values.
                        x = sorted_x[0] - abs(sorted_x[1] - sorted_x[0])
                        logger.info("Lowest energy lies below bounds. "
                                    "Setting %s = %f." %
                                    (lattice_direction, x))
                    elif ind == len(sorted_x) - 1 and len(sorted_x) > 2:
                        # Lowest energy lies outside of range of highest value.
                        # we increase the lattice parameter in the next
                        # iteration to find a minimum. This applies only when
                        # there are at least 3 values.
                        x = sorted_x[-1] + abs(sorted_x[-1] - sorted_x[-2])
                        logger.info("Lowest energy lies above bounds. "
                                    "Setting %s = %f." %
                                    (lattice_direction, x))
                    else:
                        if algo.lower() == "bfgs" and len(sorted_x) >= 4:
                            try:
                                # If there are more than 4 data points, we will
                                # do a quadratic fit to accelerate convergence.
                                x1 = list(energies.keys())
                                y1 = [energies[j] for j in x1]
                                z1 = np.polyfit(x1, y1, 2)
                                pp = np.poly1d(z1)
                                from scipy.optimize import minimize

                                result = minimize(pp,
                                                  min_x,
                                                  bounds=[(sorted_x[0],
                                                           sorted_x[-1])])
                                if (not result.success) or result.x[0] < 0:
                                    raise ValueError(
                                        "Negative lattice constant!")
                                x = result.x[0]
                                logger.info("BFGS minimized %s = %f." %
                                            (lattice_direction, x))
                            except ValueError as ex:
                                # Fall back on bisection algo if the bfgs fails.
                                logger.info(str(ex))
                                x = (min_x + sorted_x[other]) / 2
                                logger.info(
                                    "Falling back on bisection %s = %f." %
                                    (lattice_direction, x))
                        else:
                            x = (min_x + sorted_x[other]) / 2
                            logger.info("Bisection %s = %f." %
                                        (lattice_direction, x))

                lattice = lattice.matrix
                lattice[lattice_index] = (
                    lattice[lattice_index] /
                    np.linalg.norm(lattice[lattice_index]) * x)

                s = Structure(lattice, structure.species,
                              structure.frac_coords)
                fname = "POSCAR.%f" % x
                s.to(filename=fname)

                incar_update = {"ISTART": 1, "NSW": nsw, "ISIF": 2}

                settings = [
                    {
                        "dict": "INCAR",
                        "action": {
                            "_set": incar_update
                        }
                    },
                    {
                        "file": fname,
                        "action": {
                            "_file_copy": {
                                "dest": "POSCAR"
                            }
                        }
                    },
                ]

            logger.info("Generating job = %d with parameter %f!" % (i + 1, x))
            yield VaspJob(vasp_cmd,
                          final=False,
                          backup=backup,
                          suffix=".static.%f" % x,
                          settings_override=settings,
                          **vasp_job_kwargs)

        with open("EOS.txt", "wt") as f:
            f.write("# %s energy\n" % lattice_direction)
            for k in sorted(energies.keys()):
                f.write("%f %f\n" % (k, energies[k]))
Пример #3
0
#!/usr/bin/env python
# -*- coding=utf-8 -*-

import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator
from pymatgen.electronic_structure.core import Spin
from pymatgen.io.vasp.outputs import Vasprun

if __name__ == "__main__":
    vasprun_dirctory = '/mnt/c/Users/a/OneDrive/Calculation_Data/Mg2C_Graphene/Paper_results/Bands/data/'
    vasprun_file = 'vasprun.xml'
    kpoints_file = 'KPOINTS'
    saving_dictory = '/mnt/c/Users/a/OneDrive/Calculation_Data/Mg2C_Graphene/Paper_results/Picture/'
    saving_file = '{}'.format('TotBand')
    title = '{}'.format(r"$Mg_2C$" + '-Gr' + ' TotBand')
    vasprun = Vasprun("{}".format(vasprun_dirctory + vasprun_file))
    bands = vasprun.get_band_structure("{}".format(vasprun_dirctory +
                                                   kpoints_file),
                                       line_mode=True,
                                       efermi=vasprun.efermi)

    energy_min = -1
    energy_max = 1
    # 高对称点设置
    labels = [r"$M$", r"$\Gamma$", r"$K$", r"$M$"]
    labels_position = list()
    font = {'family': 'sans-serif', 'size': 24}
    # 开始画图
    fig, ax1 = plt.subplots(figsize=(16, 10))
    # 设置刻度向内
    ax1.tick_params(direction='in')
Пример #4
0
 def test_Xe(self):
     vr = Vasprun(os.path.join(test_dir, 'vasprun.xml.xe'),
                  parse_potcar_file=False)
     self.assertEqual(vr.atomic_symbols, ['Xe'])
Пример #5
0
 def test_vdw(self):
     v = Vasprun(os.path.join(test_dir, "vasprun.xml.vdw"))
     self.assertAlmostEqual(v.final_energy, -9.78310677)
Пример #6
0
 def setUp(self):
     vr = Vasprun(example_dir / "MgB2/vasprun.xml")
     bs = vr.get_band_structure()
     self.band_structure = bs
     self.output_file = test_dir / "fs.png"
Пример #7
0
from pymatgen.electronic_structure.dos import add_densities
from pymatgen.io.vasp.outputs import Vasprun, Dos
from pymatgen.electronic_structure.plotter import DosPlotter
import six
import os
from VASP.vasprun_related.utiles import write_dos
import numpy as np

os.chdir('/home/jinho93/oxides/cluster/tio2/anatase/dos')
vrun = Vasprun('vasprun.xml')
cdos = vrun.complete_dos
arr = []
arr2 = []
num = 0
num2 = 0
for i in vrun.final_structure.sites:
    if 0.425 < i.a < 0.575 and 0.425 < i.b < 0.575 and 0.42 < i.c < 0.58:
        arr.append(cdos.get_site_dos(i).densities)
        num += 1
    else:
        arr2.append(cdos.get_site_dos(i).densities)
        num2 += 1
dos = Dos(cdos.efermi, cdos.energies, six.moves.reduce(add_densities, arr))
dos2 = Dos(cdos.efermi, cdos.energies, six.moves.reduce(add_densities, arr2))
dos.densities = {k: np.array(d / num) for k, d in dos.densities.items()}
dos2.densities = {k: np.array(d / num2) for k, d in dos2.densities.items()}
dsp = DosPlotter()
dsp.add_dos('core', dos2)
write_dos(dos, filename='core.dat')
write_dos(dos2, filename='shell.dat')
dsp.show()
Пример #8
0
 def from_path(cls, path):
     vasprun_loc = zpath('{}/vasprun.xml'.format(path))
     vasprun = Vasprun(vasprun_loc)
     return cls.from_vasprun(vasprun)
Пример #9
0
def get_dos(vasprun_dos):
    ## get CompleteDos object and "save" in hidden div in json format
    dos = Vasprun(vasprun_dos).complete_dos
    return json.dumps(dos.as_dict())
Пример #10
0
#!/usr/bin python
# -*- encoding: utf-8 -*-
'''
@Author  :   Celeste Young
@File    :   能带图.py    
@Time    :   2020/12/30 13:42  
@Tips    :    
'''

import matplotlib.pyplot as plt
from pymatgen.io.vasp.outputs import Vasprun
from pymatgen.electronic_structure.plotter import BSDOSPlotter, BSPlotter, BSPlotterProjected, DosPlotter

bs_vasprun = Vasprun("vasprun.xml", parse_projected_eigen=True)
bs_data = bs_vasprun.get_band_structure(line_mode=True)
dos_data = bs_vasprun.complete_dos

banddos_fig = BSDOSPlotter(bs_projection=None, \
dos_projection=None, vb_energy_range=-5, \
fixed_cb_energy=5)
band_fig = BSPlotter(bs=bs_data)
band_fig.get_plot()
plt.ylim(-2, 1)
Пример #11
0
    def read_phase_diagram_and_chempots(self, full_sub_approach=False, 
                                        include_mp_entries=True):
        """
        Once phase diagram has been set up and run by user (in a folder 
        called "PhaseDiagram"), this method parses and prints the chemical 
        potentials based on the computed entries. The methodology is 
        basically identical to that in the analyze_GGA_chempots method.

        Will supplement unfinished entries with MP database entries 
        unless no_mp_entries is set to False

        Args:
            full_sub_approach: same attribute as described at length in 
                the analyze_GGA_chempots method. Basically, the user can 
                set this to True if they want to mix extrinsic species 
                in the phase diagram

            include_mp_entries: if set to True, extra entries from 
                Materials Project will be added to phase diagram
                according to phases that are stable in the Materials 
                Project database

        """
        pdfile = os.path.join(self.path_base, 'PhaseDiagram')
        if not os.path.exists(pdfile):
            print ('Phase diagram file does not exist at ', pdfile)
            return

        # this is where we read computed entries into a list for parsing...
        # NOTE TO USER: If not running with VASP need to use another
        # pymatgen functionality for importing computed entries below...
        personal_entry_list = []
        for structfile in os.listdir(pdfile):
            if os.path.exists(os.path.join(pdfile, structfile, 'vasprun.xml')):
                try:
                    print('loading ',structfile)
                    vr = Vasprun(
                            os.path.join(pdfile, structfile, 'vasprun.xml'), 
                            parse_potcar_file=False)
                    personal_entry_list.append(vr.get_computed_entry())
                except:
                    print('Could not load ',structfile)

        #add bulk computed entry to phase diagram, and see if it is stable
        if not self.bulk_ce:
            vr_path = os.path.join(self.path_base, 'bulk', 'vasprun.xml')
            if os.path.exists(vr_path):
                print('loading bulk computed entry')
                bulkvr = Vasprun(vr_path)
                self.bulk_ce = bulkvr.get_computed_entry()
            else:
                print ('No bulk entry given locally. Phase diagram ' + \
                       'calculations cannot be set up without this')
                return

        self.bulk_composition = self.bulk_ce.composition
        self.redcomp = self.bulk_composition.reduced_composition

        # Supplement entries to phase diagram with those from MP database 
        if include_mp_entries:
            mpcpa = MPChemPotAnalyzer(
                    bulk_ce=self.bulk_ce, sub_species=self.sub_species, 
                    mapi_key=self.mapi_key)
            tempcl = mpcpa.analyze_GGA_chempots(
                    full_sub_approach=full_sub_approach) # Use MPentries 

            curr_pd = PhaseDiagram(list(set().union(mpcpa.entries['bulk_derived'], mpcpa.entries['subs_set'])))
            stable_idlist = {i.composition.reduced_composition: [i.energy_per_atom, i.entry_id, i] for i in curr_pd.stable_entries}
            for mpcomp, mplist in stable_idlist.items():
                matched = False
                for pe in personal_entry_list:
                    if (pe.composition.reduced_composition == mpcomp):
                        # #USER: uncomment this if you want additional stable phases of identical composition included in your phase diagram
                        # if personalentry.energy_per_atom > mplist[0]:
                        #     print('Adding entry from MP-database:',mpcomp,'(entry-id:',mplist[1])
                        #     personal_entry_list.append(mplist[2])
                        matched = True
                if not matched:
                    print('Adding entry from MP-database:', mpcomp, 
                          '(entry-id:', mplist[1])
                    personal_entry_list.append(mplist[2])
        else:
            personal_entry_list.append(self.bulk_ce)
            #if you dont have entries for elemental corners of phase diagram then code breaks
            #manually inserting entries with energies of zero for competeness...USER DO NOT USE THIS
            eltcount = {elt:0 for elt in set(self.bulk_ce.composition.elements)}
            for pentry in personal_entry_list:
                if pentry.is_element:
                    eltcount[pentry.composition.elements[0]] += 1
            for elt, eltnum in eltcount.items():
                if not eltnum:
                    s = Structure([[1.,0.,0.],[0.,1.,0.],[0.,0.,1.]], [elt],[[0,0,0]])
                    eltentry = ComputedStructureEntry(s, 0.)
                    print('USER! Note that you have added a fake '+str(elt)+' structure to prevent from breaking the '
                          'Phase Diagram Analyzer.\n As a result DO NOT trust the chemical potential results for regions '
                          'of phase diagram that involve the element '+str(elt))
                    personal_entry_list.append(eltentry)


        personal_entry_list.append(self.bulk_ce)

        #compute chemical potentials
        if full_sub_approach:
            pd = PhaseDiagram(personal_entry_list)
            chem_lims = self.get_chempots_from_pd( pd)
        else:
            #first seperate out the bulk associated elements from those of substitutional elements
            entry_list = []
            sub_associated_entry_list = []
            for localentry in personal_entry_list:
                bulk_associated = True
                for elt in localentry.composition.elements:
                    if elt not in self.bulk_composition.elements:
                        bulk_associated = False

                if bulk_associated:
                    entry_list.append(localentry)
                else:
                    sub_associated_entry_list(localentry)

            #now iterate through and collect chemical potentials
            pd = PhaseDiagram(entry_list)
            chem_lims = self.get_chempots_from_pd( pd)

            finchem_lims = {}  # this will be final chem_lims dictionary
            for key in chem_lims.keys():
                face_list = key.split('-')
                blk, blknom, subnom = self.diff_bulk_sub_phases(face_list)
                finchem_lims[blknom] = {}
                finchem_lims[blknom] = chem_lims[key]

            # Now consider adding single elements to extend the phase diagram,
            # adding new additions to chemical potentials ONLY for the cases
            # where the phases in equilibria are those from the bulk phase
            # diagram. This is essentially the assumption that the majority of
            # the elements in the total composition will be from the native
            # species present rather than the sub species (a good approximation)
            for sub_el in self.sub_species:
                sub_specie_entries = entry_list[:]
                for entry in sub_associated_entry_list:
                    if sub_el in entry.composition.elements:
                        sub_specie_entries.append(entry)

                pd = PhaseDiagram(sub_specie_entries)
                chem_lims = self.get_chempots_from_pd(pd)

                for key in chem_lims.keys():
                    face_list = key.split('-')
                    blk, blknom, subnom = self.diff_bulk_sub_phases(
                        face_list, sub_el=sub_el)
                    # if one less than number of bulk species then can be
                    # grouped with rest of structures
                    if len(blk) == len(self.bulk_species_symbol):
                        if blknom not in finchem_lims.keys():
                            finchem_lims[blknom] = chem_lims[key]
                        else:
                            finchem_lims[blknom][sub_el] = \
                                chem_lims[key][sub_el]
                        if 'name-append' not in finchem_lims[blknom].keys():
                            finchem_lims[blknom]['name-append'] = subnom
                        else:
                            finchem_lims[blknom]['name-append'] += '-' + subnom
                    else:
                        # if chem pots determined by two (or more) sub-specie
                        # containing phases, skip this facet!
                        continue

            # run a check to make sure all facets dominantly defined by bulk species
            overdependent_chempot = False
            facets_to_delete = []
            for facet_name, cps in finchem_lims.items():
                cp_key_num = (len(cps.keys()) - 1) if 'name-append' in cps else len(cps.keys())
                if cp_key_num != (len(self.bulk_species_symbol) + len(self.sub_species)):
                    facets_to_delete.append(facet_name)
                    print("Not using facet {} because insufficient number of bulk facets for "
                                "bulk set {} with sub_species set {}. (only dependent on {})."
                                "".format(facet_name, self.bulk_species_symbol, self.sub_species,
                                          cps.get('name-append')))
            if len(facets_to_delete) == len(finchem_lims):
                overdependent_chempot = True
                print(
                    "Determined chemical potentials to be over dependent"
                    " on a substitutional specie. Needing to revert to full_sub_approach. If "
                    "multiple sub species exist this could take a while/break the code...")
            else:
                finchem_lims = {k: v for k, v in finchem_lims.items() if k not in facets_to_delete}

            if not overdependent_chempot:
                chem_lims = {}
                for orig_facet, fc_cp_dict in finchem_lims.items():
                    if 'name-append' not in fc_cp_dict:
                        facet_nom = orig_facet
                    else:
                        full_facet_list = orig_facet.split('-')
                        full_facet_list.extend(fc_cp_dict['name-append'].split('-'))
                        full_facet_list.sort()
                        facet_nom = '-'.join(full_facet_list)
                    chem_lims[facet_nom] = {k: v for k, v in fc_cp_dict.items() if k != 'name-append'}
            else:
                # This is for when overdetermined chempots occur, forcing the full_sub_approach to happen
                for sub, subentries in self.entries['subs_set'].items():
                    for subentry in subentries:
                        entry_list.append(subentry)
                pd = PhaseDiagram(entry_list)
                chem_lims = self.get_chempots_from_pd(pd)

        return chem_lims
Пример #12
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()
Пример #13
0
def dos_graph(rawdatadir,
              savedir,
              total_dos=True,
              by_element=False,
              by_orbital=False):
    dosrun = Vasprun("{}/vasprun.xml".format(rawdatadir), parse_dos=True)
    dos = dosrun.complete_dos

    # Get basic plot
    dos_graph.e_fermi = float(dosrun.efermi)
    dos_graph.band_gap = float(dosrun.eigenvalue_band_properties[0])
    dosplot = DosPlotter()
    #dosplot = DosPlotter(sigma=0.1)
    if total_dos == True:
        dosplot.add_dos("Total DOS", dos)
    if by_element == True:
        dosplot.add_dos_dict(dos.get_element_dos())
    if by_orbital == True:
        dosplot.add_dos_dict(dos.get_spd_dos())
    plt = dosplot.get_plot(xlim=[-3, 3], ylim=[-15, 15], element_colors=True)
    plt.grid()
    plt.savefig("{}/DOSGraph".format(savedir))
    plt.close()

    # Get plot for comparison with SOC total DOS plot
    dosplot = DosPlotter()
    dosplot.add_dos("Total DOS without SOC", dos)
    dosplot.add_dos_dict(dos.get_element_dos())
    plt = dosplot.get_plot_total(xlim=[-3, 3], element_colors=True)
    plt.grid()
    plt.savefig("{}/DOSGraph_tot_DOS by Element without SOC".format(savedir))
    plt.close()

    dosplot = DosPlotter()
    orbitals = {
        "s": Orbital.s,
        "p_y": Orbital.py,
        "p_z": Orbital.pz,
        "p_x": Orbital.px,
        "d_xy": Orbital.dxy,
        "d_yz": Orbital.dyz,
        "d_z2-r2": Orbital.dz2,
        "d_xz": Orbital.dxz,
        "d_x2-y2": Orbital.dx2
    }
    dosplot.add_dos("Total DOS without SOC", dos)
    dosplot.add_dos_dict(dos.get_orbital_dos())
    plt = dosplot.get_plot_total(xlim=[-3, 3])
    plt.grid()
    plt.savefig("{}/DOSGraph_tot_DOS by Orbital without SOC".format(savedir))
    plt.close()
    """
    # Get quick info about band gap (source: EIGENVAL)
    eigenval = Eigenval("{}/EIGENVAL".format(rawdatadir))
    dos_graph.band_properties = eigenval.eigenvalue_band_properties
    """
    # Get detailed info about band gap and CB/VB in each spin channel
    # (source: vasprun.xml)
    dos_graph.majority_vbm = \
        dosrun.tdos.get_cbm_vbm_alt(xlim=[-3,3],e_fermi=dos_graph.e_fermi,
                                    tol=0.3,abs_tol=True,spin=Spin.up)[1]
    dos_graph.majority_cbm = \
        dosrun.tdos.get_cbm_vbm_alt(xlim=[-3,3],e_fermi=dos_graph.e_fermi,
                                    tol=0.3,abs_tol=True,spin=Spin.up)[0]
    dos_graph.minority_vbm = \
        dosrun.tdos.get_cbm_vbm_alt(xlim=[-3,3],e_fermi=dos_graph.e_fermi,
                                    tol=0.3,abs_tol=True,spin=Spin.down)[1]
    dos_graph.minority_cbm = \
        dosrun.tdos.get_cbm_vbm_alt(xlim=[-3,3],e_fermi=dos_graph.e_fermi,
                                    tol=0.3,abs_tol=True,spin=Spin.down)[0]
    dos_graph.majority_gap = \
        dosrun.tdos.get_gap_alt(xlim=[-3,3],e_fermi=dos_graph.e_fermi,
                                tol=0.3,abs_tol=True,spin=Spin.up)
    dos_graph.minority_gap = \
        dosrun.tdos.get_gap_alt(xlim=[-3,3],e_fermi=dos_graph.e_fermi,
                                tol=0.3,abs_tol=True,spin=Spin.down)
    dos_graph.electronic_gap = \
        dosrun.tdos.get_gap_alt(xlim=[-3,3],e_fermi=dos_graph.e_fermi,
                                tol=0.3,abs_tol=True,spin=None)

    return
Пример #14
0
    # feel free to self specify/remove if you're f*****g
    # around with testing/fixing

data = []  # Premake the lofl
# Iterator / / / standard stuff really
for subdir, dirs, files in os.walk(workdir):
    for file in files:
        if file.endswith('OUTCAR'):
            try:
                print(subdir.replace(workdir, ''))
                # load OUTCAR
                file_ou = Outcar(subdir + '/OUTCAR')
                # load POSCAR
                file_POS = Structure.from_file(subdir + '/POSCAR')
                # load vasprun - not sure if this is even working tbh.
                file_vr = Vasprun(subdir + '/vasprun.xml')

                # Add things to a list
                data.append([
                    subdir.replace(workdir, ''), file_POS.composition,
                    file_POS.composition.num_atoms, file_ou.final_energy,
                    file_ou.final_energy / file_POS.composition.num_atoms,
                    file_vr.converged
                ])
            except:  # ignore this painful except catcher - was testing on mostly malformed XMLs and this seemed ideal
                data.append([
                    subdir.replace(workdir, ''), file_POS.composition,
                    file_POS.composition.num_atoms, file_ou.final_energy,
                    file_ou.final_energy / file_POS.composition.num_atoms,
                    '!!!', 'FLAG RAISED'
                ])
Пример #15
0
from pymatgen.analysis.phase_diagram import PhaseDiagram
from pymatgen.entries.computed_entries import (
    CompositionEnergyAdjustment,
    ComputedEntry,
    ComputedStructureEntry,
    ConstantEnergyAdjustment,
    EnergyAdjustment,
    GibbsComputedStructureEntry,
    ManualEnergyAdjustment,
    TemperatureEnergyAdjustment,
)
from pymatgen.io.vasp.outputs import Vasprun
from pymatgen.util.testing import PymatgenTest

filepath = os.path.join(PymatgenTest.TEST_FILES_DIR, "vasprun.xml")
vasprun = Vasprun(filepath)


def test_energyadjustment():
    ea = EnergyAdjustment(10)
    assert ea.name == "Manual adjustment"
    assert ea.cls == {}
    ead = ea.as_dict()
    ea2 = EnergyAdjustment.from_dict(ead)
    assert str(ead) == str(ea2.as_dict())


def test_manual_energy_adjustment():
    ea = ManualEnergyAdjustment(10)
    assert ea.name == "Manual energy adjustment"
    assert ea.value == 10
Пример #16
0
def plot_gamma_surface(fmt='pdf'):
    """
    Collect the energies from a grid of static energy
    calculations to plot the Gamma surface between two layers of the 2D
    material.

    Args:
        fmt (str): matplotlib format style. Check the matplotlib
            docs for options.
    """

    os.chdir('friction/lateral')

    static_dirs = [
        d.split('x') for d in os.listdir(os.getcwd())
        if 'x' in d and len(d) == 3
    ]

    n_divs_x = max([int(d[0]) for d in static_dirs])
    n_divs_y = max([int(d[1]) for d in static_dirs])

    lattice = Structure.from_file('POSCAR').lattice
    area = np.cross(lattice._matrix[0], lattice._matrix[1])[2]

    ax = plt.figure(figsize=(n_divs_x * 1.2, n_divs_y * 1.2)).gca()

    ax.set_xlim(0, n_divs_x + 1)
    ax.set_ylim(0, n_divs_y + 1)

    energies = []

    x_values = range(n_divs_x + 1)
    y_values = range(n_divs_y + 1)

    not_converged = []
    for x in x_values:
        energies.append([])
        for y in y_values:
            dir = '{}x{}'.format(x, y)
            os.chdir(dir)
            try:
                energy = Vasprun('vasprun.xml').final_energy / area
                energies[x].append(energy)
            except:
                not_converged.append('{}x{}'.format(x, y))
                energies[x].append(0)
            os.chdir('../')
        energies[x].append(energies[x][0])

    energies.append([])
    # ENERGY_ARRAY[n_divs_x] = ENERGY_ARRAY[0]

    if not_converged:
        warnings.warn('{} did not converge.'.format(not_converged))
        for coords in not_converged:
            energies[int(coords.split('x')[0])][int(
                coords.split('x')[1])] = energy

    minima = []
    maxima = []
    for x in x_values:
        minima.append(min(energies[x]))
        maxima.append(max(energies[x]))

    abs_minimum = min(minima)
    abs_maximum = max(maxima)

    for x in range(n_divs_x + 1):
        for y in range(n_divs_y + 1):
            # Plot all energies relative to the global minimum.
            scaled_energy = energies[x][y] - abs_minimum
            if '{}x{}'.format(x, y) in not_converged:
                color_code = 'w'
            else:
                color_code = plt.cm.jet(scaled_energy /
                                        (abs_maximum - abs_minimum))

            ax.add_patch(
                plt.Rectangle((x, y),
                              width=1,
                              height=1,
                              facecolor=color_code,
                              linewidth=0))

    # Get rid of annoying ticks.
    ax.axes.get_yaxis().set_ticks([])
    ax.axes.get_xaxis().set_ticks([])

    os.chdir('../../')

    plt.savefig('gamma_surface.{}'.format(fmt), transparent=True)
    plt.close()
Пример #17
0
    subfold = os.path.basename(path)
    # finding charge state from subfolder name
    U_par = subfold.replace('U_', '')
    U = float(U_par)

    # build path of OUTCAR file
    path_vasprun = (dir + 'vasprun.xml')
    # reading vasprun.xml and CONTCAR with pymatgen
    contcar = Poscar.from_file(dir + "CONTCAR")

    structure = contcar.structure.as_dict()
    # getting lattice parameter
    lattice_par = structure['lattice']['a']

    # reading VASP OUTPUT
    vasprun = Vasprun(path_vasprun)
    #getting energy gap
    (gap, cbm, vbm, is_direct) = vasprun.eigenvalue_band_properties

    # writing output file with charge state and total enery
    file_table.write('%f  %f  %f \n' % (U, lattice_par, gap))

file_table.close()
print(f'Data printed in "{system_name}-a-Eg.dat"')
print('')

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(18, 10))
Пример #18
0
def plot_friction_force(fmt='pdf'):
    """
    Plot the sinusoidal curve of delta E between basin and saddle
    points for each normal spacing dz.

    Args:
        fmt (str): matplotlib format style. Check the matplotlib
            docs for options.
    """

    n_surface_atoms = get_number_of_surface_atoms()

    os.chdir('friction/normal')

    f, (ax1, ax2) = plt.subplots(2, figsize=(16, 16))

    spacings = sorted(
        [float(spc) for spc in os.listdir(os.getcwd()) if os.path.isdir(spc)])

    spc_range = spacings[-1] - spacings[0] + 0.1

    for spacing in spacings:
        os.chdir(str(spacing))
        subdirectories = os.listdir(os.getcwd())

        amplitude = abs(
            Vasprun('{}/vasprun.xml'.format(subdirectories[0])).final_energy -
            Vasprun('{}/vasprun.xml'.format(subdirectories[1])).final_energy
        ) / (2 * n_surface_atoms)

        start_coords = Structure.from_file('{}/POSCAR'.format(
            subdirectories[0])).sites[-1].coords
        end_coords = Structure.from_file('{}/POSCAR'.format(
            subdirectories[1])).sites[-1].coords
        dist = np.sqrt((start_coords[0] - end_coords[0])**2 +
                       (start_coords[1] - end_coords[1])**2)

        b = (2 * np.pi) / (dist * 2)

        x = np.arange(0, 4, 0.01)
        sinx = [amplitude * np.sin(b * val) + amplitude for val in x]
        cosx = [
            b * amplitude * np.cos(b * val) if np.cos(b * val) > 0 else 0
            for val in x
        ]

        ax1.plot(x,
                 sinx,
                 linewidth=8,
                 color=plt.cm.jet(-(spacing - 4) / spc_range),
                 label=spacing)
        ax1.set_xticklabels(ax1.get_xticks(), family='serif', fontsize=18)
        ax1.set_yticklabels(ax1.get_yticks(), family='serif', fontsize=18)
        ax1.set_xlabel(r'$\mathrm{\Delta d\/(\AA)}$',
                       family='serif',
                       fontsize=24)
        ax1.set_ylabel(r'$\mathrm{E(z)\/(eV)}$', family='serif', fontsize=24)
        ax2.plot(x,
                 cosx,
                 linewidth=8,
                 color=plt.cm.jet(-(spacing - 4) / spc_range),
                 label=spacing)
        ax2.set_xticklabels(ax2.get_xticks(), family='serif', fontsize=18)
        ax2.set_yticklabels(ax2.get_yticks(), family='serif', fontsize=18)
        ax2.set_xlabel(r'$\mathrm{\Delta d\/(\AA)}$',
                       family='serif',
                       fontsize=24)
        ax2.set_ylabel(r'$\mathrm{F_f\/(eV/\AA)}$',
                       family='serif',
                       fontsize=24)
        os.chdir('../')

    ax1.legend(loc='upper right')
    ax2.legend(loc='upper right')

    os.chdir('../../')

    plt.savefig('F_f.{}'.format(fmt))
Пример #19
0
    def run_task(self, fw_spec):

        get_rdf = self.get('get_rdf') or True
        get_diffusion = self.get('get_diffusion') or True
        get_viscosity = self.get('get_viscosity') or True
        get_vdos = self.get('get_vdos') or True
        get_run_data = self.get('get_run_data') or True
        time_step = self.get('time_step') or 2
        checkpoint_dirs = fw_spec.get('checkpoint_dirs', False)

        calc_dir = get_calc_loc(True, fw_spec["calc_locs"])["path"]
        calc_loc = os.path.join(calc_dir, 'XDATCAR.gz')

        ionic_step_skip = self.get('ionic_step_skip') or 1
        ionic_step_offset = self.get('ionic_step_offset') or 0

        analysis_spec = self.get('analysis_spec') or {}

        if checkpoint_dirs:
            logger.info("LOGGER: Assimilating checkpoint structures")
            ionic_steps = []
            structures = []
            for d in checkpoint_dirs:
                ionic_steps.extend(
                    Vasprun(os.path.join(d, "vasprun.xml.gz")).ionic_steps)

                structures.extend(
                    Vasprun(os.path.join(d, 'vasprun.xml.gz'),
                            ionic_step_skip=ionic_step_skip,
                            ionic_step_offset=ionic_step_offset).structures)

        else:
            structures = Xdatcar(calc_loc).structures

        #write a trajectory file for Dospt
        molecules = []
        for struc in structures:
            molecules.append(
                Molecule(species=struc.species,
                         coords=[s.coords for s in struc.sites]))
        XYZ(mol=molecules).write_file('traj.xyz')

        db_dict = {}
        db_dict.update({'density': float(structures[0].density)})
        db_dict.update(structures[0].composition.to_data_dict)
        db_dict.update({'checkpoint_dirs': checkpoint_dirs})

        if get_rdf:
            logger.info("LOGGER: Calculating radial distribution functions...")
            rdf = RadialDistributionFunction(structures=structures)
            rdf_dat = rdf.get_radial_distribution_functions(nproc=4)
            db_dict.update({'rdf': rdf.get_rdf_db_dict()})
            del rdf
            del rdf_dat

        if get_vdos:
            logger.info("LOGGER: Calculating vibrational density of states...")
            vdos = VDOS(structures)
            vdos_dat = vdos.calc_vdos_spectrum(time_step=time_step *
                                               ionic_step_skip)
            vdos_diff = vdos.calc_diffusion_coefficient(time_step=time_step *
                                                        ionic_step_skip)
            db_dict.update({'vdos': vdos_dat})
            del vdos
            del vdos_dat

        if get_diffusion:
            logger.info("LOGGER: Calculating the diffusion coefficients...")
            diffusion = Diffusion(structures,
                                  t_step=time_step,
                                  l_lim=50,
                                  skip_first=250,
                                  block_l=1000,
                                  ci=0.95)
            D = {'msd': {}, 'vdos': {}}
            for s in structures[0].types_of_specie:
                D['msd'][s.symbol] = diffusion.getD(s.symbol)
            if vdos_diff:
                D['vdos'] = vdos_diff
            db_dict.update({'diffusion': D})
            del D

        if get_viscosity:
            logger.info("LOGGER: Calculating the viscosity...")
            viscosities = []
            if checkpoint_dirs:
                for dir in checkpoint_dirs:
                    visc = Viscosity(dir).calc_viscosity()
                    viscosities.append(visc['viscosity'])
            viscosity_dat = {
                'viscosity': np.mean(viscosities),
                'StdDev': np.std(viscosities)
            }
            db_dict.update({'viscosity': viscosity_dat})
            del viscosity_dat

        if get_run_data:
            if checkpoint_dirs:
                logger.info("LOGGER: Assimilating run stats...")
                data = MD_Data()
                for directory in checkpoint_dirs:
                    data.parse_md_data(directory)
                md_stats = data.get_md_stats()
            else:
                logger.info("LOGGER: Getting run stats...")
                data = MD_Data()
                data.parse_md_data(calc_dir)
                md_stats = data.get_md_stats()
            db_dict.update({'md_data': md_stats})

        if analysis_spec:
            logger.info("LOGGER: Adding user-specified data...")
            db_dict.update(analysis_spec)

        logger.info("LOGGER: Pushing data to database collection...")
        db_file = env_chk(">>db_file<<", fw_spec)
        db = VaspCalcDb.from_db_file(db_file, admin=True)
        db.collection = db.db["md_data"]
        db.collection.insert_one(db_dict)

        return FWAction()
Пример #20
0
def plot_normal_force(basin_dir, fmt='pdf'):
    """
    Plot the LJ-like curve of the energy at the basin point
    as a function of normal spacing dz.

    Args:
        basin_dir (str): directory corresponding to the minimum
            energy on the gamma surface. Generally obtained by the
            get_basin_and_peak_locations() function.
        fmt (str): matplotlib format style. Check the matplotlib
            docs for options.
    """

    n_surface_atoms = get_number_of_surface_atoms()

    os.chdir('friction/normal')
    spacings = [
        float(dir) for dir in os.listdir(os.getcwd()) if os.path.isdir(dir)
    ]
    spacings.sort()

    fig = plt.figure(figsize=(16, 10))
    ax = fig.gca()
    ax2 = ax.twinx()

    abs_E = [
        Vasprun('{}/{}/vasprun.xml'.format(spacing, basin_dir)).final_energy /
        n_surface_atoms for spacing in spacings
    ]
    E = [energy - abs_E[-1] for energy in abs_E]

    spline = interpolate.splrep(spacings, E, s=0)
    xnew = np.arange(spacings[0], spacings[-1], 0.001)
    ynew = interpolate.splev(xnew, spline, der=0)
    ynew_slope = interpolate.splev(spacings, spline, der=1)

    ax.set_xlim(spacings[0], spacings[-1])

    ax.plot([spacings[0], spacings[-1]], [0, 0], '--', color=plt.cm.jet(0))
    ax2.plot([spacings[0], spacings[-1]], [0, 0], '--', color=plt.cm.jet(0.9))
    E_z = ax.plot(xnew,
                  ynew,
                  color=plt.cm.jet(0),
                  linewidth=4,
                  label=r'$\mathrm{E(z)}$')
    F_N = ax2.plot(spacings, [-y for y in ynew_slope],
                   color=plt.cm.jet(0.9),
                   linewidth=4,
                   label=r'$\mathrm{F_N}$')

    ax.set_ylim(ax.get_ylim())

    ax.set_xticklabels(ax.get_xticks(), family='serif', fontsize=18)
    ax.set_yticklabels(ax.get_yticks(), family='serif', fontsize=18)
    ax2.set_yticklabels(ax2.get_yticks(), family='serif', fontsize=18)

    ax.set_xlabel(r'$\mathrm{z\/(\AA)}$', fontsize=24)
    ax.set_ylabel(r'$\mathrm{E(z)\/(eV)}$', fontsize=24)
    ax2.set_ylabel(r'$\mathrm{F_N\/(eV/\AA)}$', fontsize=24)

    data = E_z + F_N
    labs = [l.get_label() for l in data]

    ax.legend(data, labs, loc='upper right', fontsize=24)

    ax.plot(spacings,
            E,
            linewidth=0,
            marker='o',
            color=plt.cm.jet(0),
            markersize=10,
            markeredgecolor='none')

    os.chdir('../../')

    plt.savefig('F_N.{}'.format(fmt))
def _get_vasprun(args):
    
    return Vasprun(args[0], ionic_skipstep=args[1], parse_dos=False, parse_eigen=False)
Пример #22
0
def plot_mu_vs_F_N(basin_dir, fmt='pdf'):
    """
    Plot friction coefficient 'mu' vs. F_Normal.
    mu = F_friction / F_Normal.

    Args:
        basin_dir (str): directory corresponding to the minimum
            energy on the gamma surface. Generally obtained by the
            get_basin_and_peak_locations() function.
        fmt (str): matplotlib format style. Check the matplotlib
            docs for options.
    """

    n_surface_atoms = get_number_of_surface_atoms()

    fig = plt.figure(figsize=(16, 10))
    # ax = fig.gca()
    # ax2 = ax.twinx()

    os.chdir('friction/normal')
    spacings = [
        float(dir) for dir in os.listdir(os.getcwd()) if os.path.isdir(dir)
    ]
    spacings.sort()

    abs_E = [
        Vasprun('{}/{}/vasprun.xml'.format(spacing, basin_dir)).final_energy /
        n_surface_atoms for spacing in spacings
    ]
    E = [energy - abs_E[-1] for energy in abs_E]

    spline = interpolate.splrep(spacings, E, s=0)
    # xnew = np.arange(spacings[0], spacings[-1], 0.001)
    # ynew = interpolate.splev(xnew, spline, der=0)
    ynew_slope = interpolate.splev(spacings, spline, der=1)
    F_N = [-y * 1.602 for y in ynew_slope]
    F_f = []
    sorted_dirs = sorted(
        [float(spc) for spc in os.listdir(os.getcwd()) if os.path.isdir(spc)])

    for spacing in sorted_dirs:
        os.chdir(str(spacing))
        subdirectories = os.listdir(os.getcwd())

        amplitude = abs(
            Vasprun('{}/vasprun.xml'.format(subdirectories[0])).final_energy -
            Vasprun('{}/vasprun.xml'.format(subdirectories[1])).final_energy
        ) / (2 * n_surface_atoms)

        start_coords = Structure.from_file('{}/POSCAR'.format(
            subdirectories[0])).sites[-1].coords
        end_coords = Structure.from_file('{}/POSCAR'.format(
            subdirectories[1])).sites[-1].coords
        dist = np.sqrt((start_coords[0] - end_coords[0])**2 +
                       (start_coords[1] - end_coords[1])**2)

        b = (2 * np.pi) / (dist * 2)

        x = np.arange(0, 4, 0.01)
        # sinx = [amplitude * np.sin(b * val) + amplitude for val in x]
        cosx = [
            b * amplitude * np.cos(b * val) if np.cos(b * val) > 0 else 0
            for val in x
        ]
        F_f.append(max(cosx) * 1.602)
        os.chdir('../')

    os.chdir('../../')

    mu = [f / N for f, N in zip(F_f, F_N)]

    ax = plt.figure().gca()
    ax.plot(F_N,
            mu,
            linewidth=2,
            marker='o',
            markeredgecolor='none',
            markersize=3,
            color=plt.cm.jet(0))
    plt.savefig('mu_vs_F_N.{}'.format(fmt))
Пример #23
0
    def test_update_potcar(self):
        filepath = os.path.join(test_dir, 'vasprun.xml')
        potcar_path = os.path.join(test_dir, 'POTCAR.LiFePO4.gz')
        potcar_path2 = os.path.join(test_dir, 'POTCAR2.LiFePO4.gz')
        vasprun = Vasprun(filepath, parse_potcar_file=False)
        self.assertEqual(vasprun.potcar_spec, [{
            "titel": "PAW_PBE Li 17Jan2003",
            "hash": None
        }, {
            "titel": "PAW_PBE Fe 06Sep2000",
            "hash": None
        }, {
            "titel": "PAW_PBE Fe 06Sep2000",
            "hash": None
        }, {
            "titel": "PAW_PBE P 17Jan2003",
            "hash": None
        }, {
            "titel": "PAW_PBE O 08Apr2002",
            "hash": None
        }])

        vasprun.update_potcar_spec(potcar_path)
        self.assertEqual(vasprun.potcar_spec,
                         [{
                             "titel": "PAW_PBE Li 17Jan2003",
                             "hash": "65e83282d1707ec078c1012afbd05be8"
                         }, {
                             "titel": "PAW_PBE Fe 06Sep2000",
                             "hash": "9530da8244e4dac17580869b4adab115"
                         }, {
                             "titel": "PAW_PBE Fe 06Sep2000",
                             "hash": "9530da8244e4dac17580869b4adab115"
                         }, {
                             "titel": "PAW_PBE P 17Jan2003",
                             "hash": "7dc3393307131ae67785a0cdacb61d5f"
                         }, {
                             "titel": "PAW_PBE O 08Apr2002",
                             "hash": "7a25bc5b9a5393f46600a4939d357982"
                         }])

        vasprun2 = Vasprun(filepath, parse_potcar_file=False)
        self.assertRaises(ValueError, vasprun2.update_potcar_spec,
                          potcar_path2)
        vasprun = Vasprun(filepath, parse_potcar_file=potcar_path)

        self.assertEqual(vasprun.potcar_spec,
                         [{
                             "titel": "PAW_PBE Li 17Jan2003",
                             "hash": "65e83282d1707ec078c1012afbd05be8"
                         }, {
                             "titel": "PAW_PBE Fe 06Sep2000",
                             "hash": "9530da8244e4dac17580869b4adab115"
                         }, {
                             "titel": "PAW_PBE Fe 06Sep2000",
                             "hash": "9530da8244e4dac17580869b4adab115"
                         }, {
                             "titel": "PAW_PBE P 17Jan2003",
                             "hash": "7dc3393307131ae67785a0cdacb61d5f"
                         }, {
                             "titel": "PAW_PBE O 08Apr2002",
                             "hash": "7a25bc5b9a5393f46600a4939d357982"
                         }])

        self.assertRaises(ValueError,
                          Vasprun,
                          filepath,
                          parse_potcar_file=potcar_path2)
Пример #24
0
def get_mu_vs_F_N(basin_dir):
    """
    Essentially the same function as plotting, but without the plot.

    Args:
        basin_dir (str): directory corresponding to the minimum
            energy on the gamma surface. Generally obtained by the
            get_basin_and_peak_locations() function.

    Returns:
        dic: Of the form {'F_N': F_N, 'mu': mu, 'F_f': F_f}, where
            forces are in nN.
    """

    n_surface_atoms = get_number_of_surface_atoms()

    os.chdir('friction/normal')
    spacings = [
        float(dir) for dir in os.listdir(os.getcwd()) if os.path.isdir(dir)
    ]
    spacings.sort()

    abs_E = [
        Vasprun('{}/{}/vasprun.xml'.format(spacing, basin_dir)).final_energy /
        n_surface_atoms for spacing in spacings
    ]
    E = [energy - abs_E[-1] for energy in abs_E]

    spline = interpolate.splrep(spacings, E, s=0)
    xnew = np.arange(spacings[0], spacings[-1], 0.001)
    ynew = interpolate.splev(xnew, spline, der=0)
    ynew_slope = interpolate.splev(spacings, spline, der=1)
    # Convert eV.A to nN
    F_N = [-y * 1.602 for y in ynew_slope]
    F_f = []

    for spacing in sorted(
        [float(spc) for spc in os.listdir(os.getcwd()) if os.path.isdir(spc)]):
        os.chdir(str(spacing))
        subdirectories = os.listdir(os.getcwd())

        try:
            amplitude = abs(
                Vasprun('{}/vasprun.xml'.format(subdirectories[0])).
                final_energy - Vasprun('{}/vasprun.xml'.format(
                    subdirectories[1])).final_energy) / (2 * n_surface_atoms)
        except:
            print(
                'One or more jobs in {}/ have not converged.'.format(spacing))

        start_coords = Structure.from_file('{}/POSCAR'.format(
            subdirectories[0])).sites[-1].coords
        end_coords = Structure.from_file('{}/POSCAR'.format(
            subdirectories[1])).sites[-1].coords
        dist = np.sqrt((start_coords[0] - end_coords[0])**2 +
                       (start_coords[1] - end_coords[1])**2)

        b = (2 * np.pi) / (dist * 2)

        x = np.arange(0, 4, 0.01)
        # sinx = [amplitude * np.sin(b * val) + amplitude for val in x]
        cosx = [
            b * amplitude * np.cos(b * val) if np.cos(b * val) > 0 else 0
            for val in x
        ]
        F_f.append(max(cosx) * 1.602)
        os.chdir('../')

    os.chdir('../../')

    mu = [f / N for f, N in zip(F_f, F_N)]

    return {'F_N': F_N, 'mu': mu, 'F_f': F_f}
Пример #25
0
    def test_properties(self):

        filepath = os.path.join(test_dir, 'vasprun.xml.nonlm')
        vasprun = Vasprun(filepath, parse_potcar_file=False)
        orbs = list(
            vasprun.complete_dos.pdos[vasprun.final_structure[0]].keys())
        self.assertIn(OrbitalType.s, orbs)
        filepath = os.path.join(test_dir, 'vasprun.xml')
        vasprun = Vasprun(filepath, parse_potcar_file=False)

        #Test NELM parsing.
        self.assertEqual(vasprun.parameters["NELM"], 60)
        #test pdos parsing

        pdos0 = vasprun.complete_dos.pdos[vasprun.final_structure[0]]
        self.assertAlmostEqual(pdos0[Orbital.s][Spin.up][16], 0.0026)
        self.assertAlmostEqual(pdos0[Orbital.pz][Spin.down][16], 0.0012)
        self.assertEqual(pdos0[Orbital.s][Spin.up].shape, (301, ))

        filepath2 = os.path.join(test_dir, 'lifepo4.xml')
        vasprun_ggau = Vasprun(filepath2,
                               parse_projected_eigen=True,
                               parse_potcar_file=False)
        totalscsteps = sum(
            [len(i['electronic_steps']) for i in vasprun.ionic_steps])
        self.assertEqual(29, len(vasprun.ionic_steps))
        self.assertEqual(len(vasprun.structures), len(vasprun.ionic_steps))
        self.assertEqual(vasprun.lattice,
                         vasprun.lattice_rec.reciprocal_lattice)

        for i, step in enumerate(vasprun.ionic_steps):
            self.assertEqual(vasprun.structures[i], step["structure"])

        self.assertTrue(
            all([
                vasprun.structures[i] == vasprun.ionic_steps[i]["structure"]
                for i in range(len(vasprun.ionic_steps))
            ]))

        self.assertEqual(308, totalscsteps,
                         "Incorrect number of energies read from vasprun.xml")

        self.assertEqual(['Li'] + 4 * ['Fe'] + 4 * ['P'] + 16 * ["O"],
                         vasprun.atomic_symbols)
        self.assertEqual(vasprun.final_structure.composition.reduced_formula,
                         "LiFe4(PO4)4")
        self.assertIsNotNone(vasprun.incar, "Incar cannot be read")
        self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read")
        self.assertIsNotNone(vasprun.eigenvalues, "Eigenvalues cannot be read")
        self.assertAlmostEqual(vasprun.final_energy, -269.38319884, 7)
        self.assertAlmostEqual(vasprun.tdos.get_gap(), 2.0589, 4)
        expectedans = (2.539, 4.0906, 1.5516, False)
        (gap, cbm, vbm, direct) = vasprun.eigenvalue_band_properties
        self.assertAlmostEqual(gap, expectedans[0])
        self.assertAlmostEqual(cbm, expectedans[1])
        self.assertAlmostEqual(vbm, expectedans[2])
        self.assertEqual(direct, expectedans[3])
        self.assertFalse(vasprun.is_hubbard)
        self.assertEqual(vasprun.potcar_symbols, [
            'PAW_PBE Li 17Jan2003', 'PAW_PBE Fe 06Sep2000',
            'PAW_PBE Fe 06Sep2000', 'PAW_PBE P 17Jan2003',
            'PAW_PBE O 08Apr2002'
        ])
        self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read")
        self.assertIsNotNone(vasprun.actual_kpoints,
                             "Actual kpoints cannot be read")
        self.assertIsNotNone(vasprun.actual_kpoints_weights,
                             "Actual kpoints weights cannot be read")
        for atomdoses in vasprun.pdos:
            for orbitaldos in atomdoses:
                self.assertIsNotNone(orbitaldos, "Partial Dos cannot be read")

        # test skipping ionic steps.
        vasprun_skip = Vasprun(filepath, 3, parse_potcar_file=False)
        self.assertEqual(vasprun_skip.nionic_steps, 29)
        self.assertEqual(len(vasprun_skip.ionic_steps),
                         int(vasprun.nionic_steps / 3) + 1)
        self.assertEqual(len(vasprun_skip.ionic_steps),
                         len(vasprun_skip.structures))
        self.assertEqual(len(vasprun_skip.ionic_steps),
                         int(vasprun.nionic_steps / 3) + 1)
        # Check that nionic_steps is preserved no matter what.
        self.assertEqual(vasprun_skip.nionic_steps, vasprun.nionic_steps)

        self.assertNotAlmostEqual(vasprun_skip.final_energy,
                                  vasprun.final_energy)

        # Test with ionic_step_offset
        vasprun_offset = Vasprun(filepath, 3, 6, parse_potcar_file=False)
        self.assertEqual(len(vasprun_offset.ionic_steps),
                         int(len(vasprun.ionic_steps) / 3) - 1)
        self.assertEqual(vasprun_offset.structures[0],
                         vasprun_skip.structures[2])

        self.assertTrue(vasprun_ggau.is_hubbard)
        self.assertEqual(vasprun_ggau.hubbards["Fe"], 4.3)
        self.assertAlmostEqual(
            vasprun_ggau.projected_eigenvalues[(1, 0, 0, 96, Orbital.s)],
            0.0032)
        d = vasprun_ggau.as_dict()
        self.assertEqual(d["elements"], ["Fe", "Li", "O", "P"])
        self.assertEqual(d["nelements"], 4)

        filepath = os.path.join(test_dir, 'vasprun.xml.unconverged')
        with warnings.catch_warnings(record=True) as w:
            # Cause all warnings to always be triggered.
            warnings.simplefilter("always")
            # Trigger a warning.
            vasprun_unconverged = Vasprun(filepath, parse_potcar_file=False)
            # Verify some things
            self.assertEqual(len(w), 1)
            self.assertTrue(issubclass(w[-1].category, UnconvergedVASPWarning))

            self.assertTrue(vasprun_unconverged.converged_ionic)
            self.assertFalse(vasprun_unconverged.converged_electronic)
            self.assertFalse(vasprun_unconverged.converged)

        filepath = os.path.join(test_dir, 'vasprun.xml.dfpt')
        vasprun_dfpt = Vasprun(filepath, parse_potcar_file=False)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static[0][0], 3.26105533)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static[0][1], -0.00459066)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static[2][2], 3.24330517)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static_wolfe[0][0],
                               3.33402531)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static_wolfe[0][1],
                               -0.00559998)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static_wolfe[2][2],
                               3.31237357)
        self.assertTrue(vasprun_dfpt.converged)

        entry = vasprun_dfpt.get_computed_entry()
        entry = MaterialsProjectCompatibility(
            check_potcar_hash=False).process_entry(entry)
        self.assertAlmostEqual(entry.uncorrected_energy + entry.correction,
                               entry.energy)

        filepath = os.path.join(test_dir, 'vasprun.xml.dfpt.ionic')
        vasprun_dfpt_ionic = Vasprun(filepath, parse_potcar_file=False)
        self.assertAlmostEqual(vasprun_dfpt_ionic.epsilon_ionic[0][0],
                               515.73485838)
        self.assertAlmostEqual(vasprun_dfpt_ionic.epsilon_ionic[0][1],
                               -0.00263523)
        self.assertAlmostEqual(vasprun_dfpt_ionic.epsilon_ionic[2][2],
                               19.02110169)

        filepath = os.path.join(test_dir, 'vasprun.xml.dfpt.unconverged')
        vasprun_dfpt_unconv = Vasprun(filepath, parse_potcar_file=False)
        self.assertFalse(vasprun_dfpt_unconv.converged_electronic)
        self.assertTrue(vasprun_dfpt_unconv.converged_ionic)
        self.assertFalse(vasprun_dfpt_unconv.converged)

        vasprun_uniform = Vasprun(os.path.join(test_dir,
                                               "vasprun.xml.uniform"),
                                  parse_potcar_file=False)
        self.assertEqual(vasprun_uniform.kpoints.style,
                         Kpoints.supported_modes.Reciprocal)

        vasprun_no_pdos = Vasprun(os.path.join(test_dir,
                                               "Li_no_projected.xml"),
                                  parse_potcar_file=False)
        self.assertIsNotNone(vasprun_no_pdos.complete_dos)
        self.assertFalse(vasprun_no_pdos.dos_has_errors)

        vasprun_diel = Vasprun(os.path.join(test_dir,
                                            "vasprun.xml.dielectric"),
                               parse_potcar_file=False)
        self.assertAlmostEqual(0.4294, vasprun_diel.dielectric[0][10])
        self.assertAlmostEqual(19.941, vasprun_diel.dielectric[1][51][0])
        self.assertAlmostEqual(19.941, vasprun_diel.dielectric[1][51][1])
        self.assertAlmostEqual(19.941, vasprun_diel.dielectric[1][51][2])
        self.assertAlmostEqual(0.0, vasprun_diel.dielectric[1][51][3])
        self.assertAlmostEqual(34.186, vasprun_diel.dielectric[2][85][0])
        self.assertAlmostEqual(34.186, vasprun_diel.dielectric[2][85][1])
        self.assertAlmostEqual(34.186, vasprun_diel.dielectric[2][85][2])
        self.assertAlmostEqual(0.0, vasprun_diel.dielectric[2][85][3])

        v = Vasprun(os.path.join(test_dir, "vasprun.xml.indirect.gz"))
        (gap, cbm, vbm, direct) = v.eigenvalue_band_properties
        self.assertFalse(direct)
Пример #26
0
About their differences:
The two methods define differently what is the band gap.
The eigenvalue_band_properties looks at occupations. Here there are partial occupations of your upper bands.
Therefore this depends on the smearing you use.
The Bandstructure.get_band_gap() looks at bands above and below fermi level.
Here there are bands crossing the fermi level. So the method considers it as a metal and gives you a zero band gap.
(see ref: https://github.com/materialsproject/pymatgen/issues/455)
In general, get_band_structure works better.
"""
"""
In addition to the two methods in pymatgen, here, I also provide third method
in which band gap was calculated from DOSCAR to have a cross-check.
"""

# Method 1 and 2 by using pymatgen
parse_vasprun = Vasprun('vasprun.xml')
print(parse_vasprun)

(gap, cbm, vbm, is_direct) = parse_vasprun.eigenvalue_band_properties
print('pymatgen, eigenvalue_band_properties')
print('gap,', "cbm,", "vbm,", "is_direct")
print(gap, cbm, vbm, is_direct)
print('\t')
print('pymatgen, get_band_structure')
bs = parse_vasprun.get_band_structure()
gap = bs.get_band_gap()
print(gap['energy'])

# Method 3 by calculating band gap from DOSCAR
"""
This was inspired by Jeffw Doak https://github.com/jeffwdoak/vasp_scripts/blob/master/vasp_scripts/bandgap.py
Пример #27
0
def vac_antisite_def_parse_energy(mpid, mapi_key=None):
    if not mpid:
        print("============\nERROR: Provide an mpid\n============")
        return

    if not mapi_key:
        with MPRester() as mp:
            structure = mp.get_structure_by_material_id(mpid)
    else:
        with MPRester(mapi_key) as mp:
            structure = mp.get_structure_by_material_id(mpid)

    energy_dict = {}

    antisites = []
    vacancies = []
    def_folders = glob.glob(os.path.join(mpid, "vacancy*"))
    def_folders += glob.glob(os.path.join(mpid, "antisite*"))
    def_folders += glob.glob(os.path.join(mpid, "bulk"))
    for defdir in def_folders:
        fldr_name = os.path.split(defdir)[1]
        vr_file = os.path.join(defdir, 'vasprun.xml')
        if not os.path.exists(vr_file):
            print (fldr_name, ": vasprun.xml doesn't exist in the folder. " \
                   "Abandoning parsing of energies for {}".format(mpid))
            break  # Further processing for the mpid is not useful

        try:
            vr = Vasprun(vr_file)
        except:
            print(
                fldr_name, ":Failure, couldn't parse vaprun.xml file. "
                "Abandoning parsing of energies for {}".format(mpid))
            break

        if not vr.converged:
            print(
                fldr_name, ": Vasp calculation not converged. "
                "Abandoning parsing of energies for {}".format(mpid))
            break  # Further processing for the mpid is not useful

        fldr_fields = fldr_name.split("_")
        if 'bulk' in fldr_fields:
            bulk_energy = vr.final_energy
            bulk_sites = vr.structures[-1].num_sites
        elif 'vacancy' in fldr_fields:
            site_index = int(fldr_fields[1])
            site_multiplicity = int(fldr_fields[2].split("-")[1])
            site_specie = fldr_fields[3].split("-")[1]
            energy = vr.final_energy
            vacancies.append({
                'site_index': site_index,
                'site_specie': site_specie,
                'energy': energy,
                'site_multiplicity': site_multiplicity
            })
        elif 'antisite' in fldr_fields:
            site_index = int(fldr_fields[1])
            site_multiplicity = int(fldr_fields[2].split("-")[1])
            site_specie = fldr_fields[3].split("-")[1]
            substitution_specie = fldr_fields[4].split("-")[1]
            energy = vr.final_energy
            antisites.append({
                'site_index': site_index,
                'site_specie': site_specie,
                'energy': energy,
                'substitution_specie': substitution_specie,
                'site_multiplicity': site_multiplicity
            })
    else:
        print("All calculations successful for {}".format(mpid))
        e0 = bulk_energy / bulk_sites * structure.num_sites
        for vac in vacancies:
            vac_flip_energy = vac['energy'] - bulk_energy
            vac['energy'] = vac_flip_energy
        vacancies.sort(key=lambda entry: entry['site_index'])
        for antisite in antisites:
            as_flip_energy = antisite['energy'] - bulk_energy
            antisite['energy'] = as_flip_energy
        antisites.sort(key=lambda entry: entry['site_index'])
        energy_dict[mpid] = {
            'structure': structure,
            'e0': e0,
            'vacancies': vacancies,
            'antisites': antisites
        }
        return energy_dict

    return {}  # Return Null dict due to failure
Пример #28
0
    def parse_md_data(self, input):
        """
        Parses the md run data from a directory.

        Args:
            input: directory for the md run containing a vasprun.xml and OSZICAR file
        Returns:
             None
        """

        if os.path.isfile(os.path.join(input, 'vasprun.xml.gz')):
            v = Vasprun(os.path.join(input, 'vasprun.xml.gz'))
        elif os.path.isfile(os.path.join(input, 'vasprun.xml')):
            v = Vasprun(os.path.join(input, 'vasprun.xml'))
        else:
            raise FileNotFoundError

        if os.path.isfile(os.path.join(input, 'OSZICAR.gz')):
            o = Oszicar(os.path.join(input, 'OSZICAR.gz'))
        elif os.path.isfile(os.path.join(input, 'OSZICAR')):
            o = Oszicar(os.path.join(input, 'OSZICAR'))
        else:
            raise FileNotFoundError

        self.composition = v.structures[0].composition
        self.volume = v.structures[0].volume

        nsteps = v.nionic_steps
        self.nsteps += nsteps
        if self.time:
            starttime = self.time[-1]
            self.time.extend(
                np.add(
                    np.arange(0, nsteps) * v.parameters['POTIM'], starttime))
        else:
            self.time.extend(np.arange(0, nsteps) * v.parameters['POTIM'])

        pressure = []
        etot = []
        ekin = []
        temp = []
        for i, step in enumerate(o.ionic_steps):
            temp.append(step['T'])
        for i, step in enumerate(v.ionic_steps):
            ekin.append(step['kinetic'])
            etot.append(step['total'])
            stress = step['stress']
            kinP = (2 / 3) * ekin[i]
            pressure.append((1 / 3) * np.trace(stress) + kinP)

        self.md_data['pressure'].extend(pressure)
        self.md_data['etot'].extend(etot)
        self.md_data['ekin'].extend(ekin)
        self.md_data['temp'].extend(temp)

        self.md_acfs['pressure'] = autocorrelation(self.md_data['pressure'],
                                                   normalize=True)
        self.md_acfs['pressure'] = autocorrelation(self.md_data['pressure'],
                                                   normalize=True)
        self.md_acfs['pressure'] = autocorrelation(self.md_data['pressure'],
                                                   normalize=True)
        self.md_acfs['pressure'] = autocorrelation(self.md_data['pressure'],
                                                   normalize=True)
Пример #29
0
def _get_vasprun(args):
    """
    Internal method to support multiprocessing.
    """
    return Vasprun(args[0], ionic_step_skip=args[1],
                   parse_dos=False, parse_eigen=False)
Пример #30
0
def _mp_helper_energy(parse_vacuum,
                      get_core,
                      hkl,
                      path,
                      slab_thickness,
                      vac_thickness,
                      slab_index,
                      core_atom=None,
                      bulk_nn=None,
                      **kwargs):
    """
    Helper function for multiprocessing, returns a list of lists of the main 
    extracted data, electrostatic potential and core energies
    Same args as for parse_fols, only that path is the path to the folder in 
    which the vasprun and OUTCAR for the specific slab/vacuum/index slab are. 
    """
    df_list, electrostatic_list, core_energy_list, gradient_list = (
        [] for i in range(4))

    # instantiate structure, slab, vasprun and outcar objects
    vsp_path = '{}/vasprun.xml'.format(path)
    otc_path = '{}/OUTCAR'.format(path)
    vsp = Vasprun(vsp_path, parse_potcar_file=False)
    otc = Outcar(otc_path)
    slab = slab_from_file(vsp.final_structure, hkl)
    vsp_dict = vsp.as_dict()

    # extract the time data
    otc_times = otc.run_stats

    df_list.append({
        'hkl_string': ''.join(map(str, hkl)),
        'hkl_tuple': hkl,
        'slab_thickness': slab_thickness,
        'vac_thickness': vac_thickness,
        'slab_index': slab_index,
        'atoms': vsp_dict['nsites'],
        'area': slab.surface_area,
        'bandgap': vsp_dict['output']['bandgap'],
        'slab_energy': vsp_dict['output']['final_energy'],
        'slab_per_atom': vsp_dict['output']['final_energy_per_atom'],
        'time_taken': otc_times['Elapsed time (sec)']
    })

    if parse_vacuum:
        electrostatic_list.append(vacuum(path))

        lpt = '{}/LOCPOT'.format(path)
        p = electrostatic_potential(lpt, save_plt=False, save_csv=False)
        # gradient in eV
        g = p['gradient'].to_numpy()
        ratio = int(vac_thickness) / (int(vac_thickness) + int(slab_thickness))
        # check if slab is centred so can get the gradient
        if 0.45 < slab.center_of_mass[2] < 0.55:
            # divide by 2 bc two regions, 0.75 is a scaling factor that
            # should hopefully work to avoid any charge from dangling
            # bonds?
            a = int(len(g) * ratio / 2 * 0.75)
            gradient_list.append(np.mean(g[:a]) * 1000)

        else:
            a = int(len(g) * ratio * 0.75)
            # if atoms are more towards the end of the slab, the start
            # should be vacuum
            if slab.center_of_mass[2] > 0.5:
                gradient_list.append(np.mean(g[:a]) * 1000)
            # and then if atoms are at the start, the vacuum is at
            # the end
            else:
                gradient_list.append(np.mean(g[(len(g) - a):]) * 1000)

    if get_core:
        core_energy_list.append(
            core_energy(core_atom,
                        bulk_nn,
                        outcar=otc_path,
                        structure=slab,
                        **kwargs))

    return [df_list, electrostatic_list, core_energy_list, gradient_list]