def parse_xml(): v = Vasprun("../test_files/vasprun.xml")
def plot_bands(vasprun_dos, vasprun_bands, kpoints, element, ylim = (None, None)): # read data # --------- # kpoints labels # labels = [r"$L$", r"$\Gamma$", r"$X$", r"$U,K$", r"$\Gamma$"] labels = read_kpoint_labels(kpoints) # density of states # dosrun = Vasprun(vasprun_dos) dosrun = Vasprun(vasprun_bands) spd_dos = dosrun.complete_dos.get_spd_dos() # bands run = Vasprun(vasprun_bands, parse_projected_eigen=True) bands = run.get_band_structure(kpoints, line_mode=True, efermi=dosrun.efermi) # set up matplotlib plot # ---------------------- # general options for plot font = {'family': 'serif', 'size': 24} plt.rc('font', **font) # set up 2 graph with aspec ration 2/1 # plot 1: bands diagram # plot 2: Density of States gs = GridSpec(1, 2, width_ratios=[2, 1]) fig = plt.figure(figsize=(11.69, 8.27)) # fig.suptitle("Bands diagram of copper") ax1 = plt.subplot(gs[0]) ax2 = plt.subplot(gs[1]) # , sharey=ax1) # set ylim for the plot # --------------------- if ylim[0]: emin = ylim[0] else: emin = -10. if ylim[1]: emax = ylim[1] else: emax = 10. ax1.set_ylim(emin, emax) ax2.set_ylim(emin, emax) # Band Diagram # ------------ name = element pbands = bands.get_projections_on_elements_and_orbitals({name: ["s", "p", "d"]}) # print(pbands) # compute s, p, d normalized contributions contrib = np.zeros((bands.nb_bands, len(bands.kpoints), 3)) for b in range(bands.nb_bands): for k in range(len(bands.kpoints)): sc = pbands[Spin.up][b][k][name]["s"]**2 pc = pbands[Spin.up][b][k][name]["p"]**2 dc = pbands[Spin.up][b][k][name]["d"]**2 tot = sc + pc + dc if tot != 0.0: contrib[b, k, 0] = sc / tot contrib[b, k, 1] = pc / tot contrib[b, k, 2] = dc / tot # plot bands using rgb mapping for b in range(bands.nb_bands): rgbline(ax1, range(len(bands.kpoints)), [e - bands.efermi for e in bands.bands[Spin.up][b]], contrib[b, :, 0], contrib[b, :, 1], contrib[b, :, 2]) # style ax1.set_xlabel("k-points") ax1.set_ylabel(r"$E - E_f$ / eV") ax1.grid() # fermi level at 0 ax1.hlines(y=0, xmin=0, xmax=len(bands.kpoints), color="k", linestyle = '--', lw=1) # labels nlabs = len(labels) step = len(bands.kpoints) / (nlabs - 1) for i, lab in enumerate(labels): ax1.vlines(i * step, emin, emax, "k") ax1.set_xticks([i * step for i in range(nlabs)]) ax1.set_xticklabels(labels) ax1.set_xlim(0, len(bands.kpoints)) # Density of states # ---------------- ax2.set_yticklabels([]) ax2.grid() ax2.set_xlim(1e-4, 5) ax2.set_xticklabels([]) ax2.hlines(y=0, xmin=0, xmax=5, color="k", lw=2) ax2.set_xlabel("Density of States", labelpad=28) # spd contribution ax2.plot(spd_dos[OrbitalType.s].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "r-", label="3s", lw=2) ax2.plot(spd_dos[OrbitalType.p].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "g-", label="3p", lw=2) ax2.plot(spd_dos[OrbitalType.d].densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, "b-", label="3d", lw=2) # total dos ax2.fill_between(dosrun.tdos.densities[Spin.up], 0, dosrun.tdos.energies - dosrun.efermi, color=(0.7, 0.7, 0.7), facecolor=(0.7, 0.7, 0.7)) ax2.plot(dosrun.tdos.densities[Spin.up], dosrun.tdos.energies - dosrun.efermi, color=(0.6, 0.6, 0.6), label="total DOS") # plot format style # ----------------- ax2.legend(fancybox=True, shadow=True, prop={'size': 18}) plt.subplots_adjust(wspace=0) # plt.show() plt.savefig("figs/bands.png")
def check(self): try: Vasprun("vasprun.xml") except: return True return False
from re import S from pymatgen.core.periodic_table import Specie from pymatgen.core.sites import Site from pymatgen.electronic_structure.core import Spin from pymatgen.electronic_structure.dos import add_densities from pymatgen.io.vasp import Vasprun import matplotlib.pyplot as plt import numpy as np # os.chdir('/home/jinho93/interface/tin-hfo2-tio2/vasp/ag/dos') # os.chdir('/home/jinho93/interface/tin-hfo2-tio2/vasp/ag/vac/dos') os.chdir('/home/jinho93/interface/tin-hfo2-tio2/vasp/ag/dos') os.chdir('/home/jinho93/interface/tin-hfo2-tio2/vasp/ag/vac/dos') os.chdir('/home/jinho93/interface/tin-hfo2-tio2/vasp/ag/dos') os.chdir('/home/jinho93/interface/tin-hfo2-tio2/vasp/ag/dn/ag') vrun = Vasprun('vasprun.xml') s = vrun.final_structure cdos = vrun.complete_dos i: Site # fig = plt.figure() hf_start_point = .31 arr = [] tmp = [] for i in s.sites: if i.c < hf_start_point and (i.species_string == 'Ti' or i.species_string == 'Hf'): if len(tmp) > 3: arr.append(tmp)
def check_valid_folder(mainDir, bond="O_O"): COOP_folders = [] # print(mainDir) coop_folder_list = [ os.path.join(mainDir, f) for f in os.listdir(mainDir) if f.startswith("COOP_") ] if len(coop_folder_list) > 0: # print(coop_folder_list) for folder in coop_folder_list: print(folder) os.chdir(folder) # for bond in ["O_O","M_O"] : print("BOND DIR : {}".format(bond)) bond_dir = os.path.join(folder, bond) if not os.path.exists(bond_dir): os.mkdir(bond_dir) shutil.copy2(os.path.join(folder, "POSCAR"), os.path.join(bond_dir, "POSCAR")) if os.path.exists(os.path.join(bond_dir, "COOPCAR.lobster")): print("lobster done in {}".format(bond_dir)) COOP_folders.append(bond_dir) elif os.path.exists(os.path.join(folder, "vasprun.xml")) \ and platform_id.running_on_cluster(): try: print("attempt to parse vasprun") converged = Vasprun("vasprun.xml").converged except BaseException: converged = False print("corrupted vasprun") if not converged: print("invalid vaspRun") if input("istart=1 and relaunch COOP ? Y/ N : ") == "Y": launch_COOP(folder, rerun=True) else: print("vasprun converged") if not os.path.exists(os.path.join(bond_dir, "lobsterin")): if input("make lobsterin ? Y/N : ") == "Y": importlib.reload(cluster) if not os.path.exists( os.path.join(bond_dir, "POSCAR")): shutil.copy2(os.path.join(folder, "POSCAR"), os.path.join(bond_dir, "POSCAR")) make_lobsterin(bond_dir, bond=bond) if os.path.exists(os.path.join(bond_dir, "lobsterin")): print("On cluster and lobsterin found") if input("launch lobster ? Y/N : ") == "Y": # move lobsterin from the bond_dir to the main folder , # do the lobster # and move everything back to the bond_dir folder shutil.copy2(os.path.join(bond_dir, "lobsterin"), os.path.join(folder, "lobsterin")) subprocess.call(['lobster_coop'], shell=True) for f in ["lobsterin", "lobsterout"] +\ [f for f in os.listdir(folder) if f.endswith(".lobster")]: shutil.move(os.path.join(folder, f), os.path.join(bond_dir, f)) if os.path.exists( os.path.join(bond_dir, "COOPCAR.lobster")): print("lobster done") COOP_folders.append(bond_dir) else: print("No COOP folder found !") if platform_id.running_on_cluster(): if input("launch NC run to prepare COOP ? Y/N : ") == "Y": prepare_COOP(mainDir) return (COOP_folders)
def band_edge_properties(args: Namespace): vasprun = Vasprun(args.vasprun) outcar = Outcar(args.outcar) print(VaspBandEdgeProperties(vasprun, outcar))
#Making the pymatgen plots not quite as ugly from pymatgen.io.vasp import Vasprun import matplotlib.pyplot as plt import class_ as myClass #Stuff to force times new roman style plt.rcParams["font.family"] = "Times New Roman" plt.rcParams["mathtext.fontset"] = "dejavuserif" plt.tight_layout = False #Initialize a vasprun instance and a myClass instance v = Vasprun("C://Users//baron//Desktop//xmlgen//vasprun.xml.AgBiI4") test = myClass.TempName(v) test.AutoCreateGraph(v, xLims=[-5, 5], saveLoc="C://Users//baron//Desktop//pleaseBroPlease.pdf") #if(test.IsLDecomposed(v)): # #Add elements to the plot. In this case, add all of them. Sigma = (cubic) spline smoothing # for elem in test.uniqueElements: # test.GetElementDosPlot(elem, sigma = 0.065) # # # #Customize the plot with whatever else you want # plt.title("hello :)") # plt.xlabel(r"$E-E_\mathrm{F}$ (eV)") # plt.ylabel("DOS (states / eV)") # test.GenerateLegend() # if(not test.spinPol):
x = cdos.energies - cdos.efermi for j in range(6): y = np.zeros(len(cdos.energies)) for i in range(5 * j + 210, 5 * (j + 1) + 210): x, yi = get_eels(i) y += yi np.savetxt(f'y{j}.dat', y) y /= 30 plt.plot(x, y) plt.show() if __name__ == '__main__': os.chdir('/home/jinho93/oxides/wurtzite/zno/vasp/6.155/dense/nbands/4') # os.chdir('/home/jinho93/oxides/wurtzite/zno/vasp/7.eels/rec/High/core_hole/in_tuto/hyd/supc/O-k/far/maximal/6') v = Vasprun(filename='vasprun.xml') s = v.final_structure cdos = v.complete_dos y = np.zeros(len(cdos.energies)) n = 0 for i in range(17, 17 + 16): name = [r.species_string for r in s.get_neighbors(s.sites[i], 2)] if 'O' in name: print(i) continue x, yi = get_eels(i) y += yi n += 1 y /= n plt.plot(x, y) np.savetxt(f'zn.dat', y)
def Get_DielTensor(self, filepath): vasprun = Vasprun(filepath + "vasprun.xml") self.electensor = np.array(vasprun.epsilon_static) self.iontensor = np.array(vasprun.epsilon_ionic)
def optplot( modes=("absorption",), filenames=None, codes="vasp", prefix=None, directory=None, gaussian=None, band_gaps=None, labels=None, average=True, height=6, width=6, xmin=0, xmax=None, ymin=0, ymax=1e5, colours=None, style=None, no_base_style=None, image_format="pdf", dpi=400, plt=None, fonts=None, units="eV", ): """A script to plot optical absorption spectra from VASP calculations. Args: modes (:obj:`list` or :obj:`tuple`): Ordered list of :obj:`str` determining properties to plot. Accepted options are 'absorption' (default), 'eps', 'eps-real', 'eps-im', 'n', 'n-real', 'n-im', 'loss' (equivalent to n-im). filenames (:obj:`str` or :obj:`list`, optional): Path to data file. For VASP this is a *vasprun.xml* file (can be gzipped); for Questaal the *opt.ext* file from *lmf* or *eps_BSE.out* from *bethesalpeter* may be used. Alternatively, a list of paths can be provided, in which case the absorption spectra for each will be plotted concurrently. codes (:obj:`str` or :obj:`list`, optional): Original calculator. Accepted values are 'vasp' and 'questaal'. Items should correspond to filenames. prefix (:obj:`str`, optional): Prefix for file names. directory (:obj:`str`, optional): The directory in which to save files. gaussian (:obj:`float`): Standard deviation for gaussian broadening. band_gaps (:obj:`float`, :obj:`str` or :obj:`list`, optional): The band gap as a :obj:`float`, in eV, plotted as a dashed line. If plotting multiple spectra then a :obj:`list` of band gaps can be provided. Band gaps can be provided as a floating-point number or as a path to a *vasprun.xml* file. To skip over a line, set its bandgap to zero or a negative number to place it outside the visible range. labels (:obj:`str` or :obj:`list`): A label to identify the spectra. If plotting multiple spectra then a :obj:`list` of labels can be provided. average (:obj:`bool`, optional): Average the dielectric response across all lattice directions. Defaults to ``True``. height (:obj:`float`, optional): The height of the plot. width (:obj:`float`, optional): The width of the plot. xmin (:obj:`float`, optional): The minimum energy on the x-axis. xmax (:obj:`float`, optional): The maximum energy on the x-axis. ymin (:obj:`float`, optional): The minimum absorption intensity on the y-axis. ymax (:obj:`float`, optional): The maximum absorption intensity on the y-axis. colours (:obj:`list`, optional): A :obj:`list` of colours to use in the plot. The colours can be specified as a hex code, set of rgb values, or any other format supported by matplotlib. 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. 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`. units (:obj:`str`, optional): X-axis units for the plot. 'eV' for energy in electronvolts or 'nm' for wavelength in nanometers. Defaults to 'eV'. Returns: A matplotlib pyplot object. """ # Don't write files if this is being done to manipulate existing plt save_files = False if plt else True # BUILD LIST OF FILES AUTOMATICALLY IF NECESSARY if codes == "vasp": if not filenames: if os.path.exists("vasprun.xml"): filenames = ["vasprun.xml"] elif os.path.exists("vasprun.xml.gz"): filenames = ["vasprun.xml.gz"] else: logging.error("ERROR: No vasprun.xml found!") sys.exit() elif codes == "questaal": if not filenames: if len(glob("opt.*")) > 0: filenames = glob("opt.*") if len(filenames) == 1: logging.info("Found optics file: " + filenames[0]) else: logging.info("Found optics files: " + ", ".join(filenames)) if isinstance(filenames, str): filenames = [filenames] if isinstance(codes, str): codes = [codes] * len(filenames) elif len(codes) == 1: codes = list(codes) * len(filenames) # ITERATE OVER FILES READING DIELECTRIC DATA dielectrics = [] auto_labels = [] auto_band_gaps = [] for i, (filename, code) in enumerate(zip(filenames, codes)): if code == "vasp": vr = Vasprun(filename) dielectrics.append(vr.dielectric) auto_labels.append( latexify(vr.final_structure.composition.reduced_formula).replace( "$_", r"$_\mathregular" ) ) if isinstance(band_gaps, list) and not band_gaps: # band_gaps = [], auto band gap requested auto_band_gaps.append(vr.get_band_structure().get_band_gap()["energy"]) else: auto_band_gaps.append(None) elif code == "questaal": if not save_files: out_filename = None elif len(filenames) == 1: out_filename = "dielectric.dat" else: out_filename = f"dielectric_{i + 1}.dat" dielectrics.append(questaal.dielectric_from_file(filename, out_filename)) auto_band_gaps.append(None) auto_labels.append(filename.split(".")[-1]) if isinstance(band_gaps, list) and not band_gaps: logging.info( "Bandgap requested but not supported for Questaal" " file {}: skipping...".format(filename) ) else: raise Exception(f'Code selection "{code}" not recognised') if not labels and len(filenames) > 1: labels = auto_labels # PROCESS DIELECTRIC DATA: BROADENING AND DERIVED PROPERTIES if gaussian: dielectrics = [broaden_eps(d, gaussian) for d in dielectrics] # initialize spectrum data ready to append from each dataset abs_data = OrderedDict() for mode in modes: abs_data.update({mode: []}) # for each calculation, get all required properties and append to data for d in dielectrics: for mode, spectrum in calculate_dielectric_properties( d, set(modes), average=average ).items(): abs_data[mode].append(spectrum) if isinstance(band_gaps, list) and not band_gaps: # empty list therefore use bandgaps collected from vasprun files band_gaps = auto_band_gaps elif isinstance(band_gaps, list): # list containing filenames and/or values: mutate the list in-place for i, item in enumerate(band_gaps): if item is None: pass elif _floatable(item): band_gaps[i] = float(item) elif "vasprun" in item: band_gaps[i] = ( Vasprun(item).get_band_structure().get_band_gap()["energy"] ) else: raise ValueError( "Format not recognised for auto bandgap: " "{}.".format(item) ) plotter = SOpticsPlotter(abs_data, band_gap=band_gaps, label=labels) plt = plotter.get_plot( width=width, height=height, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, colours=colours, dpi=dpi, plt=plt, fonts=fonts, style=style, no_base_style=no_base_style, units=units, ) if save_files: basename = "absorption" if prefix: basename = f"{prefix}_{basename}" image_filename = f"{basename}.{image_format}" if directory: image_filename = os.path.join(directory, image_filename) plt.savefig(image_filename, format=image_format, dpi=dpi) for mode, data in abs_data.items(): basename = "absorption" if mode == "abs" else mode write_files(data, basename=basename, prefix=prefix, directory=directory) else: return plt
def optplot(modes=('absorption', ), filenames=None, prefix=None, directory=None, gaussian=None, band_gaps=None, labels=None, average=True, height=6, width=6, xmin=0, xmax=None, ymin=0, ymax=1e5, colours=None, style=None, no_base_style=None, image_format='pdf', dpi=400, plt=None, fonts=None): """A script to plot optical absorption spectra from VASP calculations. Args: modes (:obj:`list` or :obj:`tuple`): Ordered list of :obj:`str` determining properties to plot. Accepted options are 'absorption' (default), 'eps', 'eps-real', 'eps-im', 'n', 'n-real', 'n-im', 'loss' (equivalent to n-im). filenames (:obj:`str` or :obj:`list`, optional): Path to vasprun.xml file (can be gzipped). Alternatively, a list of paths can be provided, in which case the absorption spectra for each will be plotted concurrently. prefix (:obj:`str`, optional): Prefix for file names. directory (:obj:`str`, optional): The directory in which to save files. gaussian (:obj:`float`): Standard deviation for gaussian broadening. band_gaps (:obj:`float` or :obj:`list`, optional): The band gap as a :obj:`float`, plotted as a dashed line. If plotting multiple spectra then a :obj:`list` of band gaps can be provided. labels (:obj:`str` or :obj:`list`): A label to identify the spectra. If plotting multiple spectra then a :obj:`list` of labels can be provided. average (:obj:`bool`, optional): Average the dielectric response across all lattice directions. Defaults to ``True``. height (:obj:`float`, optional): The height of the plot. width (:obj:`float`, optional): The width of the plot. xmin (:obj:`float`, optional): The minimum energy on the x-axis. xmax (:obj:`float`, optional): The maximum energy on the x-axis. ymin (:obj:`float`, optional): The minimum absorption intensity on the y-axis. ymax (:obj:`float`, optional): The maximum absorption intensity on the y-axis. colours (:obj:`list`, optional): A :obj:`list` of colours to use in the plot. The colours can be specified as a hex code, set of rgb values, or any other format supported by matplotlib. 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. 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: A matplotlib pyplot object. """ if not filenames: if os.path.exists('vasprun.xml'): filenames = ['vasprun.xml'] elif os.path.exists('vasprun.xml.gz'): filenames = ['vasprun.xml.gz'] else: logging.error('ERROR: No vasprun.xml found!') sys.exit() elif isinstance(filenames, str): filenames = [filenames] vrs = [Vasprun(f) for f in filenames] dielectrics = [vr.dielectric for vr in vrs] if gaussian: dielectrics = [broaden_eps(d, gaussian) for d in dielectrics] # initialize spectrum data ready to append from each dataset abs_data = OrderedDict() for mode in modes: abs_data.update({mode: []}) # for each calculation, get all required properties and append to data for d in dielectrics: for mode, spectrum in calculate_dielectric_properties( d, set(modes), average=average).items(): abs_data[mode].append(spectrum) if isinstance(band_gaps, list) and not band_gaps: # empty list therefore get bandgap from vasprun files band_gaps = [ vr.get_band_structure().get_band_gap()['energy'] for vr in vrs ] elif isinstance(band_gaps, list) and 'vasprun' in band_gaps[0]: # band_gaps contains list of vasprun files bg_vrs = [Vasprun(f) for f in band_gaps] band_gaps = [ vr.get_band_structure().get_band_gap()['energy'] for vr in bg_vrs ] elif isinstance(band_gaps, list): # band_gaps is non empty list w. no vaspruns; presume floats band_gaps = [float(i) for i in band_gaps] save_files = False if plt else True if len(abs_data) > 1 and not labels: labels = [ latexify(vr.final_structure.composition.reduced_formula).replace( '$_', '$_\mathregular') for vr in vrs ] plotter = SOpticsPlotter(abs_data, band_gap=band_gaps, label=labels) plt = plotter.get_plot(width=width, height=height, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, colours=colours, dpi=dpi, plt=plt, fonts=fonts, style=style, no_base_style=no_base_style) if save_files: basename = 'absorption' if prefix: basename = '{}_{}'.format(prefix, basename) image_filename = '{}.{}'.format(basename, image_format) if directory: image_filename = os.path.join(directory, image_filename) plt.savefig(image_filename, format=image_format, dpi=dpi) for mode, data in abs_data.items(): basename = 'absorption' if mode == 'abs' else mode write_files(data, basename=basename, prefix=prefix, directory=directory) else: return plt
try: from pymatgen.electronic_structure.boltztrap2 import BandstructureLoader, \ VasprunLoader, BztInterpolator, BztTransportProperties, BztPlotter, \ merge_up_down_doses BOLTZTRAP2_PRESENT = True except Exception: BOLTZTRAP2_PRESENT = False BOLTZTRAP2_PRESENT = False test_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", 'test_files/boltztrap2/') vrunfile = os.path.join(test_dir, 'vasprun.xml') vrun = Vasprun(vrunfile, parse_projected_eigen=True) vrunfile_sp = os.path.join(test_dir, 'vasprun_spin.xml') vrun_sp = Vasprun(vrunfile_sp, parse_projected_eigen=True) @unittest.skipIf(not BOLTZTRAP2_PRESENT, "No boltztrap2, skipping tests...") class BandstructureLoaderTest(unittest.TestCase): def setUp(self): bs = loadfn(os.path.join(test_dir, "PbTe_bandstructure.json")) bs_sp = loadfn(os.path.join(test_dir, "N2_bandstructure.json")) self.loader = BandstructureLoader(bs, vrun.structures[-1]) self.assertIsNotNone(self.loader) self.loader_sp_up = BandstructureLoader(bs_sp, vrun_sp.structures[-1],
def process_vasprun(self, dir_name, taskname, filename): """ Adapted from matgendb.creator Process a vasprun.xml file. """ vasprun_file = os.path.join(dir_name, filename) if self.bandstructure_mode: vrun = Vasprun(vasprun_file, parse_eigen=True, parse_projected_eigen=True) else: vrun = Vasprun(vasprun_file) d = vrun.as_dict() for k, v in { "formula_pretty": "pretty_formula", "composition_reduced": "reduced_cell_formula", "composition_unit_cell": "unit_cell_formula" }.items(): d[k] = d.pop(v) for k in ["eigenvalues", "projected_eigenvalues" ]: # large storage space breaks some docs if k in d["output"]: del d["output"][k] comp = Composition(d["composition_unit_cell"]) d["formula_anonymous"] = comp.anonymized_formula d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula d["dir_name"] = os.path.abspath(dir_name) d["completed_at"] = str( datetime.datetime.fromtimestamp(os.path.getmtime(vasprun_file))) d["density"] = vrun.final_structure.density # replace 'crystal' with 'structure' d["input"]["structure"] = d["input"].pop("crystal") d["output"]["structure"] = d["output"].pop("crystal") for k, v in { "energy": "final_energy", "energy_per_atom": "final_energy_per_atom" }.items(): d["output"][k] = d["output"].pop(v) if self.parse_dos and self.parse_dos != 'final': try: d["dos"] = vrun.complete_dos.as_dict() except: raise ValueError( "No valid dos data exist in {}.".format(dir_name)) if self.bandstructure_mode: bs = vrun.get_band_structure( line_mode=(self.bandstructure_mode == "line")) else: bs = vrun.get_band_structure() d["bandstructure"] = bs.as_dict() d["output"]["vbm"] = bs.get_vbm()["energy"] d["output"]["cbm"] = bs.get_cbm()["energy"] bs_gap = bs.get_band_gap() d["output"]["bandgap"] = bs_gap["energy"] d["output"]["is_gap_direct"] = bs_gap["direct"] d["output"]["is_metal"] = bs.is_metal() d["task"] = {"type": taskname, "name": taskname} # phonon-dfpt if hasattr(vrun, "force_constants"): d["output"]["force_constants"] = vrun.force_constants.tolist() d["output"][ "normalmode_eigenvals"] = vrun.normalmode_eigenvals.tolist() d["output"][ "normalmode_eigenvecs"] = vrun.normalmode_eigenvecs.tolist() return d
import os import sys import datetime import time import pandas as pd sys.path.append('/Volumes/kaswat200GB/GitHub/pyVASP/') os.system('clear') print("Current date and time: ", datetime.datetime.now().strftime("%d-%m-%Y %H-%M-%S")) print("") from pymatgen.io.vasp import Vasprun from pymatgen.electronic_structure.plotter import DosPlotter localDir = os.getcwd() temp = os.path.join(localDir, 'vasprun.xml') v = Vasprun(temp) tdos = v.tdos plotter = DosPlotter() plotter.add_dos("Total DOS", tdos) ## plotter.show() plotter.save_plot('TDOS.eps') cdos = v.complete_dos element_dos = cdos.get_element_dos() plotter = DosPlotter() plotter.add_dos_dict(element_dos) ## plotter.show() plotter.save_plot('PDOS.eps')
def read_vasprun( filename ): return Vasprun( filename, parse_potcar_file=False, parse_dos=False, parse_eigen=False )
def test_eigenvalues_from_vasprun(test_data_files): vasprun_file = str(test_data_files / "MnO_uniform_vasprun.xml") vasprun = Vasprun(vasprun_file) assert eigenvalues_from_vasprun(vasprun)[Spin.up][1, 2] == -0.1397
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]))
def setUp(self): struc = PymatgenTest.get_structure("VO2") struc.make_supercell(3) struc = struc self.vac = Vacancy(struc, struc.sites[0], charge=-3) abc = self.vac.bulk_structure.lattice.abc axisdata = [np.arange(0.0, lattval, 0.2) for lattval in abc] bldata = [ np.array([1.0 for u in np.arange(0.0, lattval, 0.2)]) for lattval in abc ] dldata = [ np.array([(-1 - np.cos(2 * np.pi * u / lattval)) for u in np.arange(0.0, lattval, 0.2)]) for lattval in abc ] self.frey_params = { "axis_grid": axisdata, "bulk_planar_averages": bldata, "defect_planar_averages": dldata, "dielectric": 15, "initial_defect_structure": struc.copy(), "defect_frac_sc_coords": struc.sites[0].frac_coords[:], } kumagai_bulk_struc = Poscar.from_file( os.path.join(PymatgenTest.TEST_FILES_DIR, "defect", "CONTCAR_bulk")).structure bulk_out = Outcar( os.path.join(PymatgenTest.TEST_FILES_DIR, "defect", "OUTCAR_bulk.gz")) defect_out = Outcar( os.path.join(PymatgenTest.TEST_FILES_DIR, "defect", "OUTCAR_vac_Ga_-3.gz")) self.kumagai_vac = Vacancy(kumagai_bulk_struc, kumagai_bulk_struc.sites[0], charge=-3) kumagai_defect_structure = self.kumagai_vac.generate_defect_structure() self.kumagai_params = { "bulk_atomic_site_averages": bulk_out.electrostatic_potential, "defect_atomic_site_averages": defect_out.electrostatic_potential, "site_matching_indices": [[ind, ind - 1] for ind in range(len(kumagai_bulk_struc))], "defect_frac_sc_coords": [0.0, 0.0, 0.0], "initial_defect_structure": kumagai_defect_structure, "dielectric": 18.118 * np.identity(3), "gamma": 0.153156, # not necessary to load gamma, but speeds up unit test } v = Vasprun(os.path.join(PymatgenTest.TEST_FILES_DIR, "vasprun.xml")) eigenvalues = v.eigenvalues.copy() kptweights = v.actual_kpoints_weights potalign = -0.1 vbm = v.eigenvalue_band_properties[2] cbm = v.eigenvalue_band_properties[1] defect_incar = v.incar self.bandfill_params = { "eigenvalues": eigenvalues, "kpoint_weights": kptweights, "potalign": potalign, "vbm": vbm, "cbm": cbm, "run_metadata": { "defect_incar": defect_incar }, } self.band_edge_params = { "hybrid_cbm": 1.0, "hybrid_vbm": -1.0, "vbm": -0.5, "cbm": 0.6, "num_hole_vbm": 1.0, "num_elec_cbm": 1.0, }
def from_file(cls, vasprun_file): """Get a vasprun.xml file and return a VasprunLoader""" vrun_obj = Vasprun(vasprun_file, parse_projected_eigen=True) return VasprunLoader(vrun_obj)
def process_vasprun(self, dir_name, taskname, filename): """ Adapted from matgendb.creator Process a vasprun.xml file. """ vasprun_file = os.path.join(dir_name, filename) vrun = Vasprun(vasprun_file) d = vrun.as_dict() # rename formula keys for k, v in {"formula_pretty": "pretty_formula", "composition_reduced": "reduced_cell_formula", "composition_unit_cell": "unit_cell_formula"}.items(): d[k] = d.pop(v) for k in ["eigenvalues", "projected_eigenvalues"]: # large storage space breaks some docs if k in d["output"]: del d["output"][k] comp = Composition(d["composition_unit_cell"]) d["formula_anonymous"] = comp.anonymized_formula d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula d["dir_name"] = os.path.abspath(dir_name) d["completed_at"] = str(datetime.datetime.fromtimestamp(os.path.getmtime(vasprun_file))) d["density"] = vrun.final_structure.density # replace 'crystal' with 'structure' d["input"]["structure"] = d["input"].pop("crystal") d["output"]["structure"] = d["output"].pop("crystal") for k, v in {"energy": "final_energy", "energy_per_atom": "final_energy_per_atom"}.items(): d["output"][k] = d["output"].pop(v) # Process bandstructure and DOS if self.bandstructure_mode != False: bs = self.process_bandstructure(vrun) if bs: d["bandstructure"] = bs if self.parse_dos != False: dos = self.process_dos(vrun) if dos: d["dos"] = dos # Parse electronic information if possible. # For certain optimizers this is broken and we don't get an efermi resulting in the bandstructure try: bs = vrun.get_band_structure() bs_gap = bs.get_band_gap() d["output"]["vbm"] = bs.get_vbm()["energy"] d["output"]["cbm"] = bs.get_cbm()["energy"] d["output"]["bandgap"] = bs_gap["energy"] d["output"]["is_gap_direct"] = bs_gap["direct"] d["output"]["is_metal"] = bs.is_metal() if not bs_gap["direct"]: d["output"]["direct_gap"] = bs.get_direct_band_gap() if isinstance(bs, BandStructureSymmLine): d["output"]["transition"] = bs_gap["transition"] except Exception: logger.warning("Error in parsing bandstructure") if vrun.incar["IBRION"] == 1: logger.warning("Vasp doesn't properly output efermi for IBRION == 1") if self.bandstructure_mode is True: logger.error(traceback.format_exc()) logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc()) raise # store run name and location ,e.g. relax1, relax2, etc. d["task"] = {"type": taskname, "name": taskname} # include output file names d["output_file_paths"] = self.process_raw_data(dir_name, taskname=taskname) # parse axially averaged locpot if "locpot" in d["output_file_paths"] and self.parse_locpot: locpot = Locpot.from_file(os.path.join(dir_name, d["output_file_paths"]["locpot"])) d["output"]["locpot"] = {i: locpot.get_average_along_axis(i) for i in range(3)} if self.parse_chgcar != False: # parse CHGCAR file only for static calculations # TODO require static run later # if self.parse_chgcar == True and vrun.incar.get("NSW", 0) < 1: try: chgcar = self.process_chgcar(os.path.join(dir_name, d["output_file_paths"]["chgcar"])) except: raise ValueError("No valid charge data exist") d["chgcar"] = chgcar if self.parse_aeccar != False: try: chgcar = self.process_chgcar(os.path.join(dir_name, d["output_file_paths"]["aeccar0"])) except: raise ValueError("No valid charge data exist") d["aeccar0"] = chgcar try: chgcar = self.process_chgcar(os.path.join(dir_name, d["output_file_paths"]["aeccar2"])) except: raise ValueError("No valid charge data exist") d["aeccar2"] = chgcar # parse force constants if hasattr(vrun, "force_constants"): d["output"]["force_constants"] = vrun.force_constants.tolist() d["output"]["normalmode_eigenvals"] = vrun.normalmode_eigenvals.tolist() d["output"]["normalmode_eigenvecs"] = vrun.normalmode_eigenvecs.tolist() # Try and perform bader if self.parse_bader: try: bader = bader_analysis_from_path(dir_name, suffix=".{}".format(taskname)) except Exception as e: bader = "Bader analysis failed: {}".format(e) d["bader"] = bader return d
def actual_diele_func_data(test_data_files): v = Vasprun(test_data_files / "MgSe_absorption_vasprun.xml") o = Outcar(test_data_files / "MgSe_absorption_OUTCAR") return make_diele_func(v, o)
def test_get_energies_symprec(self): # vr = Vasprun(os.path.join(tin_dioxide_files, 'vasprun.xml.gz'), # parse_projected_eigen=True) vr = Vasprun( os.path.join(pbs_files, "vasprun.xml.gz"), parse_projected_eigen=True ) bs = vr.get_band_structure() num_electrons = vr.parameters["NELECT"] interpolater = Interpolator( bs, num_electrons, interpolate_projections=True, interpolation_factor=1 ) ir_kpoints, weights, kpoints, ir_kpoints_idx, ir_to_full_idx = get_kpoints( [13, 15, 29], vr.final_structure, boltztrap_ordering=True, return_full_kpoints=True, ) initialize_amset_logger() ( energies, velocities, curvature, projections, sym_info, ) = interpolater.get_energies( kpoints, None, return_velocity=True, atomic_units=True, return_curvature=True, return_projections=True, symprec=0.1, return_vel_outer_prod=True, return_kpoint_mapping=True, ) ( energies_no_sym, velocities_no_sym, curvature_no_sym, projections_no_sym, ) = interpolater.get_energies( kpoints, None, return_velocity=True, atomic_units=True, return_curvature=True, return_projections=True, return_vel_outer_prod=True, symprec=None, ) np.testing.assert_array_equal(ir_to_full_idx, sym_info["ir_to_full_idx"]) np.testing.assert_array_equal(ir_kpoints_idx, sym_info["ir_kpoints_idx"]) # print(velocities[Spin.up][5, :, :, -3:]) # print(velocities_no_sym[Spin.up][5, :, :, -3:]) # print(sym_info["ir_to_full_idx"][-10:]) np.testing.assert_array_almost_equal( energies[Spin.up], energies_no_sym[Spin.up], decimal=12 ) np.testing.assert_array_almost_equal( velocities[Spin.up], velocities_no_sym[Spin.up], decimal=12 ) np.testing.assert_array_almost_equal( curvature[Spin.up], curvature_no_sym[Spin.up], decimal=12 ) for l in projections[Spin.up]: np.testing.assert_array_almost_equal( projections[Spin.up][l], projections_no_sym[Spin.up][l] )
def test_bandfilling(self): v = Vasprun(os.path.join(test_dir, 'vasprun.xml')) eigenvalues = v.eigenvalues.copy() kptweights = v.actual_kpoints_weights potalign = 0. vbm = v.eigenvalue_band_properties[2] cbm = v.eigenvalue_band_properties[1] params = { 'eigenvalues': eigenvalues, 'kpoint_weights': kptweights, 'potalign': potalign, 'vbm': vbm, 'cbm': cbm } bfc = BandFillingCorrection() struc = PymatgenTest.get_structure("VO2") struc.make_supercell(3) vac = Vacancy(struc, struc.sites[0], charge=-3) #test trivial performing bandfilling correction bf_corr = bfc.perform_bandfill_corr(eigenvalues, kptweights, potalign, vbm, cbm) self.assertAlmostEqual(bf_corr, 0.) self.assertFalse(bfc.metadata['occupied_def_levels']) self.assertFalse(bfc.metadata['unoccupied_def_levels']) self.assertFalse(bfc.metadata['total_occupation_defect_levels']) self.assertFalse(bfc.metadata['num_elec_cbm']) self.assertFalse(bfc.metadata['num_hole_vbm']) self.assertFalse(bfc.metadata['potalign']) #test trivial full entry bandfill evaluation de = DefectEntry(vac, 0., corrections={}, parameters=params, entry_id=None) corr = bfc.get_correction(de) self.assertAlmostEqual(corr['bandfilling'], 0.) #modify the eigenvalue list to have free holes hole_eigenvalues = {} for spinkey, spinset in eigenvalues.items(): hole_eigenvalues[spinkey] = [] for kptset in spinset: hole_eigenvalues[spinkey].append([]) for eig in kptset: if (eig[0] < vbm) and (eig[0] > vbm - .8): hole_eigenvalues[spinkey][-1].append([eig[0], 0.5]) else: hole_eigenvalues[spinkey][-1].append(eig) hole_bf_corr = bfc.perform_bandfill_corr(hole_eigenvalues, kptweights, potalign, vbm, cbm) self.assertAlmostEqual(hole_bf_corr, -0.41138336) self.assertAlmostEqual(bfc.metadata['num_hole_vbm'], 0.8125000649) self.assertFalse(bfc.metadata['num_elec_cbm']) #modify the eigenvalue list to have free electrons elec_eigenvalues = {} for spinkey, spinset in eigenvalues.items(): elec_eigenvalues[spinkey] = [] for kptset in spinset: elec_eigenvalues[spinkey].append([]) for eig in kptset: if (eig[0] > cbm) and (eig[0] < cbm + .2): elec_eigenvalues[spinkey][-1].append([eig[0], 0.5]) else: elec_eigenvalues[spinkey][-1].append(eig) elec_bf_corr = bfc.perform_bandfill_corr(elec_eigenvalues, kptweights, potalign, vbm, cbm) self.assertAlmostEqual(elec_bf_corr, -0.0903187572254) self.assertAlmostEqual(bfc.metadata['num_elec_cbm'], 0.8541667349) self.assertFalse(bfc.metadata['num_hole_vbm']) #modify the potalignment and introduce new occupied defect levels from vbm states potalign = -0.1 bf_corr = bfc.perform_bandfill_corr(eigenvalues, kptweights, potalign, vbm, cbm) self.assertAlmostEqual(bfc.metadata['num_hole_vbm'], 0.) self.assertAlmostEqual(bf_corr, 0.) occu = [[1.457, 0.0833333], [1.5204, 0.0833333], [1.53465, 0.0833333], [1.5498, 0.0416667]] self.assertArrayAlmostEqual( list( sorted(bfc.metadata['occupied_def_levels'], key=lambda x: x[0])), list(sorted(occu, key=lambda x: x[0]))) self.assertAlmostEqual(bfc.metadata['total_occupation_defect_levels'], 0.29166669) self.assertFalse(bfc.metadata['unoccupied_def_levels'])
import numpy as np from pymatgen.io.vasp import Vasprun from pymatgen.io.vasp.outputs import CompleteDos, Dos from pymatgen.io.vasp.outputs import Spin, Structure import os v = Vasprun('/home/jinho/PycharmProjects/vasp/input/' + 'vasprun.xml') c = CompleteDos(v.structures, v.tdos, v.pdos) if __name__ == '__main__': s: Structure = c.structure[0] arr = [ 0, 0.05, .1, .15, .2, .25, .31, .37, .46, .52, .57, .63, .68, .74, .78, .84, .9, .95 ] same = [[] for _ in range(len(arr) - 1)] for i, k in enumerate(s.frac_coords): for j in range(len(arr) - 1): if arr[j] <= k[2] < arr[j + 1]: same[j].append(i) dos = [None for _ in range(len(arr))] dos[0] = c.energies - c.efermi sites = s.sites for ind, i in enumerate(same): for j in i: if dos[ind + 1] is None: dos[ind + 1] = c.get_site_dos(j).get_smeared_densities( sigma=0.05)[Spin.up] else:
def process_vasprun(self, dir_name, taskname, filename): """ Adapted from matgendb.creator Process a vasprun.xml file. """ vasprun_file = os.path.join(dir_name, filename) vrun = Vasprun(vasprun_file) d = vrun.as_dict() # rename formula keys for k, v in {"formula_pretty": "pretty_formula", "composition_reduced": "reduced_cell_formula", "composition_unit_cell": "unit_cell_formula"}.items(): d[k] = d.pop(v) for k in ["eigenvalues", "projected_eigenvalues"]: # large storage space breaks some docs if k in d["output"]: del d["output"][k] comp = Composition(d["composition_unit_cell"]) d["formula_anonymous"] = comp.anonymized_formula d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula d["dir_name"] = os.path.abspath(dir_name) d["completed_at"] = str(datetime.datetime.fromtimestamp(os.path.getmtime(vasprun_file))) d["density"] = vrun.final_structure.density # replace 'crystal' with 'structure' d["input"]["structure"] = d["input"].pop("crystal") d["output"]["structure"] = d["output"].pop("crystal") for k, v in {"energy": "final_energy", "energy_per_atom": "final_energy_per_atom"}.items(): d["output"][k] = d["output"].pop(v) if self.parse_dos == True or (str(self.parse_dos).lower() == "auto" and vrun.incar.get("NSW", 1) == 0): try: d["dos"] = vrun.complete_dos.as_dict() except: raise ValueError("No valid dos data exist in {}.".format(dir_name)) # Band structure parsing logic if str(self.bandstructure_mode).lower() == "auto": # if line mode nscf if vrun.incar.get("ICHARG", 0) > 10 and vrun.kpoints.num_kpts > 0: bs_vrun = BSVasprun(vasprun_file, parse_projected_eigen=True) bs = bs_vrun.get_band_structure(line_mode=True) # else if nscf elif vrun.incar.get("ICHARG", 0) > 10: bs_vrun = BSVasprun(vasprun_file, parse_projected_eigen=True) bs = bs_vrun.get_band_structure() # else just regular calculation else: bs = vrun.get_band_structure() # only save the bandstructure if not moving ions if vrun.incar["NSW"] == 0: d["bandstructure"] = bs.as_dict() # legacy line/True behavior for bandstructure_mode elif self.bandstructure_mode: bs_vrun = BSVasprun(vasprun_file, parse_projected_eigen=True) bs = bs_vrun.get_band_structure(line_mode=(str(self.bandstructure_mode).lower() == "line")) d["bandstructure"] = bs.as_dict() # parse bandstructure for vbm/cbm/bandgap but don't save else: bs = vrun.get_band_structure() # Parse electronic information if possible. # For certain optimizers this is broken and we don't get an efermi resulting in the bandstructure try: bs_gap = bs.get_band_gap() d["output"]["vbm"] = bs.get_vbm()["energy"] d["output"]["cbm"] = bs.get_cbm()["energy"] d["output"]["bandgap"] = bs_gap["energy"] d["output"]["is_gap_direct"] = bs_gap["direct"] d["output"]["is_metal"] = bs.is_metal() except Exception: if self.bandstructure_mode is True: import traceback logger.error(traceback.format_exc()) logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc()) raise logger.warning("Error in parsing bandstructure") if vrun.incar["IBRION"] == 1: logger.warning("Vasp doesn't properly output efermi for IBRION == 1") d["task"] = {"type": taskname, "name": taskname} d["output_file_paths"] = self.process_raw_data(dir_name, taskname=taskname) if "locpot" in d["output_file_paths"] and self.parse_locpot: locpot = Locpot.from_file(os.path.join(dir_name,d["output_file_paths"]["locpot"])) d["output"]["locpot"] = {i:locpot.get_average_along_axis(i) for i in range(3)} if hasattr(vrun, "force_constants"): # phonon-dfpt d["output"]["force_constants"] = vrun.force_constants.tolist() d["output"]["normalmode_eigenvals"] = vrun.normalmode_eigenvals.tolist() d["output"]["normalmode_eigenvecs"] = vrun.normalmode_eigenvecs.tolist() return d
newList = [] keys = list(lists.keys()) keys.sort(key=get_value) for i in range(9): for j in keys: newList.append(lists[j][i]) self.comps = newList ###################################### ###################################### ###################################### path = "Tuttle/VaspRuns/ABC4/" xml = "vasprun.xml" comp = [] for x, q, u in os.walk(path): if x.find("runnable") > 0: c = Vasprun(x + '/' + xml) comp.append(Compound(c)) mplot = MultiPlot(comp) mplot.sort() mplot.plot(color='r') mplot.change_limits(xlim=(-15, 10), ylim=(0, 20)) mplot.fig.savefig("a3bc6.png")
def parse_command_line_arguments(): # command line arguments parser = argparse.ArgumentParser() parser.add_argument('-f', '--file', default='vasprun.xml', type=str, help='path to input file') parser.add_argument('-o', '--output', default='totdos.dat', help='output file format') parser.add_argument('-s', '--spin', help='yes, if spin polarised, otherwise leave blank') args = parser.parse_args() return args if __name__ == "__main__": args = parse_command_line_arguments() dosrun = Vasprun(args.file) totdens = dosrun.tdos.densities[Spin.up] + dosrun.tdos.densities[Spin.down] totdos = dosrun.tdos.energies - dosrun.eigenvalue_band_properties[2] #Set VBM to 0 eV if args.spin is not None: # Use this if dos is spin polarised sc_input = np.column_stack((totdos, dosrun.tdos.densities[Spin.up], dosrun.tdos.densities[Spin.down])) # Create array of energy against spin polarised density np.savetxt("totdos.dat", sc_input) # Save as totdos.dat else: sc_input = np.column_stack((totdos, totdens)) #Create Array of Energy against density np.savetxt("totdos.dat", sc_input) #Save as totdos.dat file
def test_bandfilling(self): v = Vasprun(os.path.join(PymatgenTest.TEST_FILES_DIR, "vasprun.xml")) eigenvalues = v.eigenvalues.copy() kptweights = v.actual_kpoints_weights potalign = 0.0 vbm = v.eigenvalue_band_properties[2] cbm = v.eigenvalue_band_properties[1] defect_incar = v.incar params = { "eigenvalues": eigenvalues, "kpoint_weights": kptweights, "potalign": potalign, "vbm": vbm, "cbm": cbm, "run_metadata": { "defect_incar": defect_incar }, } bfc = BandFillingCorrection() struc = PymatgenTest.get_structure("VO2") struc.make_supercell(3) vac = Vacancy(struc, struc.sites[0], charge=-3) # test trivial performing bandfilling correction bf_corr = bfc.perform_bandfill_corr(eigenvalues, kptweights, potalign, vbm, cbm) self.assertAlmostEqual(bf_corr, 0.0) self.assertFalse(bfc.metadata["num_elec_cbm"]) self.assertFalse(bfc.metadata["num_hole_vbm"]) self.assertFalse(bfc.metadata["potalign"]) # test trivial full entry bandfill evaluation de = DefectEntry(vac, 0.0, corrections={}, parameters=params, entry_id=None) corr = bfc.get_correction(de) self.assertAlmostEqual(corr["bandfilling_correction"], 0.0) # modify the eigenvalue list to have free holes hole_eigenvalues = {} for spinkey, spinset in eigenvalues.items(): hole_eigenvalues[spinkey] = [] for kptset in spinset: hole_eigenvalues[spinkey].append([]) for eig in kptset: if (eig[0] < vbm) and (eig[0] > vbm - 0.8): hole_eigenvalues[spinkey][-1].append([eig[0], 0.5]) else: hole_eigenvalues[spinkey][-1].append(eig) hole_bf_corr = bfc.perform_bandfill_corr(hole_eigenvalues, kptweights, potalign, vbm, cbm) self.assertAlmostEqual(hole_bf_corr, -0.41138336) self.assertAlmostEqual(bfc.metadata["num_hole_vbm"], 0.8125000649) self.assertFalse(bfc.metadata["num_elec_cbm"]) # test case with only one spin and eigen-occupations are 1. one_spin_eigen = hole_eigenvalues.copy() del one_spin_eigen[list(eigenvalues.keys())[0]] bf_corr = bfc.perform_bandfill_corr(one_spin_eigen, kptweights, potalign, vbm, cbm) self.assertAlmostEqual(bf_corr, -0.14487501159000005) # test case with only one spin and eigen-occupations are 2. one_spin_eigen_twooccu = one_spin_eigen.copy() for kptset in one_spin_eigen_twooccu.values(): for bandset in kptset: for occuset in bandset: if occuset[1] == 1.0: occuset[1] = 2.0 elif occuset[1] == 0.5: occuset[1] = 1.0 bf_corr = bfc.perform_bandfill_corr(one_spin_eigen_twooccu, kptweights, potalign, vbm, cbm) self.assertAlmostEqual(bf_corr, -0.14487501159000005)
def test_parse_defect_calculations_AND_compile_all(self): #testing both parse defect_calculatiosn And the compile all methods because they both require a file structure... with ScratchDir("."): #make a fake file structure to parse vaspruns and locpot paths os.mkdir("bulk") copyfile(os.path.join(pmgtestfiles_loc, "vasprun.xml"), "bulk/vasprun.xml") os.mkdir( "bulk/LOCPOT" ) #locpot path just needs to exist..doesnt need to be real locpot file... bulktrans = {"supercell": [3, 3, 3], "defect_type": "bulk"} dumpfn(bulktrans, "bulk/transformation.json", cls=MontyEncoder) os.mkdir("dielectric") copyfile(os.path.join(pmgtestfiles_loc, "vasprun.xml.dfpt.ionic"), "dielectric/vasprun.xml") vrobj = Vasprun(os.path.join(pmgtestfiles_loc, "vasprun.xml")) os.mkdir("vac_1_As") os.mkdir("vac_1_As/charge_0") copyfile(os.path.join(pmgtestfiles_loc, "vasprun.xml"), "vac_1_As/charge_0/vasprun.xml") os.mkdir( "vac_1_As/charge_0/LOCPOT") #locpot path just needs to exist transchg0 = { "charge": 0, "supercell": [3, 3, 3], "defect_type": "vac_1_As", "defect_supercell_site": vrobj.final_structure.sites[0] } dumpfn(transchg0, "vac_1_As/charge_0/transformation.json", cls=MontyEncoder) os.mkdir("vac_1_As/charge_-1") copyfile( os.path.join(pmgtestfiles_loc, "vasprun.xml.dfpt.unconverged" ), #make this one unconverged... "vac_1_As/charge_-1/vasprun.xml") os.mkdir( "vac_1_As/charge_-1/LOCPOT") #locpot path just needs to exist transchgm1 = { "charge": -1, "supercell": [3, 3, 3], "defect_type": "vac_1_As", "defect_supercell_site": vrobj.final_structure.sites[0] } dumpfn(transchgm1, "vac_1_As/charge_-1/transformation.json", cls=MontyEncoder) os.mkdir("sub_1_Cs_on_As") os.mkdir("sub_1_Cs_on_As/charge_2") copyfile(os.path.join(pmgtestfiles_loc, "vasprun.xml"), "sub_1_Cs_on_As/charge_2/vasprun.xml") os.mkdir("sub_1_Cs_on_As/charge_2/LOCPOT" ) #locpot path just needs to exist transchg2 = { "charge": 0, "supercell": [3, 3, 3], "defect_type": "sub_1_Cs_on_As", "defect_supercell_site": vrobj.final_structure.sites[1], "substitution_specie": "Cs" } dumpfn(transchg2, "sub_1_Cs_on_As/charge_2/transformation.json", cls=MontyEncoder) #now test parse_defect_calculations pp = PostProcess(".") pdd = pp.parse_defect_calculations() self.assertEqual(pdd["bulk_entry"].energy, vrobj.final_energy) self.assertEqual(len(pdd["bulk_entry"].structure), 25) self.assertEqual(pdd["bulk_entry"].data["bulk_path"], "./bulk") self.assertEqual(pdd["bulk_entry"].data["supercell_size"], [3, 3, 3]) self.assertEqual(len(pdd["defects"]), 2) self.assertEqual(pdd["defects"][0].energy, 0.) self.assertEqual(len(pdd["defects"][0].bulk_structure), 25) self.assertEqual(pdd["defects"][0].parameters["defect_path"], "./vac_1_As/charge_0") self.assertEqual( pdd["defects"][0].parameters["fldr_name"] + "_" + str(pdd["defects"][0].charge), "vac_1_As_0") self.assertEqual(pdd["defects"][0].multiplicity, 1) self.assertEqual(list(pdd["defects"][0].defect.site.coords), list(vrobj.final_structure.sites[0].coords)) self.assertEqual(pdd["defects"][0].parameters["supercell_size"], [3, 3, 3]) self.assertEqual(list(pdd["defects"][1].defect.site.coords), list(vrobj.final_structure.sites[1].coords)) self.assertEqual(pdd["defects"][1].defect.site.specie.symbol, "Cs") #now test compile_all quickly... ca = pp.compile_all() lk = sorted(list(ca.keys())) self.assertEqual(len(lk), 6) self.assertEqual( lk, sorted([ "epsilon", "vbm", "gap", "defects", "bulk_entry", "mu_range" ])) answer = [[521.83587174, -0.00263523, 0.0026437], [-0.00263523, 24.46276268, 5.381848290000001], [0.0026437, 5.381848290000001, 24.42964103]] self.assertEqual(ca["epsilon"], answer) self.assertEqual(ca["vbm"], 1.5516000000000001) self.assertEqual(ca["gap"], 2.5390000000000001) self.assertEqual(len(ca["defects"]), 2) self.assertEqual(ca["bulk_entry"].energy, vrobj.final_energy)
def setUp(self): struc = PymatgenTest.get_structure("VO2") struc.make_supercell(3) struc = struc self.vac = Vacancy(struc, struc.sites[0], charge=-3) abc = self.vac.bulk_structure.lattice.abc axisdata = [np.arange(0., lattval, 0.2) for lattval in abc] bldata = [ np.array([1. for u in np.arange(0., lattval, 0.2)]) for lattval in abc ] dldata = [ np.array([(-1 - np.cos(2 * np.pi * u / lattval)) for u in np.arange(0., lattval, 0.2)]) for lattval in abc ] self.frey_params = { 'axis_grid': axisdata, 'bulk_planar_averages': bldata, 'defect_planar_averages': dldata, 'dielectric': 15, 'initial_defect_structure': struc.copy(), 'defect_frac_sc_coords': struc.sites[0].frac_coords[:] } kumagai_bulk_struc = Poscar.from_file( os.path.join(test_dir, 'defect', 'CONTCAR_bulk')).structure bulk_out = Outcar(os.path.join(test_dir, 'defect', 'OUTCAR_bulk.gz')) defect_out = Outcar( os.path.join(test_dir, 'defect', 'OUTCAR_vac_Ga_-3.gz')) self.kumagai_vac = Vacancy(kumagai_bulk_struc, kumagai_bulk_struc.sites[0], charge=-3) kumagai_defect_structure = self.kumagai_vac.generate_defect_structure() self.kumagai_params = { 'bulk_atomic_site_averages': bulk_out.electrostatic_potential, 'defect_atomic_site_averages': defect_out.electrostatic_potential, 'site_matching_indices': [[ind, ind - 1] for ind in range(len(kumagai_bulk_struc))], 'defect_frac_sc_coords': [0., 0., 0.], 'initial_defect_structure': kumagai_defect_structure, 'dielectric': 18.118 * np.identity(3), 'gamma': 0.153156 # not neccessary to load gamma, but speeds up unit test } v = Vasprun(os.path.join(test_dir, 'vasprun.xml')) eigenvalues = v.eigenvalues.copy() kptweights = v.actual_kpoints_weights potalign = -0.1 vbm = v.eigenvalue_band_properties[2] cbm = v.eigenvalue_band_properties[1] self.bandfill_params = { 'eigenvalues': eigenvalues, 'kpoint_weights': kptweights, 'potalign': potalign, 'vbm': vbm, 'cbm': cbm } self.band_edge_params = { 'hybrid_cbm': 1., 'hybrid_vbm': -1., 'vbm': -0.5, 'cbm': 0.6, 'num_hole_vbm': 1., 'num_elec_cbm': 1. }