def find_dirac_nodes(): """ Look for band crossings near (within `tol` eV) the Fermi level. Returns: boolean. Whether or not a band crossing occurs at or near the fermi level. """ vasprun = Vasprun('vasprun.xml') dirac = False if vasprun.get_band_structure().get_band_gap()['energy'] < 0.1: efermi = vasprun.efermi bsp = BSPlotter(vasprun.get_band_structure('KPOINTS', line_mode=True, efermi=efermi)) bands = [] data = bsp.bs_plot_data(zero_to_efermi=True) for d in range(len(data['distances'])): for i in range(bsp._nb_bands): x = data['distances'][d], y = [data['energy'][d][str(Spin.up)][i][j] for j in range(len(data['distances'][d]))] band = [x, y] bands.append(band) considered = [] for i in range(len(bands)): for j in range(len(bands)): if i != j and (j, i) not in considered: considered.append((j, i)) for k in range(len(bands[i][0])): if ((-0.1 < bands[i][1][k] < 0.1) and (-0.1 < bands[i][1][k] - bands[j][1][k] < 0.1)): dirac = True return dirac
def get_band_edges(): """ Calculate the band edge locations relative to the vacuum level for a semiconductor. If spin-polarized, returns all 4 band edges. """ # Vacuum level energy from LOCPOT. locpot = Locpot.from_file("LOCPOT") evac = max(locpot.get_average_along_axis(2)) vasprun = Vasprun("vasprun.xml") efermi = vasprun.efermi - evac if vasprun.get_band_structure().is_spin_polarized: eigenvals = {Spin.up: [], Spin.down: []} for band in vasprun.eigenvalues: for eigenvalue in vasprun.eigenvalues[band]: eigenvals[band[0]].append(eigenvalue) up_cbm = min([e[0] for e in eigenvals[Spin.up] if not e[1]]) - evac up_vbm = max([e[0] for e in eigenvals[Spin.up] if e[1]]) - evac dn_cbm = min([e[0] for e in eigenvals[Spin.down] if not e[1]]) - evac dn_vbm = max([e[0] for e in eigenvals[Spin.down] if e[1]]) - evac edges = {"up_cbm": up_cbm, "up_vbm": up_vbm, "dn_cbm": dn_cbm, "dn_vbm": dn_vbm, "efermi": efermi} else: bs = vasprun.get_band_structure() cbm = bs.get_cbm()["energy"] - evac vbm = bs.get_vbm()["energy"] - evac edges = {"cbm": cbm, "vbm": vbm, "efermi": efermi} return edges
def find_dirac_nodes(): """ Look for band crossings near (within `tol` eV) the Fermi level. Returns: boolean. Whether or not a band crossing occurs at or near the fermi level. """ vasprun = Vasprun('vasprun.xml') dirac = False if vasprun.get_band_structure().get_band_gap()['energy'] < 0.1: efermi = vasprun.efermi bsp = BSPlotter(vasprun.get_band_structure('KPOINTS', line_mode=True, efermi=efermi)) bands = [] data = bsp.bs_plot_data(zero_to_efermi=True) for d in range(len(data['distances'])): for i in range(bsp._nb_bands): x = data['distances'][d], y = [data['energy'][d][str(Spin.up)][i][j] for j in range(len(data['distances'][d]))] band = [x, y] bands.append(band) considered = [] for i in range(len(bands)): for j in range(len(bands)): if i != j and (j, i) not in considered: considered.append((j, i)) for k in range(len(bands[i][0])): if ((-0.1 < bands[i][1][k] < 0.1) and (-0.1 < bands[i][1][k] - bands[j][1][k] < 0.1)): dirac = True return dirac
def get_bs(dos, vasprun_bands, kpts_bands): ## get BandStructureSymmLine object and "save" in hidden div in json format bands = Vasprun(vasprun_bands, parse_projected_eigen = True) if dos: dos = CompleteDos.from_dict(json.loads(dos)) bs = bands.get_band_structure(kpts_bands, line_mode=True, efermi=dos.efermi) else: bs = bands.get_band_structure(kpts_bands, line_mode=True) return json.dumps(bs.as_dict(), cls=MyEncoder)
def get_bandgap_from_aexx(self, structure, aexx, outdir=None): vasprun_location = os.path.join(outdir, str(aexx).zfill(2), self.names[-1], 'vasprun.xml') try: vasprun = Vasprun(vasprun_location, parse_projected_eigen=False) band_gap = vasprun.get_band_structure().get_band_gap()['energy'] except: def set_aexx(vasp: Vasp, structure=None): vasp.add_keyword('AEXX', aexx/100) return vasp for x in self.functionals: # Set nupdown x.modifications.append(set_aexx) super().__call__(structure, outdir=os.path.join(outdir, str(aexx).zfill(2))) vasprun = Vasprun(vasprun_location, parse_projected_eigen=False) band_gap = vasprun.get_band_structure().get_band_gap()['energy'] return band_gap
def boltz_run(vrun=""): """ Helper function to run and store Bolztrap Please note high denske k-point mesh is needed The automatic k-point convergene in JARVIS-DFT is generally good enough Args: vrun: path to vasprun.xml Returns: BoltztrapAnalyzer object """ if which("x_trans") is None or which("BoltzTraP") is None: print("Please install BoltzTrap") v = Vasprun(vrun) kp = vrun.replace("vasprun.xml", "KPOINTS") out = vrun.replace("vasprun.xml", "OUTCAR") for line in open(out, "r"): if "NELECT" in line: nelect = float(line.split()[2]) bs = v.get_band_structure(kp, line_mode=False) brun = BoltztrapRunner(bs, nelect) path = vrun.split("vasprun.xml")[0] folder = str(path) + str("/boltztrap") out_trans = str(folder) + str("/boltztrap.outputtrans") if not os.path.exists(out_trans): brun.run(path_dir=path) print("doesnt exist", out_trans) bana = BoltztrapAnalyzer.from_files(folder) return bana
def run_task(self, fw_spec): potcar_spec = self.get("potcar_spec", False) vasp_input_set_params = self.get("vasp_input_set_params") or {} # update the bandgap based on output from the previous calculation, # unless the user specified a bandgap via vasp_input_set_params if vasp_input_set_params.get("bandgap") is None: # First look for the gga_bandgap key in the FW spec, to save parsing time if fw_spec.get("gga_bandgap") is not None: vasp_input_set_params["bandgap"] = fw_spec.get("gga_bandgap") # If not found, parse the files from the previous calc to find the bandgap else: parse_potcar_file = not potcar_spec vasprun = Vasprun("vasprun.xml", parse_potcar_file=parse_potcar_file) bandgap = vasprun.get_band_structure( efermi="smart").get_band_gap()["energy"] vasp_input_set_params["bandgap"] = bandgap # read the structure from the output of the previous calculation structure = Structure.from_file("POSCAR") vis = MPScanRelaxSet(structure, **vasp_input_set_params) vis.write_input(".", potcar_spec=potcar_spec)
def read_vasprun(filename='vasprun.xml'): """Read a VASP vasprun.xml file to obtain the density of states Pymatgen must be present on the system to use this method Args: filename (str): Path to vasprun.xml file Returns: data (pymatgen.electronic_structure.dos.Dos): A pymatgen Dos object """ try: from pymatgen.io.vasp.outputs import Vasprun from pymatgen.electronic_structure.core import Spin except ImportError as e: e.msg = "pymatgen package neccessary to load vasprun files" raise vr = Vasprun(filename) band = vr.get_band_structure() dos = vr.complete_dos if band.is_metal(): zero_point = vr.efermi else: zero_point = band.get_vbm()['energy'] # Shift the energies so that the vbm is at 0 eV, also taking into account # any gaussian broadening dos.energies -= zero_point if vr.parameters['ISMEAR'] == 0 or vr.parameters['ISMEAR'] == -1: dos.energies -= vr.parameters['SIGMA'] return dos
def from_file(cls, filename): """ Loads a SolarCell instance from a vasprun.xml. # TODO extend Args: filename (str): vasprum.xml file from which to load the SolarCell object. Returns: SolarCell """ try: vasprun = Vasprun(filename, parse_potcar_file=False) diel_tensor = DielTensor.from_file(filename) except ParseError: raise IOError("Error while parsing the input file. Currently the " "SolarCell class can only be constructed from " "the vasprun.xml file. If you have provided this " "file, check if the run has completed.") # Extract the information on the direct and indirect band gap bandstructure = vasprun.get_band_structure() bandgaps = (bandstructure.get_band_gap()["energy"], bandstructure.get_direct_band_gap()) return cls(diel_tensor, bandgaps)
def plot_band_structure(ylim=(-5, 5), draw_fermi=False, fmt='pdf'): """ Plot a standard band structure with no projections. Args: ylim (tuple): minimum and maximum potentials for the plot's y-axis. draw_fermi (bool): whether or not to draw a dashed line at E_F. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ vasprun = Vasprun('vasprun.xml') efermi = vasprun.efermi bsp = BSPlotter( vasprun.get_band_structure('KPOINTS', line_mode=True, efermi=efermi)) if fmt == "None": return bsp.bs_plot_data() else: plot = bsp.get_plot(ylim=ylim) fig = plot.gcf() ax = fig.gca() ax.set_xticklabels( [r'$\mathrm{%s}$' % t for t in ax.get_xticklabels()]) ax.set_yticklabels( [r'$\mathrm{%s}$' % t for t in ax.get_yticklabels()]) if draw_fermi: ax.plot([ax.get_xlim()[0], ax.get_xlim()[1]], [0, 0], 'k--') plt.savefig('band_structure.{}'.format(fmt), transparent=True) plt.close()
def plot_orb_projected_bands(orbitals, fmt='pdf', ylim=(-5, 5)): """ Plot a separate band structure for each orbital of each element in orbitals. Args: orbitals (dict): dictionary of the form {element: [orbitals]}, e.g. {'Mo': ['s', 'p', 'd'], 'S': ['p']} ylim (tuple): minimum and maximum energies for the plot's y-axis. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ vasprun = Vasprun('vasprun.xml', parse_projected_eigen=True) bs = vasprun.get_band_structure('KPOINTS', line_mode=True) bspp = BSPlotterProjected(bs) ax = bspp.get_projected_plots_dots(orbitals, ylim=ylim).gcf().gca() ax.set_xticklabels([r'$\mathrm{%s}$' % t for t in ax.get_xticklabels()]) ax.set_yticklabels([r'$\mathrm{%s}$' % t for t in ax.get_yticklabels()]) if fmt == "None": return ax else: plt.savefig('orb_projected_bands.{}'.format(fmt)) plt.close()
def test_get_band_structure(self): filepath = os.path.join(test_dir, 'vasprun_Si_bands.xml') vasprun = Vasprun(filepath, parse_projected_eigen=True, parse_potcar_file=False) bs = vasprun.get_band_structure(kpoints_filename= os.path.join(test_dir, 'KPOINTS_Si_bands')) cbm = bs.get_cbm() vbm = bs.get_vbm() self.assertEqual(cbm['kpoint_index'], [13], "wrong cbm kpoint index") self.assertAlmostEqual(cbm['energy'], 6.2301, "wrong cbm energy") self.assertEqual(cbm['band_index'], {Spin.up: [4], Spin.down: [4]}, "wrong cbm bands") self.assertEqual(vbm['kpoint_index'], [0, 63, 64]) self.assertAlmostEqual(vbm['energy'], 5.6158, "wrong vbm energy") self.assertEqual(vbm['band_index'], {Spin.up: [1, 2, 3], Spin.down: [1, 2, 3]}, "wrong vbm bands") self.assertEqual(vbm['kpoint'].label, "\Gamma", "wrong vbm label") self.assertEqual(cbm['kpoint'].label, None, "wrong cbm label") projected = bs.get_projection_on_elements() self.assertAlmostEqual(projected[Spin.up][0][0]["Si"], 0.4238) projected = bs.get_projections_on_elements_and_orbitals({"Si": ["s"]}) self.assertAlmostEqual(projected[Spin.up][0][0]["Si"]["s"], 0.4238)
def test_get_band_structure(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") filepath = os.path.join(test_dir, 'vasprun_Si_bands.xml') vasprun = Vasprun(filepath, parse_projected_eigen=True, parse_potcar_file=False) bs = vasprun.get_band_structure( kpoints_filename=os.path.join(test_dir, 'KPOINTS_Si_bands')) cbm = bs.get_cbm() vbm = bs.get_vbm() self.assertEqual(cbm['kpoint_index'], [13], "wrong cbm kpoint index") self.assertAlmostEqual(cbm['energy'], 6.2301, "wrong cbm energy") self.assertEqual(cbm['band_index'], { Spin.up: [4], Spin.down: [4] }, "wrong cbm bands") self.assertEqual(vbm['kpoint_index'], [0, 63, 64]) self.assertAlmostEqual(vbm['energy'], 5.6158, "wrong vbm energy") self.assertEqual(vbm['band_index'], { Spin.up: [1, 2, 3], Spin.down: [1, 2, 3] }, "wrong vbm bands") self.assertEqual(vbm['kpoint'].label, "\\Gamma", "wrong vbm label") self.assertEqual(cbm['kpoint'].label, None, "wrong cbm label") projected = bs.get_projection_on_elements() self.assertAlmostEqual(projected[Spin.up][0][0]["Si"], 0.4238) projected = bs.get_projections_on_elements_and_orbitals( {"Si": ["s"]}) self.assertAlmostEqual(projected[Spin.up][0][0]["Si"]["s"], 0.4238)
def plot_orb_projected_bands(orbitals, fmt='pdf', ylim=(-5, 5)): """ Plot a separate band structure for each orbital of each element in orbitals. Args: orbitals (dict): dictionary of the form {element: [orbitals]}, e.g. {'Mo': ['s', 'p', 'd'], 'S': ['p']} ylim (tuple): minimum and maximum energies for the plot's y-axis. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ vasprun = Vasprun('vasprun.xml', parse_projected_eigen=True) bs = vasprun.get_band_structure('KPOINTS', line_mode=True) bspp = BSPlotterProjected(bs) ax = bspp.get_projected_plots_dots(orbitals, ylim=ylim).gcf().gca() ax.set_xticklabels([r'$\mathrm{%s}$' % t for t in ax.get_xticklabels()]) ax.set_yticklabels([r'$\mathrm{%s}$' % t for t in ax.get_yticklabels()]) if fmt == "None": return ax else: plt.savefig('orb_projected_bands.{}'.format(fmt)) plt.close()
def plot_local_potential(axis=2, ylim=(-20, 0), fmt='pdf'): """ Plot data from the LOCPOT file along any of the 3 primary axes. Useful for determining surface dipole moments and electric potentials on the interior of the material. Args: axis (int): 0 = x, 1 = y, 2 = z ylim (tuple): minimum and maximum potentials for the plot's y-axis. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ ax = plt.figure(figsize=(16, 10)).gca() locpot = Locpot.from_file('LOCPOT') structure = Structure.from_file('CONTCAR') vd = VolumetricData(structure, locpot.data) abs_potentials = vd.get_average_along_axis(axis) vacuum_level = max(abs_potentials) vasprun = Vasprun('vasprun.xml') bs = vasprun.get_band_structure() if not bs.is_metal(): cbm = bs.get_cbm()['energy'] - vacuum_level vbm = bs.get_vbm()['energy'] - vacuum_level potentials = [potential - vacuum_level for potential in abs_potentials] axis_length = structure.lattice._lengths[axis] positions = np.arange(0, axis_length, axis_length / len(potentials)) ax.plot(positions, potentials, linewidth=2, color='k') ax.set_xlim(0, axis_length) ax.set_ylim(ylim[0], ylim[1]) ax.set_xticklabels( [r'$\mathrm{%s}$' % tick for tick in ax.get_xticks()], size=20) ax.set_yticklabels( [r'$\mathrm{%s}$' % tick for tick in ax.get_yticks()], size=20) ax.set_xlabel(r'$\mathrm{\AA}$', size=24) ax.set_ylabel(r'$\mathrm{V\/(eV)}$', size=24) if not bs.is_metal(): ax.text(ax.get_xlim()[1], cbm, r'$\mathrm{CBM}$', horizontalalignment='right', verticalalignment='bottom', size=20) ax.text(ax.get_xlim()[1], vbm, r'$\mathrm{VBM}$', horizontalalignment='right', verticalalignment='top', size=20) ax.fill_between(ax.get_xlim(), cbm, ax.get_ylim()[1], facecolor=plt.cm.jet(0.3), zorder=0, linewidth=0) ax.fill_between(ax.get_xlim(), ax.get_ylim()[0], vbm, facecolor=plt.cm.jet(0.7), zorder=0, linewidth=0) if fmt == "None": return ax else: plt.savefig('locpot.{}'.format(fmt)) plt.close()
def plot_local_potential(axis=2, ylim=(-20, 0), fmt='pdf'): """ Plot data from the LOCPOT file along any of the 3 primary axes. Useful for determining surface dipole moments and electric potentials on the interior of the material. Args: axis (int): 0 = x, 1 = y, 2 = z ylim (tuple): minimum and maximum potentials for the plot's y-axis. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ ax = plt.figure(figsize=(16, 10)).gca() locpot = Locpot.from_file('LOCPOT') structure = Structure.from_file('CONTCAR') vd = VolumetricData(structure, locpot.data) abs_potentials = vd.get_average_along_axis(axis) vacuum_level = max(abs_potentials) vasprun = Vasprun('vasprun.xml') bs = vasprun.get_band_structure() if not bs.is_metal(): cbm = bs.get_cbm()['energy'] - vacuum_level vbm = bs.get_vbm()['energy'] - vacuum_level potentials = [potential - vacuum_level for potential in abs_potentials] axis_length = structure.lattice.lengths[axis] positions = np.arange(0, axis_length, axis_length / len(potentials)) ax.plot(positions, potentials, linewidth=2, color='k') ax.set_xlim(0, axis_length) ax.set_ylim(ylim[0], ylim[1]) ax.set_xticklabels( [r'$\mathrm{%s}$' % tick for tick in ax.get_xticks()], size=20) ax.set_yticklabels( [r'$\mathrm{%s}$' % tick for tick in ax.get_yticks()], size=20) ax.set_xlabel(r'$\mathrm{\AA}$', size=24) ax.set_ylabel(r'$\mathrm{V\/(eV)}$', size=24) if not bs.is_metal(): ax.text(ax.get_xlim()[1], cbm, r'$\mathrm{CBM}$', horizontalalignment='right', verticalalignment='bottom', size=20) ax.text(ax.get_xlim()[1], vbm, r'$\mathrm{VBM}$', horizontalalignment='right', verticalalignment='top', size=20) ax.fill_between(ax.get_xlim(), cbm, ax.get_ylim()[1], facecolor=plt.cm.jet(0.3), zorder=0, linewidth=0) ax.fill_between(ax.get_xlim(), ax.get_ylim()[0], vbm, facecolor=plt.cm.jet(0.7), zorder=0, linewidth=0) if fmt == "None": return ax else: plt.savefig('locpot.{}'.format(fmt)) plt.close()
def plot_simple_smoothed_band_structure(ylim=[-1.5, 3.5], filename=None): vasprun = Vasprun('./vasprun.xml') bs = vasprun.get_band_structure(line_mode=True) if filename is None: # BSPlotter(bs).get_plot(smooth=True,ylim=ylim) BSPlotter(bs).show(smooth=True, ylim=ylim) else: BSPlotter(bs).save_plot(filename)
def bandgap(directory): # Load the vasprun.xml file vasprun = Vasprun(os.path.join(directory, "vasprun.xml")) # Extract the band gap from the band structure band_gap = vasprun.get_band_structure().get_band_gap() print("Band gap = " + str(band_gap) + " eV")
def fsplot( filename: Optional[Union[Path, str]] = None, interpolate_factor: int = 8, mu: float = 0.0, wigner_seitz: bool = True, spin: Optional[Spin] = None, plot_type: str = "plotly", interactive: bool = False, prefix: Optional[str] = None, directory: Optional[Union[Path, str]] = None, image_format: str = "png", dpi: float = 400, ): """Plot Fermi surfaces from a vasprun.xml file. Args: filename: Path to input vasprun file. interpolate_factor: The factor by which to interpolate the bands. mu: The level above the Fermi energy at which the isosurfaces are to be plotted. wigner_seitz: Controls whether the cell is the Wigner-Seitz cell or the reciprocal unit cell parallelepiped. spin: The spin channel to plot. By default plots both spin channels. plot_type: Method used for plotting. Valid options are: "matplotlib", "plotly", "mayavi". interactive: Whether to enable interactive plots. prefix: Prefix for file names. directory: The directory in which to save files. image_format: The image file format. dpi: The dots-per-inch (pixel density) for the image. Returns: The filename written to disk. """ from ifermi.fermi_surface import FermiSurface from ifermi.interpolator import Interpolater from ifermi.plotter import FSPlotter if not filename: filename = find_vasprun_file() vr = Vasprun(filename) bs = vr.get_band_structure() interpolater = Interpolater(bs) interp_bs, kpoint_dim = interpolater.interpolate_bands(interpolate_factor) fs = FermiSurface.from_band_structure( interp_bs, kpoint_dim, mu=mu, wigner_seitz=wigner_seitz, spin=spin, ) plotter = FSPlotter(fs) directory = directory if directory else "." prefix = "{}_".format(prefix) if prefix else "" output_filename = "{}fermi_surface.{}".format(prefix, image_format) output_filename = Path(directory) / output_filename plotter.plot(plot_type=plot_type, interactive=interactive, filename=output_filename)
def get_band_edges(): """ Calculate the band edge locations relative to the vacuum level for a semiconductor. Returns: edges (dict): {'up_cbm': , 'up_vbm': , 'dn_cbm': , 'dn_vbm': , 'efermi'} """ # Vacuum level energy from LOCPOT. locpot = Locpot.from_file('LOCPOT') evac = max(locpot.get_average_along_axis(2)) vasprun = Vasprun('vasprun.xml') bs = vasprun.get_band_structure() eigenvals = vasprun.eigenvalues efermi = vasprun.efermi - evac if bs.is_spin_polarized: print(eigenvals[Spin.up]) print([e[0] - evac for e in eigenvals[Spin.up][0]]) up_cbm = min([ min([e[0] for e in eigenvals[Spin.up][i] if not e[1]]) for i in range(len(eigenvals[Spin.up])) ]) - evac up_vbm = max([ max([e[0] for e in eigenvals[Spin.up][i] if e[1]]) for i in range(len(eigenvals[Spin.up])) ]) - evac dn_cbm = min([ min([e[0] for e in eigenvals[Spin.down][i] if not e[1]]) for i in range(len(eigenvals[Spin.down])) ]) - evac dn_vbm = max([ max([e[0] for e in eigenvals[Spin.down][i] if e[1]]) for i in range(len(eigenvals[Spin.down])) ]) - evac edges = { 'up_cbm': up_cbm, 'up_vbm': up_vbm, 'dn_cbm': dn_cbm, 'dn_vbm': dn_vbm, 'efermi': efermi } else: cbm = bs.get_cbm()['energy'] - evac vbm = bs.get_vbm()['energy'] - evac edges = { 'up_cbm': cbm, 'up_vbm': vbm, 'dn_cbm': cbm, 'dn_vbm': vbm, 'efermi': efermi } return edges
def get_dir_indir_gap(run=""): """ Get direct and indirect bandgaps for a vasprun.xml """ v = Vasprun(run) bandstructure = v.get_band_structure() dir_gap = bandstructure.get_direct_band_gap() indir_gap = bandstructure.get_band_gap()["energy"] return dir_gap, indir_gap
def banddos(pref='',storedir=None): ru=str("vasprun.xml") kpfile=str("KPOINTS") run = Vasprun(ru, parse_projected_eigen = True) bands = run.get_band_structure(kpfile, line_mode = True, efermi = run.efermi) bsp = BSPlotter(bands) zero_to_efermi=True bandgap=str(round(bands.get_band_gap()['energy'],3)) print "bg=",bandgap data=bsp.bs_plot_data(zero_to_efermi) plt = get_publication_quality_plot(12, 8) band_linewidth = 3 x_max = data['distances'][-1][-1] print (x_max) for d in range(len(data['distances'])): for i in range(bsp._nb_bands): plt.plot(data['distances'][d], [data['energy'][d]['1'][i][j] for j in range(len(data['distances'][d]))], 'b-', linewidth=band_linewidth) if bsp._bs.is_spin_polarized: plt.plot(data['distances'][d], [data['energy'][d]['-1'][i][j] for j in range(len(data['distances'][d]))], 'r--', linewidth=band_linewidth) bsp._maketicks(plt) if bsp._bs.is_metal(): e_min = -10 e_max = 10 band_linewidth = 3 for cbm in data['cbm']: plt.scatter(cbm[0], cbm[1], color='r', marker='o', s=100) for vbm in data['vbm']: plt.scatter(vbm[0], vbm[1], color='g', marker='o', s=100) plt.xlabel(r'$\mathrm{Wave\ Vector}$', fontsize=30) ylabel = r'$\mathrm{E\ -\ E_f\ (eV)}$' if zero_to_efermi \ else r'$\mathrm{Energy\ (eV)}$' plt.ylabel(ylabel, fontsize=30) plt.ylim(-4,4) plt.xlim(0,x_max) plt.tight_layout() plt.savefig('BAND.png',img_format="png") plt.close()
def get_band_edges(): """ Calculate the band edge locations relative to the vacuum level for a semiconductor. If spin-polarized, returns all 4 band edges. """ # Vacuum level energy from LOCPOT. locpot = Locpot.from_file('LOCPOT') evac = max(locpot.get_average_along_axis(2)) vasprun = Vasprun('vasprun.xml') efermi = vasprun.efermi - evac if vasprun.get_band_structure().is_spin_polarized: eigenvals = {Spin.up: [], Spin.down: []} for band in vasprun.eigenvalues: for eigenvalue in vasprun.eigenvalues[band]: eigenvals[band[0]].append(eigenvalue) up_cbm = min([e[0] for e in eigenvals[Spin.up] if not e[1]]) - evac up_vbm = max([e[0] for e in eigenvals[Spin.up] if e[1]]) - evac dn_cbm = min([e[0] for e in eigenvals[Spin.down] if not e[1]]) - evac dn_vbm = max([e[0] for e in eigenvals[Spin.down] if e[1]]) - evac edges = { 'up_cbm': up_cbm, 'up_vbm': up_vbm, 'dn_cbm': dn_cbm, 'dn_vbm': dn_vbm, 'efermi': efermi } else: bs = vasprun.get_band_structure() cbm = bs.get_cbm()['energy'] - evac vbm = bs.get_vbm()['energy'] - evac edges = {'cbm': cbm, 'vbm': vbm, 'efermi': efermi} return edges
def test_get_band_structure(self): filepath = os.path.join(test_dir, "vasprun_Si_bands.xml") vasprun = Vasprun(filepath, parse_potcar_file=False) bs = vasprun.get_band_structure(kpoints_filename=os.path.join(test_dir, "KPOINTS_Si_bands")) cbm = bs.get_cbm() vbm = bs.get_vbm() self.assertEqual(cbm["kpoint_index"], [13], "wrong cbm kpoint index") self.assertAlmostEqual(cbm["energy"], 6.2301, "wrong cbm energy") self.assertEqual(cbm["band_index"], {Spin.up: [4], Spin.down: [4]}, "wrong cbm bands") self.assertEqual(vbm["kpoint_index"], [0, 63, 64]) self.assertAlmostEqual(vbm["energy"], 5.6158, "wrong vbm energy") self.assertEqual(vbm["band_index"], {Spin.up: [1, 2, 3], Spin.down: [1, 2, 3]}, "wrong vbm bands") self.assertEqual(vbm["kpoint"].label, "\Gamma", "wrong vbm label") self.assertEqual(cbm["kpoint"].label, None, "wrong cbm label")
def plot_elt_projected_bands(ylim=(-5, 5), fmt="pdf"): """ Plot separate band structures for each element where the size of the markers indicates the elemental character of the eigenvalue. Args: ylim (tuple): minimum and maximum energies for the plot's y-axis. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ vasprun = Vasprun("vasprun.xml", parse_projected_eigen=True) bs = vasprun.get_band_structure("KPOINTS", line_mode=True) bspp = BSPlotterProjected(bs) bspp.get_elt_projected_plots(ylim=ylim).savefig("elt_projected_bands.{}".format(fmt)) plt.close()
def plot_elt_projected_bands(ylim=(-5, 5), fmt='pdf'): """ Plot separate band structures for each element where the size of the markers indicates the elemental character of the eigenvalue. Args: ylim (tuple): minimum and maximum energies for the plot's y-axis. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ vasprun = Vasprun('vasprun.xml', parse_projected_eigen=True) bs = vasprun.get_band_structure('KPOINTS', line_mode=True) bspp = BSPlotterProjected(bs) bspp.get_elt_projected_plots(ylim=ylim).savefig( 'elt_projected_bands.{}'.format(fmt)) plt.close()
def get_band_edges(): """ Calculate the band edge locations relative to the vacuum level for a semiconductor. For a metal, returns the fermi level. Returns: edges (dict): {'up_cbm': , 'up_vbm': , 'dn_cbm': , 'dn_vbm': , 'efermi'} """ # Vacuum level energy from LOCPOT. locpot = Locpot.from_file('LOCPOT') evac = max(locpot.get_average_along_axis(2)) vasprun = Vasprun('vasprun.xml') bs = vasprun.get_band_structure() eigenvals = vasprun.eigenvalues efermi = vasprun.efermi - evac if bs.is_metal(): edges = {'up_cbm': None, 'up_vbm': None, 'dn_cbm': None, 'dn_vbm': None, 'efermi': efermi} elif bs.is_spin_polarized: up_cbm = min( [min([e[0] for e in eigenvals[Spin.up][i] if not e[1]]) for i in range(len(eigenvals[Spin.up]))]) - evac up_vbm = max( [max([e[0] for e in eigenvals[Spin.up][i] if e[1]]) for i in range(len(eigenvals[Spin.up]))]) - evac dn_cbm = min( [min([e[0] for e in eigenvals[Spin.down][i] if not e[1]]) for i in range(len(eigenvals[Spin.down]))]) - evac dn_vbm = max( [max([e[0] for e in eigenvals[Spin.down][i] if e[1]]) for i in range(len(eigenvals[Spin.down]))]) - evac edges = {'up_cbm': up_cbm, 'up_vbm': up_vbm, 'dn_cbm': dn_cbm, 'dn_vbm': dn_vbm, 'efermi': efermi} else: cbm = bs.get_cbm()['energy'] - evac vbm = bs.get_vbm()['energy'] - evac edges = {'up_cbm': cbm, 'up_vbm': vbm, 'dn_cbm': cbm, 'dn_vbm': vbm, 'efermi': efermi} return edges
def test_get_band_structure(self): filepath = os.path.join(test_dir, 'vasprun_Si_bands.xml') vasprun = Vasprun(filepath, parse_potcar_file=False) bs = vasprun.get_band_structure(kpoints_filename= os.path.join(test_dir, 'KPOINTS_Si_bands')) cbm = bs.get_cbm() vbm = bs.get_vbm() self.assertEqual(cbm['kpoint_index'], [13], "wrong cbm kpoint index") self.assertAlmostEqual(cbm['energy'], 6.2301, "wrong cbm energy") self.assertEqual(cbm['band_index'], {Spin.up: [4], Spin.down: [4]}, "wrong cbm bands") self.assertEqual(vbm['kpoint_index'], [0, 63, 64]) self.assertAlmostEqual(vbm['energy'], 5.6158, "wrong vbm energy") self.assertEqual(vbm['band_index'], {Spin.up: [1, 2, 3], Spin.down: [1, 2, 3]}, "wrong vbm bands") self.assertEqual(vbm['kpoint'].label, "\Gamma", "wrong vbm label") self.assertEqual(cbm['kpoint'].label, None, "wrong cbm label")
def read_convergence_data(self, data_dir): results = {} if 'G0W0' in data_dir or 'GW0' in data_dir or 'scGW0' in data_dir: run = os.path.join(data_dir, 'vasprun.xml') kpoints = os.path.join(data_dir, 'IBZKPT') if os.path.isfile(run): try: logger.debug(run) print(run) data = Vasprun(run, ionic_step_skip=1) parameters = data.incar.as_dict() bandstructure = data.get_band_structure(kpoints) results = {'ecuteps': parameters['ENCUTGW'], 'nbands': parameters['NBANDS'], 'nomega': parameters['NOMEGA'], 'gwgap': bandstructure.get_band_gap()['energy']} print(results) except (IOError, OSError, IndexError, KeyError): pass return results
def plot_orb_projected_bands(orbitals, fmt="pdf", ylim=(-5, 5)): """ Plot a separate band structure for each orbital of each element in orbitals. Args: orbitals (dict): dictionary of the form {element: [orbitals]}, e.g. {'Mo': ['s', 'p', 'd'], 'S': ['p']} ylim (tuple): minimum and maximum energies for the plot's y-axis. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ vasprun = Vasprun("vasprun.xml", parse_projected_eigen=True) bs = vasprun.get_band_structure("KPOINTS", line_mode=True) bspp = BSPlotterProjected(bs) bspp.get_projected_plots_dots(orbitals, ylim=ylim).savefig("orb_projected_bands.{}".format(fmt)) plt.close()
def __init__(self, waveder_file_ip, outcar_file_ip, vasprun_file_static): """ waveder and outcar files from the linear optical independent particle approximation vasprun file from the associated static calculation """ waveder = Waveder(waveder_file_ip) outcar = Outcar(outcar_file_ip) vasprun = Vasprun(vasprun_file_static) M_norm = norm(waveder.cder_data, axis=-1) * (1e-10 / e) self.M_squared = M_norm * M_norm nelect = round(outcar.nelect) self.vbm_band = nelect // 2 - 1 self.cbm_band = nelect // 2 self.bs = vasprun.get_band_structure() self.nbands = self.bs.nb_bands self.kpoints = self.bs.kpoints self.nkpoints = waveder.nkpoints
def plot_color_projected_bands(ylim=(-5, 5), fmt="pdf"): """ Plot a single band structure where the color of the band indicates the elemental character of the eigenvalue. Args: ylim (tuple): minimum and maximum energies for the plot's y-axis. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ vasprun = Vasprun("vasprun.xml", parse_projected_eigen=True) bs = vasprun.get_band_structure("KPOINTS", line_mode=True) bspp = BSPlotterProjected(bs) plot = bspp.get_elt_projected_plots_color() fig = plot.gcf() ax = fig.gca() ax.set_xticklabels([r"$\mathrm{%s}$" % t for t in ax.get_xticklabels()]) ax.set_ylim(ylim) fig.savefig("color_projected_bands.{}".format(fmt)) plt.close()
def plot_color_projected_bands(ylim=(-5, 5), fmt='pdf'): """ Plot a single band structure where the color of the band indicates the elemental character of the eigenvalue. Args: ylim (tuple): minimum and maximum energies for the plot's y-axis. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ vasprun = Vasprun('vasprun.xml', parse_projected_eigen=True) bs = vasprun.get_band_structure('KPOINTS', line_mode=True) bspp = BSPlotterProjected(bs) plot = bspp.get_elt_projected_plots_color() fig = plot.gcf() ax = fig.gca() ax.set_xticklabels([r'$\mathrm{%s}$' % t for t in ax.get_xticklabels()]) ax.set_ylim(ylim) fig.savefig('color_projected_bands.{}'.format(fmt)) plt.close()
def read_convergence_data(self, data_dir): results = {} if 'G0W0' in data_dir or 'GW0' in data_dir or 'scGW0' in data_dir: run = os.path.join(data_dir, 'vasprun.xml') kpoints = os.path.join(data_dir, 'IBZKPT') if os.path.isfile(run): try: logger.debug(run) print(run) data = Vasprun(run, ionic_step_skip=1) parameters = data.incar.as_dict() bandstructure = data.get_band_structure(kpoints) results = { 'ecuteps': parameters['ENCUTGW'], 'nbands': parameters['NBANDS'], 'nomega': parameters['NOMEGA'], 'gwgap': bandstructure.get_band_gap()['energy'] } print(results) except (IOError, OSError, IndexError, KeyError): pass return results
def get_fermi_velocities(): """ Calculates the fermi velocity of each band that crosses the fermi level, according to v_F = dE/(h_bar*dk). Returns: fermi_velocities (list). The absolute values of the adjusted slopes of each band, in Angstroms/s. """ vr = Vasprun('vasprun.xml') eigenvalues = vr.eigenvalues bs = vr.get_band_structure() bands = bs.bands kpoints = bs.kpoints efermi = bs.efermi h_bar = 6.582e-16 # eV*s fermi_bands = [] for spin in bands: for i in range(len(bands[spin])): if max(bands[spin][i]) > efermi > min(bands[spin][i]): fermi_bands.append(bands[spin][i]) fermi_velocities = [] for band in fermi_bands: for i in range(len(band) - 1): if (band[i] < efermi and band[i + 1] > efermi) or (band[i] > efermi and band[i + 1] < efermi): dk = np.sqrt((kpoints[i + 1].cart_coords[0] - kpoints[i].cart_coords[0])**2 + (kpoints[i + 1].cart_coords[1] - kpoints[i].cart_coords[1])**2) v_f = abs((band[i + 1] - band[i]) / (h_bar * dk)) fermi_velocities.append(v_f) return fermi_velocities # Values are in Angst./s
def plot_elt_projected_bands(ylim=(-5, 5), fmt='pdf'): """ Plot separate band structures for each element where the size of the markers indicates the elemental character of the eigenvalue. Args: ylim (tuple): minimum and maximum energies for the plot's y-axis. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ vasprun = Vasprun('vasprun.xml', parse_projected_eigen=True) bs = vasprun.get_band_structure('KPOINTS', line_mode=True) bspp = BSPlotterProjected(bs) ax = bspp.get_elt_projected_plots(ylim=ylim).gcf().gca() ax.set_xticklabels([r'$\mathrm{%s}$' % t for t in ax.get_xticklabels()]) ax.set_yticklabels([r'$\mathrm{%s}$' % t for t in ax.get_yticklabels()]) if fmt == "None": return ax else: plt.savefig('elt_projected_bands.{}'.format(fmt)) plt.close()
def get_fermi_velocities(): """ Calculates the fermi velocity of each band that crosses the fermi level, according to v_F = dE/(h_bar*dk). Returns: fermi_velocities (list). The absolute values of the adjusted slopes of each band, in Angstroms/s. """ vr = Vasprun('vasprun.xml') # eigenvalues = vr.eigenvalues bs = vr.get_band_structure() bands = bs.bands kpoints = bs.kpoints efermi = bs.efermi h_bar = 6.582e-16 # eV*s fermi_bands = [] for spin in bands: for i in range(len(bands[spin])): if max(bands[spin][i]) > efermi > min(bands[spin][i]): fermi_bands.append(bands[spin][i]) fermi_velocities = [] for band in fermi_bands: for i in range(len(band)-1): if (band[i] < efermi < band[i+1]) or (band[i] > efermi > band[i+1]): dk = np.sqrt((kpoints[i+1].cart_coords[0] - kpoints[i].cart_coords[0])**2 + (kpoints[i+1].cart_coords[1] - kpoints[i].cart_coords[1])**2) v_f = abs((band[i+1] - band[i]) / (h_bar * dk)) fermi_velocities.append(v_f) return fermi_velocities # Values are in Angst./s
def plot_band_structure(ylim=(-5, 5), draw_fermi=False, fmt="pdf"): """ Plot a standard band structure with no projections. Args: ylim (tuple): minimum and maximum potentials for the plot's y-axis. draw_fermi (bool): whether or not to draw a dashed line at E_F. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ vasprun = Vasprun("vasprun.xml") efermi = vasprun.efermi bsp = BSPlotter(vasprun.get_band_structure("KPOINTS", line_mode=True, efermi=efermi)) plot = bsp.get_plot(ylim=ylim) fig = plot.gcf() ax = fig.gca() ax.set_xticklabels([r"$\mathrm{%s}$" % t for t in ax.get_xticklabels()]) if draw_fermi: ax.plot([ax.get_xlim()[0], ax.get_xlim()[1]], [0, 0], "k--") fig.savefig("band_structure.{}".format(fmt), transparent=True) plt.close()
nseg = len(k)-1 r = [0.5*(red[i]+red[i+1]) for i in range(nseg)] g = [0.5*(green[i]+green[i+1]) for i in range(nseg)] b = [0.5*(blue[i]+blue[i+1]) for i in range(nseg)] a = np.ones(nseg, np.float)*alpha lc = LineCollection(seg, colors=zip(r,g,b,a), linewidth = 2) ax.add_collection(lc) if __name__ == "__main__": # -------------------------------------------------------------- # read data # -------------------------------------------------------------- # readin bandstructure and density of states from vasprun.xml file run = Vasprun("vasprun.xml", parse_projected_eigen = True) bands = run.get_band_structure("KPOINTS", line_mode = True, efermi = run.efermi) complete_dos = run.complete_dos print 'cbm and vbm ', complete_dos.get_cbm_vbm() print 'gap = ', complete_dos.get_gap() # get orbital projected DOS. spd_dos = complete_dos.get_spd_dos() # kpoints labels, must conform with the label in the KPOINTS file labels = [ r"$G$", r"$X$", r"$M$", r"$G$"] # -------------------------------------------------------------- # compute a dictionary of projections on elements and specific orbitals #A dictionary of Elements and Orbitals for which we want #to have projections on. It is given as: {Element:[orbitals]}, #e.g., {'Cu':['d','s']} # -------------------------------------------------------------- pbands = bands.get_projections_on_elts_and_orbitals({"Fe": ["s", "p", "d"]})
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 = 0 energy_max = 0.12 # 高对称点设置 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') # 设置能量区间 ax1.set_ylim(energy_min, energy_max) # 设置x轴区间
# !/usr/bin/env python # -*- coding: utf-8 -*- from pymatgen.io.vasp.outputs import Vasprun from pymatgen.electronic_structure.plotter import BSPlotter vasprun = Vasprun("vasprun.xml") bss = vasprun.get_band_structure(kpoints_filename="KPOINTS", line_mode=True) plotter = BSPlotter(bss) #plotter.save_plot("bandStructure.svg", img_format="svg") #plotter.save_plot("bandStructure.png", img_format="png") #plotter.save_plot("lim_bandStructure.svg", img_format="svg", ylim=(-.2, 1.4)) plotter.save_plot("MAPbI3-primitive.png", img_format="png", ylim=(-5, 5)) plotter.plot_brillouin()
import numpy as np import matplotlib.pyplot as plt from matplotlib import gridspec from matplotlib.pyplot import figure import matplotlib matplotlib.rcParams.update({'font.size': 22}) # from pymatgen.io.vasp.outputs import Vasprun # modified version of pymatgen plotter from my_functions.pmg_electronic_structure_plotter import BSPlotter vaspout = Vasprun("./vasprun.xml") bandstr = vaspout.get_band_structure(line_mode=True) # give range for y axis ymin = -7 ymax = 6 BSPlotter(bandstr).get_plot(ylim=[ymin, ymax], get_subplot=True) # path for location of DOS file dos_path = '..' dos_path += '/1-DOS/' # give elements in list type_elements = ['Na', 'Nb', 'O'] # give a list of orbitals you want to plot for each element : 'element_orbital'
def _get_fermi_surface( filename, interpolation_factor, properties, mu, decimate_factor, smooth, wigner_seitz, calculate_dimensionality, ): """Common helper method to get Fermi surface""" import numpy as np from pymatgen.electronic_structure.core import Spin from pymatgen.io.vasp.outputs import Vasprun from ifermi.interpolate import FourierInterpolator from ifermi.kpoints import kpoints_from_bandstructure from ifermi.surface import FermiSurface if not filename: filename = find_vasprun_file() parse_projections = properties == "spin" vr = Vasprun(filename, parse_projected_eigen=parse_projections) bs = vr.get_band_structure() interpolator = FourierInterpolator(bs) interp_bs, velocities = interpolator.interpolate_bands( interpolation_factor, return_velocities=True ) property_data = None property_kpoints = None if properties == "velocity": property_data = velocities property_kpoints = kpoints_from_bandstructure(interp_bs) elif properties == "spin": if vr.projected_magnetisation is not None: # transpose so shape is (nbands, nkpoints, natoms, norbitals, 3) property_data = vr.projected_magnetisation.transpose(1, 0, 2, 3, 4) # sum across all atoms and orbitals property_data = property_data.sum(axis=(2, 3)) property_data /= np.linalg.norm(property_data, axis=-1)[..., None] property_data = {Spin.up: property_data} property_kpoints = kpoints_from_bandstructure(bs) else: click.echo( "ERROR: Band structure does not include spin properties.\n" "Ensure calculation was run with LSORBIT or LNONCOLLINEAR = True " "and LSORBIT = 11." ) sys.exit() return ( FermiSurface.from_band_structure( interp_bs, mu=mu, wigner_seitz=wigner_seitz, decimate_factor=decimate_factor, smooth=smooth, property_data=property_data, property_kpoints=property_kpoints, calculate_dimensionality=calculate_dimensionality, ), bs, )
yaxis=dosyaxis, font=dict( family="Arial", size=22 ) ) dosfig = go.Figure(data=dosdata, layout=doslayout) plot_url = iplot(dosfig, filename="DOS") # In[9]: run = Vasprun("./vasprun.xml", parse_projected_eigen = True) bands = run.get_band_structure("./KPOINTS", line_mode=True, efermi=dosrun.efermi) # In[10]: # Look for the boundaries of the band diagram in order to set up y axes range. emin = 1e100 emax = -1e100 for spin in bands.bands.keys(): for band in range(bands.nb_bands): emin = min(emin, min(bands.bands[spin][band])) emax = max(emax, max(bands.bands[spin][band])) emin = emin - bands.efermi - 1 emax = emax - bands.efermi + 1
if __name__ == "__main__": # read data # --------- # kpoints labels labels = [r"$L$", r"$\Gamma$", r"$X$", r"$U,K$", r"$\Gamma$"] # density of states dosrun = Vasprun("./DOS/vasprun.xml") spd_dos = dosrun.complete_dos.get_spd_dos() # bands run = Vasprun("./Bandes/vasprun.xml", parse_projected_eigen=True) bands = run.get_band_structure("./Bandes/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")
from pathlib import Path from monty.serialization import dumpfn from ifermi.fermi_surface import FermiSurface from ifermi.interpolator import Interpolater from pymatgen.io.vasp.outputs import Vasprun if __name__ == "__main__": example_dir = Path("../../examples") vr = Vasprun(example_dir / "MgB2/vasprun.xml") bs = vr.get_band_structure() dumpfn(bs.structure, "structure.json.gz") interpolater = Interpolater(bs) new_bs, kpoint_dim = interpolater.interpolate_bands(1) bs_data = {"bs": new_bs, "dim": kpoint_dim, "structure": bs.structure} dumpfn(bs_data, "bs_BaFe2As2.json.gz") fs = FermiSurface.from_band_structure(new_bs, kpoint_dim, wigner_seitz=True) dumpfn(fs, "fs_BaFe2As2_wigner.json.gz") dumpfn(fs.reciprocal_space, "rs_wigner.json.gz") fs = FermiSurface.from_band_structure(new_bs, kpoint_dim, wigner_seitz=False) dumpfn(fs, "fs_BaFe2As2_reciprocal.json.gz") dumpfn(fs.reciprocal_space, "rs_reciprocal.json.gz")
def assimilate(self, path, launches_coll=None): """ Parses vasp runs. Then insert the result into the db. and return the task_id or doc of the insertion. Returns: If in simulate_mode, the entire doc is returned for debugging purposes. Else, only the task_id of the inserted doc is returned. """ d = self.get_task_doc(path) if self.additional_fields: d.update(self.additional_fields) # always add additional fields, even for failed jobs try: d["dir_name_full"] = d["dir_name"].split(":")[1] d["dir_name"] = get_block_part(d["dir_name_full"]) d["stored_data"] = {} except: print 'COULD NOT GET DIR NAME' pprint.pprint(d) print traceback.format_exc() raise ValueError('IMPROPER PARSING OF {}'.format(path)) if not self.simulate: # Perform actual insertion into db. Because db connections cannot # be pickled, every insertion needs to create a new connection # to the db. conn = MongoClient(self.host, self.port) db = conn[self.database] if self.user: db.authenticate(self.user, self.password) coll = db[self.collection] # Insert dos data into gridfs and then remove it from the dict. # DOS data tends to be above the 4Mb limit for mongo docs. A ref # to the dos file is in the dos_fs_id. result = coll.find_one({"dir_name": d["dir_name"]}) if result is None or self.update_duplicates: if self.parse_dos and "calculations" in d: for calc in d["calculations"]: if "dos" in calc: dos = json.dumps(calc["dos"], cls=MontyEncoder) fs = gridfs.GridFS(db, "dos_fs") dosid = fs.put(dos) calc["dos_fs_id"] = dosid del calc["dos"] d["last_updated"] = datetime.datetime.today() if result is None: if ("task_id" not in d) or (not d["task_id"]): d["task_id"] = "mp-{}".format( db.counter.find_one_and_update( {"_id": "taskid"}, {"$inc": {"c": 1}} )["c"]) logger.info("Inserting {} with taskid = {}" .format(d["dir_name"], d["task_id"])) elif self.update_duplicates: d["task_id"] = result["task_id"] logger.info("Updating {} with taskid = {}" .format(d["dir_name"], d["task_id"])) #Fireworks processing self.process_fw(path, d) try: #Add oxide_type struct=Structure.from_dict(d["output"]["crystal"]) d["oxide_type"]=oxide_type(struct) except: logger.error("can't get oxide_type for {}".format(d["task_id"])) d["oxide_type"] = None #Override incorrect outcar subdocs for two step relaxations if "optimize structure" in d['task_type'] and \ os.path.exists(os.path.join(path, "relax2")): try: run_stats = {} for i in [1,2]: o_path = os.path.join(path,"relax"+str(i),"OUTCAR") o_path = o_path if os.path.exists(o_path) else o_path+".gz" outcar = Outcar(o_path) d["calculations"][i-1]["output"]["outcar"] = outcar.as_dict() run_stats["relax"+str(i)] = outcar.run_stats except: logger.error("Bad OUTCAR for {}.".format(path)) try: overall_run_stats = {} for key in ["Total CPU time used (sec)", "User time (sec)", "System time (sec)", "Elapsed time (sec)"]: overall_run_stats[key] = sum([v[key] for v in run_stats.values()]) run_stats["overall"] = overall_run_stats except: logger.error("Bad run stats for {}.".format(path)) d["run_stats"] = run_stats # add is_compatible mpc = MaterialsProjectCompatibility("Advanced") try: func = d["pseudo_potential"]["functional"] labels = d["pseudo_potential"]["labels"] symbols = ["{} {}".format(func, label) for label in labels] parameters = {"run_type": d["run_type"], "is_hubbard": d["is_hubbard"], "hubbards": d["hubbards"], "potcar_symbols": symbols} entry = ComputedEntry(Composition(d["unit_cell_formula"]), 0.0, 0.0, parameters=parameters, entry_id=d["task_id"]) d['is_compatible'] = bool(mpc.process_entry(entry)) except: traceback.print_exc() print 'ERROR in getting compatibility' d['is_compatible'] = None #task_type dependent processing if 'static' in d['task_type']: launch_doc = launches_coll.find_one({"fw_id": d['fw_id'], "launch_dir": {"$regex": d["dir_name"]}}, {"action.stored_data": 1}) for i in ["conventional_standard_structure", "symmetry_operations", "symmetry_dataset", "refined_structure"]: try: d['stored_data'][i] = launch_doc['action']['stored_data'][i] except: pass #parse band structure if necessary if ('band structure' in d['task_type'] or "Uniform" in d['task_type'])\ and d['state'] == 'successful': launch_doc = launches_coll.find_one({"fw_id": d['fw_id'], "launch_dir": {"$regex": d["dir_name"]}}, {"action.stored_data": 1}) vasp_run = Vasprun(zpath(os.path.join(path, "vasprun.xml")), parse_projected_eigen=False) if 'band structure' in d['task_type']: def string_to_numlist(stringlist): g=re.search('([0-9\-\.eE]+)\s+([0-9\-\.eE]+)\s+([0-9\-\.eE]+)', stringlist) return [float(g.group(i)) for i in range(1,4)] for i in ["kpath_name", "kpath"]: d['stored_data'][i] = launch_doc['action']['stored_data'][i] kpoints_doc = d['stored_data']['kpath']['kpoints'] for i in kpoints_doc: kpoints_doc[i]=string_to_numlist(kpoints_doc[i]) bs=vasp_run.get_band_structure(efermi=d['calculations'][0]['output']['outcar']['efermi'], line_mode=True) else: bs=vasp_run.get_band_structure(efermi=d['calculations'][0]['output']['outcar']['efermi'], line_mode=False) bs_json = json.dumps(bs.as_dict(), cls=MontyEncoder) fs = gridfs.GridFS(db, "band_structure_fs") bs_id = fs.put(bs_json) d['calculations'][0]["band_structure_fs_id"] = bs_id # also override band gap in task doc gap = bs.get_band_gap() vbm = bs.get_vbm() cbm = bs.get_cbm() update_doc = {'bandgap': gap['energy'], 'vbm': vbm['energy'], 'cbm': cbm['energy'], 'is_gap_direct': gap['direct']} d['analysis'].update(update_doc) d['calculations'][0]['output'].update(update_doc) coll.update_one({"dir_name": d["dir_name"]}, {'$set': d}, upsert=True) return d["task_id"], d else: logger.info("Skipping duplicate {}".format(d["dir_name"])) return result["task_id"], result else: d["task_id"] = 0 logger.info("Simulated insert into database for {} with task_id {}" .format(d["dir_name"], d["task_id"])) return 0, d