def test_as_dict(self): filepath = os.path.join(test_dir, 'vasprun.xml') vasprun = Vasprun(filepath) #Test that as_dict() is json-serializable self.assertIsNotNone(json.dumps(vasprun.as_dict())) self.assertEqual( vasprun.as_dict()["input"]["potcar_type"], ['PAW_PBE', 'PAW_PBE', 'PAW_PBE', 'PAW_PBE', 'PAW_PBE'])
def get_fermi_energy(self, directory): """Returns the Fermi energy from a directory""" abspath = '%s/%s/' % (self.directory, directory) if ('vasprun.xml' in os.listdir(abspath)): return Vasprun('%s/vasprun.xml' % abspath).efermi elif ('OUTCAR' in os.listdir(abspath)): return Outcar('%s/OUTCAR' % abspath).efermi
def from_previous_vasp_run(previous_vasp_dir, output_dir='.', user_incar_settings=None, make_dir_if_not_present=True): """ Generate a set of Vasp input files for static calculations from a directory of previous Vasp run. Args: previous_vasp_dir: The directory contains the outputs(vasprun.xml and OUTCAR) of previous vasp run. output_dir: The directory to write the VASP input files for the static calculations. Default to write in the current directory. make_dir_if_not_present: Set to True if you want the directory (and the whole path) to be created if it is not present. """ try: vasp_run = Vasprun(os.path.join(previous_vasp_dir, "vasprun.xml"), parse_dos=False, parse_eigen=None) outcar = Outcar(os.path.join(previous_vasp_dir, "OUTCAR")) except: traceback.format_exc() raise RuntimeError("Can't get valid results from previous run") structure = MPStaticVaspInputSet.get_structure( vasp_run, outcar) mpsvip = MPStaticVaspInputSet( user_incar_settings=user_incar_settings) mpsvip.write_input(structure, output_dir, make_dir_if_not_present)
def run_task(self, fw_spec): try: vasp_run = Vasprun("vasprun.xml", parse_dos=False, parse_eigen=False) outcar = Outcar(os.path.join(os.getcwd(), "OUTCAR")) except Exception as e: raise RuntimeError("Can't get valid results from relaxed run: " + str(e)) user_incar_settings = MPNonSCFVaspInputSet.get_incar_settings( vasp_run, outcar) user_incar_settings.update({"NPAR": 2}) structure = MPNonSCFVaspInputSet.get_structure(vasp_run, outcar, initial_structure=True) if self.line: mpnscfvip = MPNonSCFVaspInputSet(user_incar_settings, mode="Line") for k, v in mpnscfvip.get_all_vasp_input( structure, generate_potcar=True).items(): v.write_file(os.path.join(os.getcwd(), k)) kpath = HighSymmKpath(structure) else: mpnscfvip = MPNonSCFVaspInputSet(user_incar_settings, mode="Uniform") for k, v in mpnscfvip.get_all_vasp_input( structure, generate_potcar=True).items(): v.write_file(os.path.join(os.getcwd(), k)) if self.line: return FWAction(stored_data={"kpath": kpath.kpath, "kpath_name": kpath.name}) else: return FWAction()
def get_structure(self, directory): """Returns the final structure from an optimization""" abspath = '%s/%s/' % (self.directory, directory) if ('vasprun.xml' in os.listdir(abspath)): return Vasprun('%s/vasprun.xml' % abspath).final_structure elif ('CONTCAR' in os.listdir(abspath)): return pmg.read_structure('%s/CONTCAR' % abspath)
def get_total_energy(self, directory): """Returns the total energy from a directory""" abspath = '%s/%s/' % (self.directory, directory) if ('vasprun.xml' in os.listdir(abspath)): # Modified from the PyMatGen Vasprun.final_energy() function to return E_0 return Vasprun( '%s/vasprun.xml' % abspath).ionic_steps[-1]["electronic_steps"][-1]["e_0_energy"]
def test_sc_step_overflow(self): filepath = os.path.join(test_dir, 'vasprun.xml.sc_overflow') with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") vasprun = Vasprun(filepath) self.assertEqual(len(w), 3) estep = vasprun.ionic_steps[0]['electronic_steps'][29] self.assertTrue(np.isnan(estep['e_wo_entrp']))
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: data = Vasprun(run, ionic_step_skip=1) parameters = data.__getattribute__('incar').to_dict bandstructure = data.get_band_structure(kpoints) results = {'ecuteps': parameters['ENCUTGW'], 'nbands': parameters['NBANDS'], 'nomega': parameters['NOMEGA'], 'gwgap': bandstructure.get_band_gap()['energy']} except (IOError, OSError, IndexError, KeyError): pass return results
def test_get_ir_kpoints(self): v = Vasprun(os.path.join(test_dir, 'vasprun_Si_bands.xml')) finder = SymmetryFinder(v.final_structure) actual_kpts = v.actual_kpoints mapping = finder.get_ir_kpoints_mapping(actual_kpts) irr_kpts = finder.get_ir_kpoints(actual_kpts) self.assertLess(len(irr_kpts), len(actual_kpts)) self.assertEqual(len(irr_kpts), len(set(mapping)))
def from_files(cls, filepaths, specie, step_skip=10, min_obs=30, weighted=True, ncores=None): """ Convenient constructor that takes in a list of vasprun.xml paths to perform diffusion analysis. Args: filepaths ([str]): List of paths to vasprun.xml files of runs. ( must be ordered in sequence of MD simulation). For example, you may have done sequential VASP runs and they are in run1, run2, run3, etc. You should then pass in ["run1/vasprun.xml", "run2/vasprun.xml", ...]. specie (Element/Specie): Specie to calculate diffusivity for as a String. E.g., "Li". step_skip (int): Sampling frequency of the displacements ( time_step is multiplied by this number to get the real time between measurements) min_obs (int): Minimum number of observations to have before including in the MSD vs dt calculation. E.g. If a structure has 10 diffusing atoms, and min_obs = 30, the MSD vs dt will be calculated up to dt = total_run_time / 3, so that each diffusing atom is measured at least 3 uncorrelated times. weighted (bool): Uses a weighted least squares to fit the MSD vs dt. Weights are proportional to 1/dt, since the number of observations are also proportional to 1/dt (and hence the variance is proportional to dt) ncores (int): Numbers of cores to use for multiprocessing. Can speed up vasprun parsing considerably. Defaults to None, which means serial. It should be noted that if you want to use multiprocessing, the number of ionic steps in all vasprun .xml files should be a multiple of the ionic_step_skip. Otherwise, inconsistent results may arise. Serial mode has no such restrictions. """ if ncores is not None: import multiprocessing p = multiprocessing.Pool(ncores) vaspruns = p.map(_get_vasprun, [(p, step_skip) for p in filepaths]) else: vaspruns = [] offset = 0 for p in filepaths: v = Vasprun(p, ionic_step_offset=offset, ionic_step_skip=step_skip) vaspruns.append(v) # Recompute offset. offset = (-(v.nionic_steps - offset)) % step_skip return cls.from_vaspruns(vaspruns, min_obs=min_obs, weighted=weighted, specie=specie)
def assimilate(self, path): files = os.listdir(path) if "relax1" in files and "relax2" in files: filepath = glob.glob(os.path.join(path, "relax2", "vasprun.xml*"))[0] else: vasprun_files = glob.glob(os.path.join(path, "vasprun.xml*")) filepath = None if len(vasprun_files) == 1: filepath = vasprun_files[0] elif len(vasprun_files) > 1: """ This is a bit confusing, since there maybe be multi-steps. By default, assimilate will try to find a file simply named vasprun.xml, vasprun.xml.bz2, or vasprun.xml.gz. Failing which it will try to get a relax2 from an aflow style run if possible. Or else, a randomly chosen file containing vasprun.xml is chosen. """ for fname in vasprun_files: if os.path.basename(fname) in [ "vasprun.xml", "vasprun.xml.gz", "vasprun.xml.bz2" ]: filepath = fname break if re.search("relax2", fname): filepath = fname break filepath = fname try: vasprun = Vasprun(filepath) except Exception as ex: logger.debug("error in {}: {}".format(filepath, ex)) return None param = {} for p in self._parameters: param[p] = getattr(vasprun, p) param["history"] = _get_transformation_history(path) data = {} for d in self._data: data[d] = getattr(vasprun, d) if self._inc_structure: entry = ComputedStructureEntry(vasprun.final_structure, vasprun.final_energy, parameters=param, data=data) else: entry = ComputedEntry(vasprun.final_structure.composition, vasprun.final_energy, parameters=param, data=data) return entry
def test_get_band_structure(self): filepath = os.path.join(test_dir, 'vasprun_Si_bands.xml') vasprun = Vasprun(filepath) 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], "wrong vbm kpoint index") 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 assimilate(self, path): files = os.listdir(path) if "relax1" in files and "relax2" in files: filepath = glob.glob(os.path.join(path, "relax2", "vasprun.xml*"))[0] else: vasprun_files = glob.glob(os.path.join(path, "vasprun.xml*")) filepath = None if len(vasprun_files) == 1: filepath = vasprun_files[0] elif len(vasprun_files) > 1: """ This is a bit confusing, since there maybe be multi-steps. By default, assimilate will try to find a file simply named vasprun.xml, vasprun.xml.bz2, or vasprun.xml.gz. Failing which it will try to get a relax2 from an aflow style run if possible. Or else, a randomly chosen file containing vasprun.xml is chosen. """ for fname in vasprun_files: if os.path.basename(fname) in ["vasprun.xml", "vasprun.xml.gz", "vasprun.xml.bz2"]: filepath = fname break if re.search("relax2", fname): filepath = fname break filepath = fname try: vasprun = Vasprun(filepath) except Exception as ex: logger.debug("error in {}: {}".format(filepath, ex)) return None entry = vasprun.get_computed_entry(self._inc_structure, parameters=self._parameters, data=self._data) entry.parameters["history"] = _get_transformation_history(path) return entry
def run_task(self, fw_spec): user_incar_settings = {"NPAR": 2} MPStaticVaspInputSet.from_previous_vasp_run(os.getcwd(), user_incar_settings=user_incar_settings) structure = MPStaticVaspInputSet.get_structure(Vasprun("vasprun.xml"), Outcar("OUTCAR"), initial_structure=False, additional_info=True) return FWAction(stored_data={'refined_structure': structure[1][0].to_dict, 'conventional_standard_structure': structure[1][1].to_dict, 'symmetry_dataset': structure[1][2], 'symmetry_operations': [x.to_dict for x in structure[1][3]]})
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 test_update_potcar(self): filepath = os.path.join(test_dir, 'vasprun.xml') potcar_path = os.path.join(test_dir, 'POTCAR.LiFePO4.gz') potcar_path2 = os.path.join(test_dir, 'POTCAR2.LiFePO4.gz') vasprun = Vasprun(filepath, parse_potcar_file=False) self.assertEqual(vasprun.potcar_spec, [{"titel": "PAW_PBE Li 17Jan2003", "hash": None}, {"titel": "PAW_PBE Fe 06Sep2000", "hash": None}, {"titel": "PAW_PBE Fe 06Sep2000", "hash": None}, {"titel": "PAW_PBE P 17Jan2003", "hash": None}, {"titel": "PAW_PBE O 08Apr2002", "hash": None}]) vasprun.update_potcar_spec(potcar_path) self.assertEqual(vasprun.potcar_spec, [{"titel": "PAW_PBE Li 17Jan2003", "hash": "65e83282d1707ec078c1012afbd05be8"}, {"titel": "PAW_PBE Fe 06Sep2000", "hash": "9530da8244e4dac17580869b4adab115"}, {"titel": "PAW_PBE Fe 06Sep2000", "hash": "9530da8244e4dac17580869b4adab115"}, {"titel": "PAW_PBE P 17Jan2003", "hash": "7dc3393307131ae67785a0cdacb61d5f"}, {"titel": "PAW_PBE O 08Apr2002", "hash": "7a25bc5b9a5393f46600a4939d357982"}]) vasprun2 = Vasprun(filepath, parse_potcar_file=False) self.assertRaises(ValueError, vasprun2.update_potcar_spec, potcar_path2) vasprun = Vasprun(filepath, parse_potcar_file=potcar_path) self.assertEqual(vasprun.potcar_spec, [{"titel": "PAW_PBE Li 17Jan2003", "hash": "65e83282d1707ec078c1012afbd05be8"}, {"titel": "PAW_PBE Fe 06Sep2000", "hash": "9530da8244e4dac17580869b4adab115"}, {"titel": "PAW_PBE Fe 06Sep2000", "hash": "9530da8244e4dac17580869b4adab115"}, {"titel": "PAW_PBE P 17Jan2003", "hash": "7dc3393307131ae67785a0cdacb61d5f"}, {"titel": "PAW_PBE O 08Apr2002", "hash": "7a25bc5b9a5393f46600a4939d357982"}]) self.assertRaises(ValueError, Vasprun, filepath, parse_potcar_file=potcar_path2)
def get_fermi_energy(self, directory): """Returns the Fermi energy from a directory""" abspath = '%s/%s/' % (self.recdir, directory) if ('OUTCAR' in os.listdir(abspath)): grepfermi = fileutil.grepme("%s/OUTCAR" % abspath, "E-fermi") lastfermi = grepfermi[-1] fermi = float(lastfermi.split()[2]) print "TTM DEBUG LAST FERMI: ", fermi return fermi #print "TTM DEBUG: OUTCAR efermi: ", Outcar('%s/OUTCAR' % abspath).efermi #return Outcar('%s/OUTCAR' % abspath).efermi elif ('vasprun.xml' in os.listdir(abspath)): return Vasprun('%s/vasprun.xml' % abspath).efermi
def add_data_entry(self, path): """ parse the data found in path and add it to data """ try: xml = Vasprun(os.path.join(path, "vasprun.xml")) out = Outcar(os.path.join(path, "OUTCAR")) if xml.converged or True: entry = { 'system': path.split('/')[1].split('_par')[0], "NPAR": xml.parameters.get('NPAR'), 'nband': xml.parameters.get('NBANDS'), 'ncpus': int(out.run_stats['cores']), "final_energy": xml.final_energy, "vasp_version": xml.vasp_version, "generator": xml.generator, "generator_hash": hash(frozenset(xml.generator)), "run_stats": out.run_stats } entry_hash = hash((entry['ncpus'], entry['NPAR'], entry['generator_hash'], entry['system'])) #print(entry) self.data.update({str(entry_hash): entry}) print(entry['ncpus'], entry['NPAR'], entry['generator_hash'], entry['system']) except (ParseError, ValueError, IOError): try: out = Outcar(os.path.join(path, "OUTCAR")) inc = Incar(os.path.join(path, "INCAR")) entry = { "NPAR": inc.as_dict()['NPAR'], "nband": inc.as_dict()['nband'], 'ncpus': int(out.run_stats['cores']), "final_energy": -1, "vasp_version": 'v', "generator": {}, "generator_hash": hash(' '), "run_stats": out.run_stats } entry_hash = hash((entry['ncpus'], entry['NPAR'], entry['generator_hash'], entry['system'])) log(entry) self.data.update({str(entry_hash): entry}) print(entry['ncpus'], entry['NPAR'], entry['generator_hash'], entry['system']) except (ParseError, ValueError, IOError): print('parsing error') pass
def from_previous_vasp_run(previous_vasp_dir, output_dir='.', mode="Uniform", user_incar_settings=None, copy_chgcar=True, make_dir_if_not_present=True): """ Generate a set of Vasp input files for NonSCF calculations from a directory of previous static Vasp run. Args: previous_vasp_dir: The directory contains the outputs(vasprun.xml and OUTCAR) of previous vasp run. output_dir: The directory to write the VASP input files for the NonSCF calculations. Default to write in the current directory. copy_chgcar: Default to copy CHGCAR from SC run make_dir_if_not_present: Set to True if you want the directory (and the whole path) to be created if it is not present. """ try: vasp_run = Vasprun(os.path.join(previous_vasp_dir, "vasprun.xml"), parse_dos=False, parse_eigen=None) outcar = Outcar(os.path.join(previous_vasp_dir, "OUTCAR")) except: traceback.format_exc() raise RuntimeError("Can't get valid results from previous run") #Get a Magmom-decorated structure structure = MPNonSCFVaspInputSet.get_structure(vasp_run, outcar) user_incar_settings = MPNonSCFVaspInputSet.get_incar_settings( vasp_run, outcar) mpnscfvip = MPNonSCFVaspInputSet(user_incar_settings, mode) mpnscfvip.write_input(structure, output_dir, make_dir_if_not_present) if copy_chgcar: try: shutil.copyfile(os.path.join(previous_vasp_dir, "CHGCAR"), os.path.join(output_dir, "CHGCAR")) except Exception as e: traceback.format_exc() raise RuntimeError("Can't copy CHGCAR from SC run" + '\n' + str(e))
import pymatgen.io.vaspio.vasp_output from pymatgen.core import structure from pymatgen.io.vaspio.vasp_input import Kpoints from pymatgen.io.vaspio_set import DictVaspInputSet from pymatgen.matproj.rest import MPRester from pymatgen.io.vaspio.vasp_output import Vasprun from abipy.electrons.scissors import ScissorsBuilder import abipy.data as abidata from abipy.abilab import abiopen, ElectronBandsPlotter MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) try: data = Vasprun('vasprun.xml', ionic_step_skip=1) print(data.converged) bandstructure = data.get_band_structure('../IBZKPT') print('gap: ', bandstructure.get_band_gap()['energy'], ' direct : ', bandstructure.get_band_gap()['direct']) print('cbm: ', bandstructure.get_cbm()['energy'], data.actual_kpoints[bandstructure.get_cbm()['kpoint_index'][0]]) print('vbm: ', bandstructure.get_vbm()['energy'], data.actual_kpoints[bandstructure.get_vbm()['kpoint_index'][0]]) print( 'gap: ', bandstructure.get_cbm()['energy'] - bandstructure.get_vbm()['energy']) print('direct gap: ', bandstructure.get_direct_band_gap())
__author__ = 'Qimin' from pymatgen.io.vaspio.vasp_output import Vasprun from pymatgen.electronic_structure.plotter import BSPlotter import os import pickle vasp_dir = os.path.dirname(os.path.abspath(__file__)) vasp_run = Vasprun(os.path.join(vasp_dir,"vasprun.xml")) bs = vasp_run.get_band_structure(line_mode=True) print bs.get_vbm()["energy"] print bs.get_cbm()["energy"] print bs.get_band_gap()["energy"] # The above doesn't work on Vulcan or nano cluster due to a bug in virtualenv. Please use the following line to get band structure data from the cluster. pickle.dump(bs, open("band_structure.dat", "w")) # And then load the pickle object on your local machine. #bs = pickle.load(open("band_structure.dat", "r")) #print BSPlotter(bs).bs_plot_data(zero_to_efermi=True) #BSPlotter(bs).save_plot(filename="1.pdf",img_format="pdf",ylim=None,zero_to_efermi=True,smooth=True)
""" Example of DOS modulation Apply moduleDOS module """ from __future__ import division, print_function import moduleDOS from pymatgen.io.vaspio.vasp_output import Vasprun __author__ = "Germain Salvato-Vallverdu" __email__ = "*****@*****.**" __licence__ = "GPL" __date__ = "Nov. 2014" # options: xmlfile = "dos.xml" tofile = False # print cross sections: print("Cross sections :") run = Vasprun(xmlfile, parse_dos=False, parse_eigen=False) for el in run.initial_structure.composition.elements: print(moduleDOS.CrossSec.from_string(el.symbol)) # molate DOS: moduleDOS.modulate(xmlfile, tofile)
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_and_modify( query={"_id": "taskid"}, update={"$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({"dir_name": d["dir_name"]}, 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
def from_files(cls, filepaths, specie, step_skip=10, smoothed="max", min_obs=30, avg_nsteps=1000, ncores=None, initial_disp=None, initial_structure=None): """ Convenient constructor that takes in a list of vasprun.xml paths to perform diffusion analysis. Args: filepaths ([str]): List of paths to vasprun.xml files of runs. ( must be ordered in sequence of MD simulation). For example, you may have done sequential VASP runs and they are in run1, run2, run3, etc. You should then pass in ["run1/vasprun.xml", "run2/vasprun.xml", ...]. specie (Element/Specie): Specie to calculate diffusivity for as a String. E.g., "Li". step_skip (int): Sampling frequency of the displacements ( time_step is multiplied by this number to get the real time between measurements) smoothed (str): Whether to smooth the MSD, and what mode to smooth. Supported modes are: i. "max", which tries to use the maximum # of data points for each time origin, subject to a minimum # of observations given by min_obs, and then weights the observations based on the variance accordingly. This is the default. ii. "constant", in which each timestep is averaged over the same number of observations given by min_obs. iii. None / False / any other false-like quantity. No smoothing. min_obs (int): Used with smoothed="max". Minimum number of observations to have before including in the MSD vs dt calculation. E.g. If a structure has 10 diffusing atoms, and min_obs = 30, the MSD vs dt will be calculated up to dt = total_run_time / 3, so that each diffusing atom is measured at least 3 uncorrelated times. Only applies in smoothed="max". avg_nsteps (int): Used with smoothed="constant". Determines the number of time steps to average over to get the msd for each timestep. Default of 1000 is usually pretty good. ncores (int): Numbers of cores to use for multiprocessing. Can speed up vasprun parsing considerably. Defaults to None, which means serial. It should be noted that if you want to use multiprocessing, the number of ionic steps in all vasprun .xml files should be a multiple of the ionic_step_skip. Otherwise, inconsistent results may arise. Serial mode has no such restrictions. initial_disp (np.ndarray): Sometimes, you need to iteratively compute estimates of the diffusivity. This supplies an initial displacement that will be added on to the initial displacements. Note that this makes sense only when smoothed=False. initial_structure (Structure): Like initial_disp, this is used for iterative computations of estimates of the diffusivity. You typically need to supply both variables. This stipulates the initial strcture from which the current set of displacements are computed. """ if ncores is not None and len(filepaths) > 1: import multiprocessing p = multiprocessing.Pool(ncores) vaspruns = p.map(_get_vasprun, [(fp, step_skip) for fp in filepaths]) p.close() p.join() else: vaspruns = [] offset = 0 for p in filepaths: v = Vasprun(p, ionic_step_offset=offset, ionic_step_skip=step_skip) vaspruns.append(v) # Recompute offset. offset = (-(v.nionic_steps - offset)) % step_skip return cls.from_vaspruns(vaspruns, min_obs=min_obs, smoothed=smoothed, specie=specie, initial_disp=initial_disp, initial_structure=initial_structure, avg_nsteps=avg_nsteps)
def main(): """ Main routine """ parser = argparse.ArgumentParser(description='Calculate the band structure of a vasp calculation.') parser.add_argument('-d', '--density', nargs='?', default=10, type=int, help='k-point density of the bands (default: 10)') parser.add_argument('-s', '--sigma', nargs='?', default=0.04, type=float, help='SIGMA value in eV (default: 0.04)') parser.add_argument('-l', '--linemode', nargs='?', default=None, type=str, help='linemode file') parser.add_argument('-v', '--vasp', nargs='?', default='vasp', type=str, help='vasp executable') args = parser.parse_args() line_density = args.density line_file = args.linemode # Check that required files exist _check('vasprun.xml') _check('INCAR') _check('POSCAR') _check('POTCAR') _check('CHGCAR') # Get IBZ from vasprun vasprun = Vasprun('vasprun.xml') ibz = HighSymmKpath(vasprun.final_structure) # Create a temp directory print('Create temporary directory ... ', end='') tempdir = mkdtemp() print(tempdir) # Edit the inputs print('Saving new inputs in temporary directory ... ') incar = Incar.from_file('INCAR') print('Making the following changes to the INCAR:') print(' ICHARG = 11') print(' ISMEAR = 0') print(' SIGMA = %f' % args.sigma) incar['ICHARG'] = 11 # Constant density incar['ISMEAR'] = 0 # Gaussian Smearing incar['SIGMA'] = args.sigma # Smearing temperature incar.write_file(os.path.join(tempdir, 'INCAR')) # Generate line-mode kpoint file if line_file is None: print('Creating a new KPOINTS file:') kpoints = _automatic_kpoints(line_density, ibz) kpoints.write_file(os.path.join(tempdir, 'KPOINTS')) print('### BEGIN KPOINTS') print(kpoints) print('### END KPOINTS') else: cp(line_file, os.path.join(tempdir, 'KPOINTS')) # Copy other files (May take some time...) print('Copying POSCAR, POTCAR and CHGCAR to the temporary directory.') cp('POSCAR', os.path.join(tempdir, 'POSCAR')) cp('POTCAR', os.path.join(tempdir, 'POTCAR')) cp('CHGCAR', os.path.join(tempdir, 'CHGCAR')) # cd to temp directory and run vasp path = os.getcwd() os.chdir(tempdir) print('Running VASP in the temporary directory ...') try: check_call(args.vasp) except CalledProcessError: print('There was an error running VASP') _clean_exit(path, tempdir) # Read output vasprun = Vasprun('vasprun.xml') ibz = HighSymmKpath(vasprun.final_structure) _, _ = ibz.get_kpoints(line_density) bands = vasprun.get_band_structure() print('Success! Efermi = %f' % bands.efermi) # Backup vasprun.xml only print('Making a gzip backup of vasprun.xml called bands_vasprun.xml.gz') zfile = os.path.join(path, 'bands_vasprun.xml.gz') try: with gzip.open(zfile, 'wb') as gz, open('vasprun.xml', 'rb') as vr: gz.writelines(vr) except (OSError, IOError): print('There was an error with gzip') _clean_exit(path, tempdir) # Return to original path os.chdir(path) # Write band structure # There may be multiple bands due to spin or noncollinear. for key, item in bands.bands.items(): print('Preparing bands_%s.csv' % key) kpts = [] # Get list of kpoints for kpt in bands.kpoints: kpts.append(kpt.cart_coords) # Subtract fermi energy print('Shifting energies so Efermi = 0.') band = numpy.array(item) - bands.efermi # Prepend kpoint vector as label out = numpy.hstack([kpts, band.T]) final = [] lastrow = float('inf') * numpy.ones(3) for row in out: if numpy.linalg.norm(row[:3] - lastrow) > 1.e-12: final.append(row) lastrow = row[:3] # Write bands to csv file. print('Writing bands_%s.csv to disk' % key) with open('bands_%s.csv' % key, 'w+') as f: numpy.savetxt(f, numpy.array(final), delimiter=',', header=' kptx, kpty, kptz, band1, band2, ... ') # Delete temporary directory _clean_exit(path, tempdir, 0)
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=list(zip(r, g, b, a)), linewidth=2) ax.add_collection(lc) 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)
from pymatgen.core import structure from pymatgen.io.vaspio.vasp_input import Kpoints from pymatgen.io.vaspio_set import DictVaspInputSet from pymatgen.matproj.rest import MPRester from pymatgen.io.vaspio.vasp_output import Vasprun from abipy.electrons.scissors import ScissorsBuilder import abipy.data as abidata from abipy.abilab import abiopen, ElectronBandsPlotter MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) try: data = Vasprun('vasprun.xml', ionic_step_skip=1) print(data.converged) bandstructure = data.get_band_structure('../IBZKPT') print('gap: ', bandstructure.get_band_gap()['energy'], ' direct : ', bandstructure.get_band_gap()['direct']) print('cbm: ', bandstructure.get_cbm()['energy'], data.actual_kpoints[bandstructure.get_cbm()['kpoint_index'][0]]) print('vbm: ', bandstructure.get_vbm()['energy'], data.actual_kpoints[bandstructure.get_vbm()['kpoint_index'][0]]) print('gap: ', bandstructure.get_cbm()['energy'] - bandstructure.get_vbm()['energy']) print('direct gap: ', bandstructure.get_direct_band_gap()) except (IOError, OSError): print('no vasp output found') try: # Get the quasiparticle results from the SIGRES.nc database. sigma_file = abiopen(abidata.ref_file("tgw1_9o_DS4_SIGRES.nc")) #sigma_file.plot_qps_vs_e0() qplist_spin = sigma_file.qplist_spin
__maintainer__ = "Shyue Ping Ong" __email__ = "*****@*****.**" __date__ = "Mar 18, 2012" import unittest import os from pymatgen.io.vaspio.vasp_output import Vasprun from pymatgen.entries.computed_entries import ComputedEntry, \ ComputedStructureEntry test_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", 'test_files') filepath = os.path.join(test_dir, 'vasprun.xml') vasprun = Vasprun(filepath) class ComputedEntryTest(unittest.TestCase): def setUp(self): self.entry = ComputedEntry(vasprun.final_structure.composition, vasprun.final_energy, parameters=vasprun.incar) self.entry2 = ComputedEntry({"Fe": 2, "O": 3}, 2.3) self.entry3 = ComputedEntry("Fe2O3", 2.3) self.entry4 = ComputedEntry("Fe2O3", 2.3, entry_id=1) def test_energy(self): self.assertAlmostEqual(self.entry.energy, -269.38319884) self.entry.correction = 1.0 self.assertAlmostEqual(self.entry.energy, -268.38319884)
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, self.parse_dos, self.additional_fields) 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"]) 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_and_modify( query={"_id": "taskid"}, update={"$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) #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]: outcar = Outcar(os.path.join(path,"relax"+str(i),"OUTCAR")) d["calculations"][i-1]["output"]["outcar"] = outcar.to_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 #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(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.to_dict) fs = gridfs.GridFS(db, "band_structure_fs") bs_id = fs.put(bs_json) d['calculations'][0]["band_structure_fs_id"] = bs_id coll.update({"dir_name": d["dir_name"]}, 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
path = HighSymmKpath(mg.read_structure("./POSCAR")).kpath["path"] labels = list() for p in path: if len(labels) != 0: labels[-1] = r"$%s,%s$" % (labels[-1].strip("$"), p[0]) else: labels.append(r"$%s$" % p[0]) for kp in p[1:]: labels.append(r"$%s$" % kp) # density of state dosrun = Vasprun("../../DOS/Cu/vasprun.xml") spd_dos = dosrun.complete_dos.get_spd_dos() # bands run = Vasprun("vasprun.xml", 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 State gs = GridSpec(1, 2, width_ratios=[2,1])
def _get_vasprun(args): """ Internal method to support multiprocessing. """ return Vasprun(args[0], ionic_step_skip=args[1])
def from_previous_vasp_run(previous_vasp_dir, output_dir='.', user_incar_settings=None, copy_chgcar=True, make_dir_if_not_present=True, kpoints_density=1000): """ Generate a set of Vasp input files for NonSCF calculations from a directory of previous static Vasp run. Args: previous_vasp_dir (str): The directory contains the outputs( vasprun.xml and OUTCAR) of previous vasp run. output_dir (str): The directory to write the VASP input files for the NonSCF calculations. Default to write in the current directory. user_incar_settings (dict): A dict specify customized settings for INCAR. copy_chgcar (bool): Default to copy CHGCAR from SC run make_dir_if_not_present (bool): Set to True if you want the directory (and the whole path) to be created if it is not present. kpoints_density (int): kpoints density for the reciprocal cell of structure. Might need to increase the default value when calculating metallic materials. kpoints_line_density (int): kpoints density to use in line-mode. Might need to increase the default value when calculating metallic materials. """ user_incar_settings = user_incar_settings or {} try: vasp_run = Vasprun(os.path.join(previous_vasp_dir, "vasprun.xml"), parse_dos=False, parse_eigen=None) outcar = Outcar(os.path.join(previous_vasp_dir, "OUTCAR")) previous_incar = vasp_run.incar except: traceback.print_exc() raise RuntimeError("Can't get valid results from previous run. prev dir: {}".format(previous_vasp_dir)) #Get a Magmom-decorated structure structure = TetrahedronDosSet.get_structure(vasp_run, outcar, initial_structure=True) nscf_incar_settings = TetrahedronDosSet.get_incar_settings(vasp_run, outcar) mpnscfvip = TetrahedronDosSet(nscf_incar_settings, kpoints_density=kpoints_density) mpnscfvip.write_input(structure, output_dir, make_dir_if_not_present) if copy_chgcar: try: shutil.copyfile(os.path.join(previous_vasp_dir, "CHGCAR"), os.path.join(output_dir, "CHGCAR")) except Exception as e: traceback.print_exc() raise RuntimeError("Can't copy CHGCAR from SC run" + '\n' + str(e)) #Overwrite necessary INCAR parameters from previous runs # this is already done in the __init__; is it necessary here? previous_incar.update(nscf_incar_settings) previous_incar.update(user_incar_settings) # MAKE EXTRA DUPER SURE THESE PARAMETERS ARE NOT OVERWRITTEN previous_incar.update({"IBRION": -1, "ISMEAR": -5, "LCHARG": False, "LORBIT": 11, "LWAVE": False, "NSW": 0, "ISYM": 0, "ICHARG": 11}) previous_incar.pop("MAGMOM", None) previous_incar.pop('SIGMA',None) previous_incar.write_file(os.path.join(output_dir, "INCAR")) # Perform checking on INCAR parameters if any([previous_incar.get("NSW", 0) != 0, previous_incar["IBRION"] != -1, previous_incar["ICHARG"] != 11, any([sum(previous_incar["LDAUU"]) <= 0, previous_incar["LMAXMIX"] < 4]) if previous_incar.get("LDAU") else False]): raise ValueError("Incompatible INCAR parameters!")
from pymatgen.io.vaspio.vasp_output import Outcar, Vasprun from pymatgen.electronic_structure import bandstructure import os vasp_dir = os.path.dirname(os.path.abspath(__file__)) vasp_run = Vasprun(os.path.join(vasp_dir,"vasprun.xml")) bs = vasp_run.get_band_structure(kpoints_filename=None, efermi=None,line_mode=False) vbm = bs.get_vbm()['energy'] cbm = bs.get_cbm()['energy'] bandgap = bs.get_band_gap()['energy'] vbm_position = bs.get_vbm()['kpoint_index'] cbm_position = bs.get_cbm()['kpoint_index'] print vbm_position, cbm_position direct = False if vbm_position == cbm_position: direct = True print vbm, cbm, bandgap, direct
def test_to_dict(self): filepath = os.path.join(test_dir, 'vasprun.xml') vasprun = Vasprun(filepath) #Test that to_dict is json-serializable self.assertIsNotNone(json.dumps(vasprun.to_dict))
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_and_modify( query={"_id": "taskid"}, update={"$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.to_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.to_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 coll.update({"dir_name": d["dir_name"]}, 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
def test_properties(self): filepath = os.path.join(test_dir, 'vasprun.xml') vasprun = Vasprun(filepath) filepath2 = os.path.join(test_dir, 'lifepo4.xml') vasprun_ggau = Vasprun(filepath2, parse_projected_eigen=True) totalscsteps = sum([len(i['electronic_steps']) for i in vasprun.ionic_steps]) self.assertEquals(29, len(vasprun.ionic_steps)) self.assertEquals(308, totalscsteps, "Incorrect number of energies read from vasprun.xml") self.assertEquals([u'Li', u'Fe', u'Fe', u'Fe', u'Fe', u'P', u'P', u'P', u'P', u'O', u'O', u'O', u'O', u'O', u'O', u'O', u'O', u'O', u'O', u'O', u'O', u'O', u'O', u'O', u'O'], vasprun.atomic_symbols, "Incorrect symbols read from vasprun.xml") self.assertEquals(vasprun.final_structure.composition.reduced_formula, "LiFe4(PO4)4", "Wrong formula for final structure read.") self.assertIsNotNone(vasprun.incar, "Incar cannot be read") self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read") self.assertIsNotNone(vasprun.eigenvalues, "Eigenvalues cannot be read") self.assertAlmostEqual(vasprun.final_energy, -269.38319884, 7, "Wrong final energy") self.assertAlmostEqual(vasprun.tdos.get_gap(), 2.0589, 4, "Wrong gap from dos!") expectedans = (2.539, 4.0906, 1.5516, False) (gap, cbm, vbm, direct) = vasprun.eigenvalue_band_properties self.assertAlmostEqual(gap, expectedans[0]) self.assertAlmostEqual(cbm, expectedans[1]) self.assertAlmostEqual(vbm, expectedans[2]) self.assertEqual(direct, expectedans[3]) self.assertFalse(vasprun.is_hubbard) self.assertEqual(vasprun.potcar_symbols, [u'PAW_PBE Li 17Jan2003', u'PAW_PBE Fe 06Sep2000', u'PAW_PBE Fe 06Sep2000', u'PAW_PBE P 17Jan2003', u'PAW_PBE O 08Apr2002']) self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read") self.assertIsNotNone(vasprun.actual_kpoints, "Actual kpoints cannot be read") self.assertIsNotNone(vasprun.actual_kpoints_weights, "Actual kpoints weights cannot be read") for atomdoses in vasprun.pdos: for orbitaldos in atomdoses: self.assertIsNotNone(orbitaldos, "Partial Dos cannot be read") #test skipping ionic steps. vasprun_skip = Vasprun(filepath, 3) self.assertEqual(vasprun_skip.final_energy, vasprun.final_energy) self.assertEqual(len(vasprun_skip.ionic_steps), int(len(vasprun.ionic_steps) / 3) + 1) self.assertEqual(len(vasprun_skip.ionic_steps), len(vasprun_skip.structures) - 2) self.assertTrue(vasprun_ggau.is_hubbard) self.assertEqual(vasprun_ggau.hubbards["Fe"], 4.3) self.assertAlmostEqual(vasprun_ggau.projected_eigenvalues[(Spin.up, 0, 0, 96, Orbital.s)], 0.0032) d = vasprun_ggau.to_dict self.assertEqual(d["elements"], ["Fe", "Li", "O", "P"]) self.assertEqual(d["nelements"], 4) filepath = os.path.join(test_dir, 'vasprun.xml.unconverged') vasprun_unconverged = Vasprun(filepath) self.assertFalse(vasprun_unconverged.converged)
def from_previous_vasp_run(previous_vasp_dir, output_dir='.', user_incar_settings=None, make_dir_if_not_present=True): """ Generate a set of Vasp input files for static calculations from a directory of previous Vasp run. Args: previous_vasp_dir: The directory contains the outputs(vasprun.xml and OUTCAR) of previous vasp run. output_dir: The directory to write the VASP input files for the static calculations. Default to write in the current directory. make_dir_if_not_present: Set to True if you want the directory (and the whole path) to be created if it is not present. """ try: vasp_run = Vasprun(os.path.join(previous_vasp_dir, "vasprun.xml"), parse_dos=False, parse_eigen=None) outcar = Outcar(os.path.join(previous_vasp_dir, "OUTCAR")) previous_incar = vasp_run.incar previous_kpoints = vasp_run.kpoints previous_final_structure = vasp_run.final_structure except: traceback.format_exc() raise RuntimeError("Can't get valid results from previous run") structure = MPStaticVaspInputSet.get_structure(vasp_run, outcar) mpsvip = MPStaticVaspInputSet() mpsvip.write_input(structure, output_dir, make_dir_if_not_present) #new_incar = Incar.from_file(os.path.join(output_dir, "INCAR")) new_incar = mpsvip.get_incar(structure) # Use previous run INCAR and override necessary parameters previous_incar.update({ "IBRION": -1, "ISMEAR": -5, "LAECHG": True, "LCHARG": True, "LORBIT": 11, "LVHAR": True, "LWAVE": False, "NSW": 0, "ICHARG": 0 }) for incar_key in ["MAGMOM", "NUPDOWN"]: if new_incar.get(incar_key, None): previous_incar.update({incar_key: new_incar[incar_key]}) else: previous_incar.pop(incar_key, None) # use new LDAUU when possible b/c the Poscar might have changed # representation if previous_incar.get('LDAU'): u = previous_incar.get('LDAUU', []) j = previous_incar.get('LDAUJ', []) if sum([u[x] - j[x] for x, y in enumerate(u)]) > 0: for tag in ('LDAUU', 'LDAUL', 'LDAUJ'): previous_incar.update({tag: new_incar[tag]}) # Compare ediff between previous and staticinputset values, # choose the tighter ediff previous_incar.update( {"EDIFF": min(previous_incar.get("EDIFF", 1), new_incar["EDIFF"])}) # add user settings if user_incar_settings: previous_incar.update(user_incar_settings) previous_incar.write_file(os.path.join(output_dir, "INCAR")) # Prefer to use k-point scheme from previous run previous_kpoints_density = np.prod(previous_kpoints.kpts[0]) / \ previous_final_structure.lattice.reciprocal_lattice.volume new_kpoints_density = max(previous_kpoints_density, 90) new_kpoints = mpsvip.get_kpoints(structure, kpoints_density=new_kpoints_density) if previous_kpoints.style[0] != new_kpoints.style[0]: if previous_kpoints.style[0] == "M" and \ SymmetryFinder(structure, 0.01).get_lattice_type() != \ "hexagonal": k_div = (kp + 1 if kp % 2 == 1 else kp for kp in new_kpoints.kpts[0]) Kpoints.monkhorst_automatic(k_div). \ write_file(os.path.join(output_dir, "KPOINTS")) else: Kpoints.gamma_automatic(new_kpoints.kpts[0]). \ write_file(os.path.join(output_dir, "KPOINTS")) else: new_kpoints.write_file(os.path.join(output_dir, "KPOINTS"))
def test_properties(self): filepath = os.path.join(test_dir, 'vasprun.xml') vasprun = Vasprun(filepath) filepath2 = os.path.join(test_dir, 'lifepo4.xml') vasprun_ggau = Vasprun(filepath2, parse_projected_eigen=True) totalscsteps = sum( [len(i['electronic_steps']) for i in vasprun.ionic_steps]) self.assertEquals(29, len(vasprun.ionic_steps)) self.assertEquals(len(vasprun.structures), len(vasprun.ionic_steps)) self.assertEqual(vasprun.lattice, vasprun.lattice_rec.reciprocal_lattice) for i, step in enumerate(vasprun.ionic_steps): self.assertEqual(vasprun.structures[i], step["structure"]) self.assertTrue( all([ vasprun.structures[i] == vasprun.ionic_steps[i]["structure"] for i in xrange(len(vasprun.ionic_steps)) ])) self.assertEquals( 308, totalscsteps, "Incorrect number of energies read from vasprun.xml") self.assertEquals(['Li'] + 4 * ['Fe'] + 4 * ['P'] + 16 * ["O"], vasprun.atomic_symbols) self.assertEquals(vasprun.final_structure.composition.reduced_formula, "LiFe4(PO4)4") self.assertIsNotNone(vasprun.incar, "Incar cannot be read") self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read") self.assertIsNotNone(vasprun.eigenvalues, "Eigenvalues cannot be read") self.assertAlmostEqual(vasprun.final_energy, -269.38319884, 7) self.assertAlmostEqual(vasprun.tdos.get_gap(), 2.0589, 4) expectedans = (2.539, 4.0906, 1.5516, False) (gap, cbm, vbm, direct) = vasprun.eigenvalue_band_properties self.assertAlmostEqual(gap, expectedans[0]) self.assertAlmostEqual(cbm, expectedans[1]) self.assertAlmostEqual(vbm, expectedans[2]) self.assertEqual(direct, expectedans[3]) self.assertFalse(vasprun.is_hubbard) self.assertEqual(vasprun.potcar_symbols, [ u'PAW_PBE Li 17Jan2003', u'PAW_PBE Fe 06Sep2000', u'PAW_PBE Fe 06Sep2000', u'PAW_PBE P 17Jan2003', u'PAW_PBE O 08Apr2002' ]) self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read") self.assertIsNotNone(vasprun.actual_kpoints, "Actual kpoints cannot be read") self.assertIsNotNone(vasprun.actual_kpoints_weights, "Actual kpoints weights cannot be read") for atomdoses in vasprun.pdos: for orbitaldos in atomdoses: self.assertIsNotNone(orbitaldos, "Partial Dos cannot be read") #test skipping ionic steps. vasprun_skip = Vasprun(filepath, 3) self.assertEqual(vasprun_skip.nionic_steps, 29) self.assertEqual(len(vasprun_skip.ionic_steps), int(vasprun.nionic_steps / 3) + 1) self.assertEqual(len(vasprun_skip.ionic_steps), len(vasprun_skip.structures)) self.assertEqual(len(vasprun_skip.ionic_steps), int(vasprun.nionic_steps / 3) + 1) #Check that nionic_steps is preserved no matter what. self.assertEqual(vasprun_skip.nionic_steps, vasprun.nionic_steps) self.assertNotAlmostEqual(vasprun_skip.final_energy, vasprun.final_energy) #Test with ionic_step_offset vasprun_offset = Vasprun(filepath, 3, 6) self.assertEqual(len(vasprun_offset.ionic_steps), int(len(vasprun.ionic_steps) / 3) - 1) self.assertEqual(vasprun_offset.structures[0], vasprun_skip.structures[2]) self.assertTrue(vasprun_ggau.is_hubbard) self.assertEqual(vasprun_ggau.hubbards["Fe"], 4.3) self.assertAlmostEqual( vasprun_ggau.projected_eigenvalues[(Spin.up, 0, 0, 96, Orbital.s)], 0.0032) d = vasprun_ggau.to_dict self.assertEqual(d["elements"], ["Fe", "Li", "O", "P"]) self.assertEqual(d["nelements"], 4) filepath = os.path.join(test_dir, 'vasprun.xml.unconverged') vasprun_unconverged = Vasprun(filepath) self.assertFalse(vasprun_unconverged.converged) filepath = os.path.join(test_dir, 'vasprun.xml.dfpt') vasprun_dfpt = Vasprun(filepath) self.assertAlmostEqual(vasprun_dfpt.epsilon_static[0][0], 3.26105533) self.assertAlmostEqual(vasprun_dfpt.epsilon_static[0][1], -0.00459066) self.assertAlmostEqual(vasprun_dfpt.epsilon_static[2][2], 3.24330517) entry = vasprun_dfpt.get_computed_entry() entry = MaterialsProjectCompatibility().process_entry(entry) self.assertAlmostEqual(entry.uncorrected_energy + entry.correction, entry.energy) vasprun_uniform = Vasprun(os.path.join(test_dir, "vasprun.xml.uniform")) self.assertEqual(vasprun_uniform.kpoints.style, "Reciprocal")
def test_properties(self): filepath = os.path.join(test_dir, 'vasprun.xml.nonlm') vasprun = Vasprun(filepath, parse_potcar_file=False) orbs = list(vasprun.complete_dos.pdos[vasprun.final_structure[ 0]].keys()) self.assertIn("S", orbs) filepath = os.path.join(test_dir, 'vasprun.xml') vasprun = Vasprun(filepath, parse_potcar_file=False) #test pdos parsing pdos0 = vasprun.complete_dos.pdos[vasprun.final_structure[0]] self.assertAlmostEqual(pdos0[Orbital.s][1][16], 0.0026) self.assertAlmostEqual(pdos0[Orbital.pz][-1][16], 0.0012) self.assertEqual(pdos0[Orbital.s][1].shape, (301, )) filepath2 = os.path.join(test_dir, 'lifepo4.xml') vasprun_ggau = Vasprun(filepath2, parse_projected_eigen=True, parse_potcar_file=False) totalscsteps = sum([len(i['electronic_steps']) for i in vasprun.ionic_steps]) self.assertEqual(29, len(vasprun.ionic_steps)) self.assertEqual(len(vasprun.structures), len(vasprun.ionic_steps)) self.assertEqual(vasprun.lattice, vasprun.lattice_rec.reciprocal_lattice) for i, step in enumerate(vasprun.ionic_steps): self.assertEqual(vasprun.structures[i], step["structure"]) self.assertTrue(all([vasprun.structures[i] == vasprun.ionic_steps[i][ "structure"] for i in range(len(vasprun.ionic_steps))])) self.assertEqual(308, totalscsteps, "Incorrect number of energies read from vasprun.xml") self.assertEqual(['Li'] + 4 * ['Fe'] + 4 * ['P'] + 16 * ["O"], vasprun.atomic_symbols) self.assertEqual(vasprun.final_structure.composition.reduced_formula, "LiFe4(PO4)4") self.assertIsNotNone(vasprun.incar, "Incar cannot be read") self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read") self.assertIsNotNone(vasprun.eigenvalues, "Eigenvalues cannot be read") self.assertAlmostEqual(vasprun.final_energy, -269.38319884, 7) self.assertAlmostEqual(vasprun.tdos.get_gap(), 2.0589, 4) expectedans = (2.539, 4.0906, 1.5516, False) (gap, cbm, vbm, direct) = vasprun.eigenvalue_band_properties self.assertAlmostEqual(gap, expectedans[0]) self.assertAlmostEqual(cbm, expectedans[1]) self.assertAlmostEqual(vbm, expectedans[2]) self.assertEqual(direct, expectedans[3]) self.assertFalse(vasprun.is_hubbard) self.assertEqual(vasprun.potcar_symbols, ['PAW_PBE Li 17Jan2003', 'PAW_PBE Fe 06Sep2000', 'PAW_PBE Fe 06Sep2000', 'PAW_PBE P 17Jan2003', 'PAW_PBE O 08Apr2002']) self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read") self.assertIsNotNone(vasprun.actual_kpoints, "Actual kpoints cannot be read") self.assertIsNotNone(vasprun.actual_kpoints_weights, "Actual kpoints weights cannot be read") for atomdoses in vasprun.pdos: for orbitaldos in atomdoses: self.assertIsNotNone(orbitaldos, "Partial Dos cannot be read") #test skipping ionic steps. vasprun_skip = Vasprun(filepath, 3, parse_potcar_file=False) self.assertEqual(vasprun_skip.nionic_steps, 29) self.assertEqual(len(vasprun_skip.ionic_steps), int(vasprun.nionic_steps / 3) + 1) self.assertEqual(len(vasprun_skip.ionic_steps), len(vasprun_skip.structures)) self.assertEqual(len(vasprun_skip.ionic_steps), int(vasprun.nionic_steps / 3) + 1) #Check that nionic_steps is preserved no matter what. self.assertEqual(vasprun_skip.nionic_steps, vasprun.nionic_steps) self.assertNotAlmostEqual(vasprun_skip.final_energy, vasprun.final_energy) #Test with ionic_step_offset vasprun_offset = Vasprun(filepath, 3, 6, parse_potcar_file=False) self.assertEqual(len(vasprun_offset.ionic_steps), int(len(vasprun.ionic_steps) / 3) - 1) self.assertEqual(vasprun_offset.structures[0], vasprun_skip.structures[2]) self.assertTrue(vasprun_ggau.is_hubbard) self.assertEqual(vasprun_ggau.hubbards["Fe"], 4.3) self.assertAlmostEqual(vasprun_ggau.projected_eigenvalues[(Spin.up, 0, 0, 96, Orbital.s)], 0.0032) d = vasprun_ggau.as_dict() self.assertEqual(d["elements"], ["Fe", "Li", "O", "P"]) self.assertEqual(d["nelements"], 4) filepath = os.path.join(test_dir, 'vasprun.xml.unconverged') vasprun_unconverged = Vasprun(filepath, parse_potcar_file=False) self.assertTrue(vasprun_unconverged.converged_ionic) self.assertFalse(vasprun_unconverged.converged_electronic) self.assertFalse(vasprun_unconverged.converged) filepath = os.path.join(test_dir, 'vasprun.xml.dfpt') vasprun_dfpt = Vasprun(filepath, parse_potcar_file=False) self.assertAlmostEqual(vasprun_dfpt.epsilon_static[0][0], 3.26105533) self.assertAlmostEqual(vasprun_dfpt.epsilon_static[0][1], -0.00459066) self.assertAlmostEqual(vasprun_dfpt.epsilon_static[2][2], 3.24330517) self.assertAlmostEqual(vasprun_dfpt.epsilon_static_wolfe[0][0], 3.33402531) self.assertAlmostEqual(vasprun_dfpt.epsilon_static_wolfe[0][1], -0.00559998) self.assertAlmostEqual(vasprun_dfpt.epsilon_static_wolfe[2][2], 3.31237357) self.assertTrue(vasprun_dfpt.converged) entry = vasprun_dfpt.get_computed_entry() entry = MaterialsProjectCompatibility(check_potcar_hash=False).process_entry(entry) self.assertAlmostEqual(entry.uncorrected_energy + entry.correction, entry.energy) filepath = os.path.join(test_dir, 'vasprun.xml.dfpt.ionic') vasprun_dfpt_ionic = Vasprun(filepath, parse_potcar_file=False) self.assertAlmostEqual(vasprun_dfpt_ionic.epsilon_ionic[0][0], 515.73485838) self.assertAlmostEqual(vasprun_dfpt_ionic.epsilon_ionic[0][1], -0.00263523) self.assertAlmostEqual(vasprun_dfpt_ionic.epsilon_ionic[2][2], 19.02110169) filepath = os.path.join(test_dir, 'vasprun.xml.dfpt.unconverged') vasprun_dfpt_unconv = Vasprun(filepath, parse_potcar_file=False) self.assertFalse(vasprun_dfpt_unconv.converged_electronic) self.assertTrue(vasprun_dfpt_unconv.converged_ionic) self.assertFalse(vasprun_dfpt_unconv.converged) vasprun_uniform = Vasprun(os.path.join(test_dir, "vasprun.xml.uniform"), parse_potcar_file=False) self.assertEqual(vasprun_uniform.kpoints.style, "Reciprocal") vasprun_no_pdos = Vasprun(os.path.join(test_dir, "Li_no_projected.xml"), parse_potcar_file=False) self.assertIsNotNone(vasprun_no_pdos.complete_dos) self.assertFalse(vasprun_no_pdos.dos_has_errors) vasprun_diel = Vasprun(os.path.join(test_dir, "vasprun.xml.dielectric"), parse_potcar_file=False) self.assertAlmostEqual(0.4294,vasprun_diel.dielectric[0][10]) self.assertAlmostEqual(19.941,vasprun_diel.dielectric[1][51][0]) self.assertAlmostEqual(19.941,vasprun_diel.dielectric[1][51][1]) self.assertAlmostEqual(19.941,vasprun_diel.dielectric[1][51][2]) self.assertAlmostEqual(0.0,vasprun_diel.dielectric[1][51][3]) self.assertAlmostEqual(34.186,vasprun_diel.dielectric[2][85][0]) self.assertAlmostEqual(34.186,vasprun_diel.dielectric[2][85][1]) self.assertAlmostEqual(34.186,vasprun_diel.dielectric[2][85][2]) self.assertAlmostEqual(0.0,vasprun_diel.dielectric[2][85][3])
def test_properties(self): filepath = os.path.join(test_dir, 'vasprun.xml') vasprun = Vasprun(filepath) filepath2 = os.path.join(test_dir, 'lifepo4.xml') vasprun_ggau = Vasprun(filepath2, parse_projected_eigen=True) totalscsteps = sum([len(i['electronic_steps']) for i in vasprun.ionic_steps]) self.assertEquals(29, len(vasprun.ionic_steps)) self.assertEquals(len(vasprun.structures), len(vasprun.ionic_steps)) self.assertEqual(vasprun.lattice, vasprun.lattice_rec.reciprocal_lattice) for i, step in enumerate(vasprun.ionic_steps): self.assertEqual(vasprun.structures[i], step["structure"]) self.assertTrue(all([vasprun.structures[i] == vasprun.ionic_steps[i][ "structure"] for i in xrange(len(vasprun.ionic_steps))])) self.assertEquals(308, totalscsteps, "Incorrect number of energies read from vasprun.xml") self.assertEquals(['Li'] + 4 * ['Fe'] + 4 * ['P'] + 16 * ["O"], vasprun.atomic_symbols) self.assertEquals(vasprun.final_structure.composition.reduced_formula, "LiFe4(PO4)4") self.assertIsNotNone(vasprun.incar, "Incar cannot be read") self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read") self.assertIsNotNone(vasprun.eigenvalues, "Eigenvalues cannot be read") self.assertAlmostEqual(vasprun.final_energy, -269.38319884, 7) self.assertAlmostEqual(vasprun.tdos.get_gap(), 2.0589, 4) expectedans = (2.539, 4.0906, 1.5516, False) (gap, cbm, vbm, direct) = vasprun.eigenvalue_band_properties self.assertAlmostEqual(gap, expectedans[0]) self.assertAlmostEqual(cbm, expectedans[1]) self.assertAlmostEqual(vbm, expectedans[2]) self.assertEqual(direct, expectedans[3]) self.assertFalse(vasprun.is_hubbard) self.assertEqual(vasprun.potcar_symbols, [u'PAW_PBE Li 17Jan2003', u'PAW_PBE Fe 06Sep2000', u'PAW_PBE Fe 06Sep2000', u'PAW_PBE P 17Jan2003', u'PAW_PBE O 08Apr2002']) self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read") self.assertIsNotNone(vasprun.actual_kpoints, "Actual kpoints cannot be read") self.assertIsNotNone(vasprun.actual_kpoints_weights, "Actual kpoints weights cannot be read") for atomdoses in vasprun.pdos: for orbitaldos in atomdoses: self.assertIsNotNone(orbitaldos, "Partial Dos cannot be read") #test skipping ionic steps. vasprun_skip = Vasprun(filepath, 3) self.assertEqual(vasprun_skip.nionic_steps, 29) self.assertEqual(len(vasprun_skip.ionic_steps), int(vasprun.nionic_steps / 3) + 1) self.assertEqual(len(vasprun_skip.ionic_steps), len(vasprun_skip.structures)) self.assertEqual(len(vasprun_skip.ionic_steps), int(vasprun.nionic_steps / 3) + 1) #Check that nionic_steps is preserved no matter what. self.assertEqual(vasprun_skip.nionic_steps, vasprun.nionic_steps) self.assertNotAlmostEqual(vasprun_skip.final_energy, vasprun.final_energy) #Test with ionic_step_offset vasprun_offset = Vasprun(filepath, 3, 6) self.assertEqual(len(vasprun_offset.ionic_steps), int(len(vasprun.ionic_steps) / 3) - 1) self.assertEqual(vasprun_offset.structures[0], vasprun_skip.structures[2]) self.assertTrue(vasprun_ggau.is_hubbard) self.assertEqual(vasprun_ggau.hubbards["Fe"], 4.3) self.assertAlmostEqual(vasprun_ggau.projected_eigenvalues[(Spin.up, 0, 0, 96, Orbital.s)], 0.0032) d = vasprun_ggau.to_dict self.assertEqual(d["elements"], ["Fe", "Li", "O", "P"]) self.assertEqual(d["nelements"], 4) filepath = os.path.join(test_dir, 'vasprun.xml.unconverged') vasprun_unconverged = Vasprun(filepath) self.assertFalse(vasprun_unconverged.converged) filepath = os.path.join(test_dir, 'vasprun.xml.dfpt') vasprun_dfpt = Vasprun(filepath) self.assertAlmostEqual(vasprun_dfpt.epsilon_static[0][0], 3.26105533) self.assertAlmostEqual(vasprun_dfpt.epsilon_static[0][1], -0.00459066) self.assertAlmostEqual(vasprun_dfpt.epsilon_static[2][2], 3.24330517) entry = vasprun_dfpt.get_computed_entry() entry = MaterialsProjectCompatibility().process_entry(entry) self.assertAlmostEqual(entry.uncorrected_energy + entry.correction, entry.energy) vasprun_uniform = Vasprun(os.path.join(test_dir, "vasprun.xml.uniform")) self.assertEqual(vasprun_uniform.kpoints.style, "Reciprocal")
def modulate(xmlfile="vasprun.xml", tofile=False): """ Multiply DOS by cross sections and plot it using matplotlib Args: xmlfile(string): name of the vasprun.xml file tofile(bool): data are printed into file BV.dat if true """ run = Vasprun(xmlfile) dos = run.complete_dos BV = dict() BV["total"] = np.zeros(dos.energies.shape) for el in dos.structure.composition.elements: # cross section sigma = CrossSec.from_string(el.symbol) print(sigma.comment) # spd DOS of the element el_dos = dos.get_element_spd_dos(el) # sum up spin contribution spd_dos = dict() if run.is_spin: for orb in el_dos.keys(): spd_dos[orb] = el_dos[orb].densities[Spin.up] \ + el_dos[orb].densities[Spin.down] else: for orb in el_dos.keys(): spd_dos[orb] = el_dos[orb].densities[Spin.up] # compute the BV BV[el] = sigma.s * spd_dos["S"] \ + sigma.p * spd_dos["P"] \ + sigma.d * spd_dos["D"] BV["total"] += BV[el] if tofile: lines = "# Valence Band of compound %s\n" % \ dos.structure.composition.reduced_formula lines += "# column 1: E - E_fermi (eV)\n" lines += "# column 2: total valence band\n" i = 2 for el in dos.structure.composition.elements: i += 1 lines += "# column %d: Contribution of %s \n" % (i, el.symbol) for i in xrange(len(dos.energies)): lines += "%12.7f " % (dos.energies[i] - dos.efermi) lines += "%12.7f " % BV["total"][i] for el in dos.structure.composition.elements: lines += "%12.7f " % BV[el][i] lines += "\n" open("BV.dat", "w").write(lines) else: # plot font = {'family': 'serif', 'size': 20} plt.rc('font', **font) plt.figure(figsize=(11.69, 8.27)) # A4 plt.fill_between(dos.energies - dos.efermi, BV["total"], 0, color=(.8, .8, .8)) plt.plot(dos.energies - dos.efermi, BV["total"], color=(.5, .5, .5), label="total") color = ["r-", "g-", "b-", "y-", "m-", "c-"] for el, c in zip(dos.structure.composition.elements, color): plt.plot(dos.energies - dos.efermi, BV[el], c, label=el.symbol) # set up figure plt.title("Valence band of " + \ run.initial_structure.composition.reduced_formula) plt.xlabel(r"$E - E_{f}$ / eV") plt.ylabel("Density of states times cross sections") plt.grid() ymin, ymax = plt.ylim() plt.vlines(0, ymin, ymax, color="k", lw=1, linestyle="--") plt.legend(prop={"size": 18}) plt.show()