def actual_diele_func_data(test_data_files): v = Vasprun(test_data_files / "MgSe_absorption_vasprun.xml") o = Outcar(test_data_files / "MgSe_absorption_OUTCAR") return make_diele_func(v, o)
from pymatgen.io.vasp import Outcar oc = Outcar('OUTCAR') for i in oc.magnetization: print(i['tot'])
def band_edge_properties(args: Namespace): vasprun = Vasprun(args.vasprun) outcar = Outcar(args.outcar) print(VaspBandEdgeProperties(vasprun, outcar))
import numpy as np from pymatgen.io.vasp import Structure, Outcar s: Structure = Structure.from_file('POSCAR') out = Outcar('OUTCAR') e = 1.60217646e-19 v = s.volume pol = np.zeros(3) for j in range(4): result = np.zeros(3) for i in s.get_all_neighbors(2.5)[j]: result += i[0].coords diff = result / 7 - s.sites[j].coords pol += np.inner(out.born[j], diff) print(pol * e / v * 1e+22) # uC/cm^2
def setUp(self): struc = PymatgenTest.get_structure("VO2") struc.make_supercell(3) struc = struc self.vac = Vacancy(struc, struc.sites[0], charge=-3) abc = self.vac.bulk_structure.lattice.abc axisdata = [np.arange(0.0, lattval, 0.2) for lattval in abc] bldata = [ np.array([1.0 for u in np.arange(0.0, lattval, 0.2)]) for lattval in abc ] dldata = [ np.array([(-1 - np.cos(2 * np.pi * u / lattval)) for u in np.arange(0.0, lattval, 0.2)]) for lattval in abc ] self.frey_params = { "axis_grid": axisdata, "bulk_planar_averages": bldata, "defect_planar_averages": dldata, "dielectric": 15, "initial_defect_structure": struc.copy(), "defect_frac_sc_coords": struc.sites[0].frac_coords[:], } kumagai_bulk_struc = Poscar.from_file( os.path.join(PymatgenTest.TEST_FILES_DIR, "defect", "CONTCAR_bulk")).structure bulk_out = Outcar( os.path.join(PymatgenTest.TEST_FILES_DIR, "defect", "OUTCAR_bulk.gz")) defect_out = Outcar( os.path.join(PymatgenTest.TEST_FILES_DIR, "defect", "OUTCAR_vac_Ga_-3.gz")) self.kumagai_vac = Vacancy(kumagai_bulk_struc, kumagai_bulk_struc.sites[0], charge=-3) kumagai_defect_structure = self.kumagai_vac.generate_defect_structure() self.kumagai_params = { "bulk_atomic_site_averages": bulk_out.electrostatic_potential, "defect_atomic_site_averages": defect_out.electrostatic_potential, "site_matching_indices": [[ind, ind - 1] for ind in range(len(kumagai_bulk_struc))], "defect_frac_sc_coords": [0.0, 0.0, 0.0], "initial_defect_structure": kumagai_defect_structure, "dielectric": 18.118 * np.identity(3), "gamma": 0.153156, # not necessary to load gamma, but speeds up unit test } v = Vasprun(os.path.join(PymatgenTest.TEST_FILES_DIR, "vasprun.xml")) eigenvalues = v.eigenvalues.copy() kptweights = v.actual_kpoints_weights potalign = -0.1 vbm = v.eigenvalue_band_properties[2] cbm = v.eigenvalue_band_properties[1] defect_incar = v.incar self.bandfill_params = { "eigenvalues": eigenvalues, "kpoint_weights": kptweights, "potalign": potalign, "vbm": vbm, "cbm": cbm, "run_metadata": { "defect_incar": defect_incar }, } self.band_edge_params = { "hybrid_cbm": 1.0, "hybrid_vbm": -1.0, "vbm": -0.5, "cbm": 0.6, "num_hole_vbm": 1.0, "num_elec_cbm": 1.0, }
def test_kumagai(self): gamma = 0.19357221 prec = 28 lattice = Lattice([[4.692882, -8.12831, 0.0], [4.692882, 8.12831, 0.0], [0.0, 0.0, 10.03391]]) # note that real/recip vector generation is not dependent on epsilon g_vecs, _, r_vecs, _ = generate_R_and_G_vecs(gamma, prec, lattice, 80.0 * np.identity(3)) # test real space summation (bigger for large epsilon) kc_high_diel = KumagaiCorrection(80.0 * np.identity(3), gamma=gamma) real_sum = kc_high_diel.get_real_summation(gamma, r_vecs[0]) self.assertAlmostEqual(real_sum, 0.00843104) # test recip space summation (bigger for small epsilon) kc_low_diel = KumagaiCorrection(0.1 * np.identity(3), gamma=gamma) recip_sum = kc_low_diel.get_recip_summation(gamma, g_vecs[0], lattice.volume) self.assertAlmostEqual(recip_sum, 0.31117099) # test self interaction si_corr = kc_low_diel.get_self_interaction(gamma) self.assertAlmostEqual(si_corr, -0.54965249) # test potenital shift interaction correction ps_corr = kc_low_diel.get_potential_shift(gamma, lattice.volume) self.assertAlmostEqual(ps_corr, -0.00871593) # """Test Defect Entry approach to correction """ bulk_struc = Poscar.from_file( os.path.join(test_dir, "defect", "CONTCAR_bulk")).structure bulk_out = Outcar(os.path.join(test_dir, "defect", "OUTCAR_bulk.gz")) defect_out = Outcar( os.path.join(test_dir, "defect", "OUTCAR_vac_Ga_-3.gz")) epsilon = 18.118 * np.identity(3) vac = Vacancy(bulk_struc, bulk_struc.sites[0], charge=-3) defect_structure = vac.generate_defect_structure() defect_frac_coords = [0.0, 0.0, 0.0] parameters = { "bulk_atomic_site_averages": bulk_out.electrostatic_potential, "defect_atomic_site_averages": defect_out.electrostatic_potential, "site_matching_indices": [[ind, ind - 1] for ind in range(len(bulk_struc))], "initial_defect_structure": defect_structure, "defect_frac_sc_coords": defect_frac_coords, } dentry = DefectEntry(vac, 0.0, parameters=parameters) kc = KumagaiCorrection(epsilon) kcorr = kc.get_correction(dentry) self.assertAlmostEqual(kcorr["kumagai_electrostatic"], 0.88236299) self.assertAlmostEqual(kcorr["kumagai_potential_alignment"], 2.09704862) # test ES correction high_diel_es_corr = kc_high_diel.perform_es_corr( gamma, prec, lattice, -3.0) self.assertAlmostEqual(high_diel_es_corr, 0.25176240) low_diel_es_corr = kc_low_diel.perform_es_corr(gamma, prec, lattice, -3.0) self.assertAlmostEqual(low_diel_es_corr, 201.28810966) # test pot correction site_list = [] for bs_ind, ds_ind in dentry.parameters["site_matching_indices"]: Vqb = -(defect_out.electrostatic_potential[ds_ind] - bulk_out.electrostatic_potential[bs_ind]) site_list.append([defect_structure[ds_ind], Vqb]) sampling_radius = dentry.parameters["kumagai_meta"]["sampling_radius"] gamma = dentry.parameters["kumagai_meta"]["gamma"] q = -3 g_vecs, _, r_vecs, _ = generate_R_and_G_vecs(gamma, 28, defect_structure.lattice, np.identity(3)) high_diel_pot_corr = kc_high_diel.perform_pot_corr( defect_structure, defect_frac_coords, site_list, sampling_radius, q, r_vecs[0], g_vecs[0], gamma, ) self.assertAlmostEqual(high_diel_pot_corr, 2.35840716) low_diel_pot_corr = kc_low_diel.perform_pot_corr( defect_structure, defect_frac_coords, site_list, sampling_radius, q, r_vecs[0], g_vecs[0], gamma, ) self.assertAlmostEqual(low_diel_pot_corr, -58.83598095) # test the kumagai plotter kcp = kc.plot() self.assertTrue(kcp) # check that uncertainty metadata exists self.assertAlmostEqual( set(kc.metadata["pot_corr_uncertainty_md"].keys()), set(["number_sampled", "stats"]), )
def elastic_analysis(): filename = 'OUTCAR' step_count = 1 check_file(filename) proc_str = "Reading Data From " + filename + " File ..." procs(proc_str, step_count, sp='-->>') outcar = Outcar(filename) outcar.read_elastic_tensor() cij_tensor = np.array(outcar.data['elastic_tensor']) filename = 'vasprun.xml' step_count += 1 check_file(filename) proc_str = "Reading Data From " + filename + " File ..." procs(proc_str, step_count, sp='-->>') vsr = Vasprun(filename) struct0 = vsr.structures[0] natom = struct0.num_sites weight = struct0.composition.weight volume = struct0.lattice.volume ## converting the units volume *= 1.0e-30 ## from Angstrom to meters weight *= weight * 1.0e-3 ## from gram to kg density = weight / (volume * Avogadro) asa = analyzer.SpacegroupAnalyzer(struct0) # lat_type=asa.get_crystal_system() crys_type = asa.get_lattice_type() ## Redefining the Cij matrix into the correct Voigt notation since VASP's OUTCAR has a different order ## In VASP: Columns and rows are listed as: 1, 2, 3, 6, 4, 5 ## In this format OUTCAR's C44 values would be actually C66, C55 would be C44, and C66 would be C55. ## OUTCAR follows the below order: ## [C11 C12 C13 C16 C14 C15] ## [C21 C22 C23 C26 C24 C25] ## [C31 C32 C33 C36 C34 C35] ## [C61 C62 C63 C66 C64 C65] ## [C41 C42 C43 C46 C44 C45] ## [C51 C52 C53 C56 C54 C55] cnew = np.zeros((6, 6)) snew = np.zeros((6, 6)) cnew = np.copy(cij_tensor) for j in range(0, 6): cnew[3][j] = cij_tensor[4][j] cnew[4][j] = cij_tensor[5][j] cnew[5][j] = cij_tensor[3][j] ctemp = np.zeros((6, 6)) ctemp = np.copy(cnew) for i in range(0, 6): cnew[i][3] = cnew[i][4] cnew[i][4] = cnew[i][5] cnew[i][5] = ctemp[i][3] # Change the units of Cij from kBar to GPa cnew = cnew / 10.0 proc_str = "\n Modified elastic tensor in correct order (in GPa units)" print(proc_str) fmt = "%7.3f " * 6 for i in range(6): print(fmt % tuple(cnew[i, :])) def check_symmetric(a, tol=1e-8): return np.allclose(a, a.T, atol=tol) print( '\n Checking if the elastic tensor is symmetric: i.e. Cij = Cji: %5s' % check_symmetric(cnew)) print("\n Eigen Values of the elastic tensor:") evals = LA.eigvals(cnew) print(fmt % tuple(evals)) if np.all(evals) > 0.0: print("\n All eigen values are positive indicating elastic stability.") else: print( "\n ATTENTION: One or more eigen values are negative indicating elastic instability." ) calc_elastic_prop(cnew, snew, crys_type, density, weight, natom)
def post_process(self, dir_name, d): """ Simple post-processing for various files other than the vasprun.xml. Called by generate_task_doc. Modify this if your runs have other kinds of processing requirements. Args: dir_name: The dir_name. d: Current doc generated. """ logger.info("Post-processing dir:{}".format(dir_name)) fullpath = os.path.abspath(dir_name) # VASP input generated by pymatgen's alchemy has a # transformations.json file that keeps track of the origin of a # particular structure. This is extremely useful for tracing back a # result. If such a file is found, it is inserted into the task doc # as d["transformations"] transformations = {} filenames = glob.glob(os.path.join(fullpath, "transformations.json*")) if len(filenames) >= 1: with zopen(filenames[0], "rt") as f: transformations = json.load(f) try: m = re.match("(\d+)-ICSD", transformations["history"][0]["source"]) if m: d["icsd_id"] = int(m.group(1)) except Exception as ex: logger.warning("Cannot parse ICSD from transformations " "file.") pass else: logger.warning("Transformations file does not exist.") other_parameters = transformations.get("other_parameters") new_tags = None if other_parameters: # We don't want to leave tags or authors in the # transformations file because they'd be copied into # every structure generated after this one. new_tags = other_parameters.pop("tags", None) new_author = other_parameters.pop("author", None) if new_author: d["author"] = new_author if not other_parameters: # if dict is now empty remove it transformations.pop("other_parameters") d["transformations"] = transformations # Calculations done using custodian has a custodian.json, # which tracks the jobs performed and any errors detected and fixed. # This is useful for tracking what has actually be done to get a # result. If such a file is found, it is inserted into the task doc # as d["custodian"] filenames = glob.glob(os.path.join(fullpath, "custodian.json*")) if len(filenames) >= 1: with zopen(filenames[0], "r") as f: d["custodian"] = json.load(f) # Parse OUTCAR for additional information and run stats that are # generally not in vasprun.xml. try: run_stats = {} for filename in glob.glob(os.path.join(fullpath, "OUTCAR*")): outcar = Outcar(filename) i = 1 if re.search("relax2", filename) else 0 taskname = "relax2" if re.search("relax2", filename) else \ "relax1" d["calculations"][i]["output"]["outcar"] = outcar.as_dict() run_stats[taskname] = outcar.run_stats except: logger.error("Bad OUTCAR for {}.".format(fullpath)) 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(fullpath)) d["run_stats"] = run_stats #Convert to full uri path. if self.use_full_uri: d["dir_name"] = get_uri(dir_name) if new_tags: d["tags"] = new_tags logger.info("Post-processed " + fullpath)
fE = tot_E - ref_dict[el[0]] - ref_dict[ el[1]] - 1.5 * ref_dict['O2_corr'] if el[0] or el[1] in U_corr_dict: for x in range(len(el)): if el[x] in U_corr_dict: fE = fE - U_corr_dict[el[x]] fE = fE / len(conv_struc) # eV/atom df_bulk.DHf[idx + 1] = fE df_bulk.Err_DHf[idx + 1] = df_bulk.DHf_ref[idx + 1] - df_bulk.DHf[idx + 1] outcar = Outcar(file_path + 'OUTCAR') magm_list = [] for atom in range(len(conv_struc)): magm_list.append(outcar.magnetization[atom]['tot']) df_bulk.Magm[idx + 1] = magm_list if tot_mag >= 0.5: # not a physical definition df_bulk.Mag_O[idx + 1] = 'FM' elif tot_mag < 0.5: df_bulk.Mag_O[idx + 1] = 'NM' bulk_opt = read_vasp(file_path + 'CONTCAR') elements = [] for element in bulk_opt.get_chemical_symbols(): if element not in elements:
df_bulk.Err_V_percent[idx+1] = (volume_ref - volume) / volume_ref * 100 el = v.as_dict()['elements'] el.remove('O') fE = tot_E - ref_dict[el[0]] - ref_dict[el[1]] - 1.5*ref_dict['O2_corr'] if el[0] or el[1] in U_corr_dict: for x in range(len(el)): if el[x] in U_corr_dict: fE = fE - U_corr_dict[el[x]] df_bulk.DHf[idx+1] = fE/5.0 df_bulk.Err_DHf[idx+1] = df_bulk.DHf_ref[idx+1] - df_bulk.DHf[idx+1] outcar = Outcar('%03d_%s/2nd/OUTCAR' % (idx + 1.0, formula)) magm_list = [] for atom in range(len(conv_struc)): magm_list.append(outcar.magnetization[atom]['tot']) df_bulk.Magm[idx + 1] = magm_list if tot_mag >= 0.5: # not a physical definition df_bulk.Mag_O[idx+1] = 'FM' elif tot_mag < 0.5: df_bulk.Mag_O[idx+1] = 'NM' except FileNotFoundError: # print('%03d_%s/2nd files are not found' % (idx + 1.0, formula)) f.writelines('%03d_%s/2nd files are not found\n' % (idx + 1.0, formula)) continue
def run_task(self, fw_spec): write_output = True job_info_array = fw_spec['_job_info'] # get dummy index with open(os.path.join(job_info_array[-1]['launch_dir'], 'POSCAR'), 'rt') as f: poscar_lines = f.readlines() elem_list = poscar_lines[0].split() num_ions = [int(item) for item in poscar_lines[5].split()] dummy_index = 0 for elem, amount in zip(elem_list, num_ions): if elem == self['dummy_atom']: if amount == 1: break else: raise ValueError( 'More than one dummy atom in the structure') else: dummy_index += amount # get charges charges = [] incar_bare = Incar.from_file( os.path.join(job_info_array[0]['launch_dir'], 'INCAR')) outcar_bare = Outcar( os.path.join(job_info_array[0]['launch_dir'], 'OUTCAR')) bare_magmoms = [ item['tot'] for item, ref in zip(outcar_bare.magnetization, incar_bare['MAGMOM']) if ref != 0 ] for step in [1, 2]: outcar = Outcar( os.path.join(job_info_array[step]['launch_dir'], 'OUTCAR')) with open( os.path.join(job_info_array[step]['launch_dir'], 'is_converged'), 'r') as f: conv_info = f.readline() if 'f' in outcar.charge[dummy_index]: charges.append(outcar.charge[dummy_index]['f']) else: charges.append(outcar.charge[dummy_index]['d']) final_magmoms = [ item['tot'] for item, ref in zip( outcar.magnetization, incar_bare['MAGMOM']) if ref != 0 ] for bare_magmom, final_magmom in zip(bare_magmoms, final_magmoms): if bare_magmom != 0: # if the magnetic moment changes too much, do not write charges in output if final_magmom / bare_magmom < 0.8 or final_magmom / bare_magmom > 1.2 \ or conv_info == 'NONCONVERGED': write_output = False if write_output: with open( os.path.join(os.environ.get('AUTOMAG_PATH'), 'CalcFold', self['filename']), 'a') as f: f.write( f"{self['pert_value']:5.2f} {charges[0]} {charges[1]}\n")
def _inner(_dir: Path): calc_results = make_calc_results_from_vasp( vasprun=Vasprun(_dir / defaults.vasprun), outcar=Outcar(_dir / defaults.outcar)) calc_results.to_json_file(str(_dir / "calc_results.json"))
def Get_ElasConst(self, filepath): outcar = Outcar(filepath + "OUTCAR") outcar.read_elastic_tensor() self.tensor = np.array( outcar.data["elastic_tensor"]) / 10 #unit in GPa
def calc_results(vasp_files): vasprun = Vasprun(vasp_files / "MgO_conv_Va_O_0" / "vasprun.xml") outcar = Outcar(vasp_files / "MgO_conv_Va_O_0" / "OUTCAR") return make_calc_results_from_vasp(vasprun, outcar)
def correct(self): backup(VASP_BACKUP_FILES | {self.output_filename}) actions = [] vi = VaspInput.from_directory(".") if self.errors.intersection(["tet", "dentet"]): actions.append({ "dict": "INCAR", "action": { "_set": { "ISMEAR": 0 } } }) if "inv_rot_mat" in self.errors: actions.append({ "dict": "INCAR", "action": { "_set": { "SYMPREC": 1e-8 } } }) if "brmix" in self.errors: # If there is not a valid OUTCAR already, increment # error count to 1 to skip first fix if self.error_count['brmix'] == 0: try: assert (Outcar(zpath(os.path.join( os.getcwd(), "OUTCAR"))).is_stopped is False) except: self.error_count['brmix'] += 1 if self.error_count['brmix'] == 0: # Valid OUTCAR - simply rerun the job and increment # error count for next time actions.append({ "dict": "INCAR", "action": { "_set": { "ISTART": 1 } } }) self.error_count['brmix'] += 1 elif self.error_count['brmix'] == 1: # Use Kerker mixing w/default values for other parameters actions.append({ "dict": "INCAR", "action": { "_set": { "IMIX": 1 } } }) self.error_count['brmix'] += 1 elif self.error_count['brmix'] == 2 and vi["KPOINTS"].style \ == Kpoints.supported_modes.Gamma: actions.append({ "dict": "KPOINTS", "action": { "_set": { "generation_style": "Monkhorst" } } }) actions.append({ "dict": "INCAR", "action": { "_unset": { "IMIX": 1 } } }) self.error_count['brmix'] += 1 elif self.error_count['brmix'] in [2, 3] and vi["KPOINTS"].style \ == Kpoints.supported_modes.Monkhorst: actions.append({ "dict": "KPOINTS", "action": { "_set": { "generation_style": "Gamma" } } }) actions.append({ "dict": "INCAR", "action": { "_unset": { "IMIX": 1 } } }) self.error_count['brmix'] += 1 if vi["KPOINTS"].num_kpts < 1: all_kpts_even = all( [bool(n % 2 == 0) for n in vi["KPOINTS"].kpts[0]]) print("all_kpts_even = {}".format(all_kpts_even)) if all_kpts_even: new_kpts = (tuple(n + 1 for n in vi["KPOINTS"].kpts[0]), ) print("new_kpts = {}".format(new_kpts)) actions.append({ "dict": "KPOINTS", "action": { "_set": { "kpoints": new_kpts } } }) else: actions.append({ "dict": "INCAR", "action": { "_set": { "ISYM": 0 } } }) if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst: actions.append({ "dict": "KPOINTS", "action": { "_set": { "generation_style": "Gamma" } } }) # Based on VASP forum's recommendation, you should delete the # CHGCAR and WAVECAR when dealing with this error. actions.append({ "file": "CHGCAR", "action": { "_file_delete": { 'mode': "actual" } } }) actions.append({ "file": "WAVECAR", "action": { "_file_delete": { 'mode': "actual" } } }) if "zpotrf" in self.errors: # Usually caused by short bond distances. If on the first step, # volume needs to be increased. Otherwise, it was due to a step # being too big and POTIM should be decreased. try: oszicar = Oszicar("OSZICAR") nsteps = len(oszicar.ionic_steps) except: nsteps = 0 if nsteps >= 1: potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0 actions.append({ "dict": "INCAR", "action": { "_set": { "ISYM": 0, "POTIM": potim } } }) else: s = vi["POSCAR"].structure s.apply_strain(0.2) actions.append({ "dict": "POSCAR", "action": { "_set": { "structure": s.as_dict() } } }) # Based on VASP forum's recommendation, you should delete the # CHGCAR and WAVECAR when dealing with this error. actions.append({ "file": "CHGCAR", "action": { "_file_delete": { 'mode': "actual" } } }) actions.append({ "file": "WAVECAR", "action": { "_file_delete": { 'mode': "actual" } } }) if self.errors.intersection( ["subspacematrix", "rspher", "real_optlay"]): actions.append({ "dict": "INCAR", "action": { "_set": { "LREAL": False } } }) if self.errors.intersection(["tetirr", "incorrect_shift"]): if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst: actions.append({ "dict": "KPOINTS", "action": { "_set": { "generation_style": "Gamma" } } }) if "rot_matrix" in self.errors: if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst: actions.append({ "dict": "KPOINTS", "action": { "_set": { "generation_style": "Gamma" } } }) else: actions.append({ "dict": "INCAR", "action": { "_set": { "ISYM": 0 } } }) if "amin" in self.errors: actions.append({ "dict": "INCAR", "action": { "_set": { "AMIN": "0.01" } } }) if "triple_product" in self.errors: s = vi["POSCAR"].structure trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0))) new_s = trans.apply_transformation(s) actions.append({ "dict": "POSCAR", "action": { "_set": { "structure": new_s.as_dict() } }, "transformation": trans.as_dict() }) if "pricel" in self.errors: actions.append({ "dict": "INCAR", "action": { "_set": { "SYMPREC": 1e-8, "ISYM": 0 } } }) if "brions" in self.errors: potim = float(vi["INCAR"].get("POTIM", 0.5)) + 0.1 actions.append({ "dict": "INCAR", "action": { "_set": { "POTIM": potim } } }) if "zbrent" in self.errors: actions.append({ "dict": "INCAR", "action": { "_set": { "IBRION": 1 } } }) if "too_few_bands" in self.errors: if "NBANDS" in vi["INCAR"]: nbands = int(vi["INCAR"]["NBANDS"]) else: with open("OUTCAR") as f: for line in f: if "NBANDS" in line: try: d = line.split("=") nbands = int(d[-1].strip()) break except (IndexError, ValueError): pass actions.append({ "dict": "INCAR", "action": { "_set": { "NBANDS": int(1.1 * nbands) } } }) if "pssyevx" in self.errors: actions.append({ "dict": "INCAR", "action": { "_set": { "ALGO": "Normal" } } }) if "eddrmm" in self.errors: #RMM algorithm is not stable for this calculation if vi["INCAR"].get("ALGO", "Normal") in ["Fast", "VeryFast"]: actions.append({ "dict": "INCAR", "action": { "_set": { "ALGO": "Normal" } } }) else: potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0 actions.append({ "dict": "INCAR", "action": { "_set": { "POTIM": potim } } }) actions.append({ "file": "CHGCAR", "action": { "_file_delete": { 'mode': "actual" } } }) actions.append({ "file": "WAVECAR", "action": { "_file_delete": { 'mode': "actual" } } }) if "edddav" in self.errors: actions.append({ "file": "CHGCAR", "action": { "_file_delete": { 'mode': "actual" } } }) actions.append({ "dict": "INCAR", "action": { "_set": { "ALGO": "All" } } }) VaspModder(vi=vi).apply_actions(actions) return {"errors": list(self.errors), "actions": actions}
def setUp(self): struc = PymatgenTest.get_structure("VO2") struc.make_supercell(3) struc = struc self.vac = Vacancy(struc, struc.sites[0], charge=-3) abc = self.vac.bulk_structure.lattice.abc axisdata = [np.arange(0., lattval, 0.2) for lattval in abc] bldata = [ np.array([1. for u in np.arange(0., lattval, 0.2)]) for lattval in abc ] dldata = [ np.array([(-1 - np.cos(2 * np.pi * u / lattval)) for u in np.arange(0., lattval, 0.2)]) for lattval in abc ] self.frey_params = { 'axis_grid': axisdata, 'bulk_planar_averages': bldata, 'defect_planar_averages': dldata, 'dielectric': 15, 'initial_defect_structure': struc.copy(), 'defect_frac_sc_coords': struc.sites[0].frac_coords[:] } kumagai_bulk_struc = Poscar.from_file( os.path.join(test_dir, 'defect', 'CONTCAR_bulk')).structure bulk_out = Outcar(os.path.join(test_dir, 'defect', 'OUTCAR_bulk.gz')) defect_out = Outcar( os.path.join(test_dir, 'defect', 'OUTCAR_vac_Ga_-3.gz')) self.kumagai_vac = Vacancy(kumagai_bulk_struc, kumagai_bulk_struc.sites[0], charge=-3) kumagai_defect_structure = self.kumagai_vac.generate_defect_structure() self.kumagai_params = { 'bulk_atomic_site_averages': bulk_out.electrostatic_potential, 'defect_atomic_site_averages': defect_out.electrostatic_potential, 'site_matching_indices': [[ind, ind - 1] for ind in range(len(kumagai_bulk_struc))], 'defect_frac_sc_coords': [0., 0., 0.], 'initial_defect_structure': kumagai_defect_structure, 'dielectric': 18.118 * np.identity(3), 'gamma': 0.153156 # not neccessary to load gamma, but speeds up unit test } v = Vasprun(os.path.join(test_dir, 'vasprun.xml')) eigenvalues = v.eigenvalues.copy() kptweights = v.actual_kpoints_weights potalign = -0.1 vbm = v.eigenvalue_band_properties[2] cbm = v.eigenvalue_band_properties[1] self.bandfill_params = { 'eigenvalues': eigenvalues, 'kpoint_weights': kptweights, 'potalign': potalign, 'vbm': vbm, 'cbm': cbm } self.band_edge_params = { 'hybrid_cbm': 1., 'hybrid_vbm': -1., 'vbm': -0.5, 'cbm': 0.6, 'num_hole_vbm': 1., 'num_elec_cbm': 1. }
def generate_doc(self, dir_name, vasprun_files, outcar_files): """ Adapted from matgendb.creator.generate_doc """ try: # basic properties, incl. calcs_reversed and run_stats fullpath = os.path.abspath(dir_name) d = {k: v for k, v in self.additional_fields.items()} d["schema"] = {"code": "atomate", "version": VaspDrone.__version__} d["dir_name"] = fullpath d["calcs_reversed"] = [self.process_vasprun(dir_name, taskname, filename) for taskname, filename in vasprun_files.items()] outcar_data = [Outcar(os.path.join(dir_name, filename)).as_dict() for taskname, filename in outcar_files.items()] run_stats = {} for i, d_calc in enumerate(d["calcs_reversed"]): run_stats[d_calc["task"]["name"]] = outcar_data[i].pop("run_stats") if d_calc.get("output"): d_calc["output"].update({"outcar": outcar_data[i]}) else: d_calc["output"] = {"outcar": outcar_data[i]} 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(fullpath)) d["run_stats"] = run_stats # reverse the calculations data order so newest calc is first d["calcs_reversed"].reverse() # set root formula/composition keys based on initial and final calcs d_calc_init = d["calcs_reversed"][-1] d_calc_final = d["calcs_reversed"][0] d["chemsys"] = "-".join(sorted(d_calc_final["elements"])) comp = Composition(d_calc_final["composition_unit_cell"]) d["formula_anonymous"] = comp.anonymized_formula d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula for root_key in ["completed_at", "nsites", "composition_unit_cell", "composition_reduced", "formula_pretty", "elements", "nelements"]: d[root_key] = d_calc_final[root_key] # store the input key based on initial calc # store any overrides to the exchange correlation functional xc = d_calc_init["input"]["incar"].get("GGA") if xc: xc = xc.upper() p = d_calc_init["input"]["potcar_type"][0].split("_") pot_type = p[0] functional = "lda" if len(pot_type) == 1 else "_".join(p[1:]) d["input"] = {"structure": d_calc_init["input"]["structure"], "is_hubbard": d_calc_init.pop("is_hubbard"), "hubbards": d_calc_init.pop("hubbards"), "is_lasph": d_calc_init["input"]["incar"].get("LASPH", False), "potcar_spec": d_calc_init["input"].get("potcar_spec"), "xc_override": xc, "pseudo_potential": {"functional": functional.lower(), "pot_type": pot_type.lower(), "labels": d_calc_init["input"]["potcar"]}, "parameters": d_calc_init["input"]["parameters"], "incar": d_calc_init["input"]["incar"] } # store the output key based on final calc d["output"] = { "structure": d_calc_final["output"]["structure"], "density": d_calc_final.pop("density"), "energy": d_calc_final["output"]["energy"], "energy_per_atom": d_calc_final["output"]["energy_per_atom"]} # patch calculated magnetic moments into final structure if len(d_calc_final["output"]["outcar"]["magnetization"]) != 0: magmoms = [m["tot"] for m in d_calc_final["output"]["outcar"]["magnetization"]] s = Structure.from_dict(d["output"]["structure"]) s.add_site_property('magmom', magmoms) d["output"]["structure"] = s.as_dict() calc = d["calcs_reversed"][0] try: d["output"].update({"bandgap": calc["output"]["bandgap"], "cbm": calc["output"]["cbm"], "vbm": calc["output"]["vbm"], "is_gap_direct": calc["output"]["is_gap_direct"], "is_metal": calc["output"]["is_metal"]}) except Exception: if self.bandstructure_mode is True: import traceback logger.error(traceback.format_exc()) logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc()) raise sg = SpacegroupAnalyzer(Structure.from_dict(d_calc_final["output"]["structure"]), 0.1) if not sg.get_symmetry_dataset(): sg = SpacegroupAnalyzer(Structure.from_dict(d_calc_final["output"]["structure"]), 1e-3, 1) d["output"]["spacegroup"] = { "source": "spglib", "symbol": sg.get_space_group_symbol(), "number": sg.get_space_group_number(), "point_group": sg.get_point_group_symbol(), "crystal_system": sg.get_crystal_system(), "hall": sg.get_hall()} if d["input"]["parameters"].get("LEPSILON"): for k in ['epsilon_static', 'epsilon_static_wolfe', 'epsilon_ionic']: d["output"][k] = d_calc_final["output"][k] if SymmOp.inversion() not in sg.get_symmetry_operations(): for k in ["piezo_ionic_tensor", "piezo_tensor"]: d["output"][k] = d_calc_final["output"]["outcar"][k] d["state"] = "successful" if d_calc["has_vasp_completed"] else "unsuccessful" self.set_analysis(d) d["last_updated"] = datetime.datetime.today() return d except Exception: import traceback logger.error(traceback.format_exc()) logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc()) raise
def process_outcar(self, dir_name, filename): """ Process the outcar file """ return Outcar(os.path.join(dir_name, filename)).as_dict()
def from_dir(cls, root_dir, relaxation_dirs=None, **kwargs): """ Initializes a NEBAnalysis object from a directory of a NEB run. Note that OUTCARs must be present in all image directories. For the terminal OUTCARs from relaxation calculations, you can specify the locations using relaxation_dir. If these are not specified, the code will attempt to look for the OUTCARs in 00 and 0n directories, followed by subdirs "start", "end" or "initial", "final" in the root_dir. These are just some typical conventions used preferentially in Shyue Ping's MAVRL research group. For the non-terminal points, the CONTCAR is read to obtain structures. For terminal points, the POSCAR is used. The image directories are assumed to be the only directories that can be resolved to integers. E.g., "00", "01", "02", "03", "04", "05", "06". The minimum sub-directory structure that can be parsed is of the following form ( a 5-image example is shown): 00: - POSCAR - OUTCAR 01, 02, 03, 04, 05: - CONTCAR - OUTCAR 06: - POSCAR - OUTCAR Args: root_dir (str): Path to the root directory of the NEB calculation. relaxation_dirs (tuple): This specifies the starting and ending relaxation directories from which the OUTCARs are read for the terminal points for the energies. Returns: NEBAnalysis object. """ neb_dirs = [] for d in os.listdir(root_dir): pth = os.path.join(root_dir, d) if os.path.isdir(pth) and d.isdigit(): i = int(d) neb_dirs.append((i, pth)) neb_dirs = sorted(neb_dirs, key=lambda d: d[0]) outcars = [] structures = [] # Setup the search sequence for the OUTCARs for the terminal # directories. terminal_dirs = [] if relaxation_dirs is not None: terminal_dirs.append(relaxation_dirs) terminal_dirs.append((neb_dirs[0][1], neb_dirs[-1][1])) terminal_dirs.append( [os.path.join(root_dir, d) for d in ["start", "end"]]) terminal_dirs.append( [os.path.join(root_dir, d) for d in ["initial", "final"]]) for i, d in neb_dirs: outcar = glob.glob(os.path.join(d, "OUTCAR*")) contcar = glob.glob(os.path.join(d, "CONTCAR*")) poscar = glob.glob(os.path.join(d, "POSCAR*")) terminal = i == 0 or i == neb_dirs[-1][0] if terminal: for ds in terminal_dirs: od = ds[0] if i == 0 else ds[1] outcar = glob.glob(os.path.join(od, "OUTCAR*")) if outcar: outcar = sorted(outcar) outcars.append(Outcar(outcar[-1])) break else: raise ValueError("OUTCAR cannot be found for terminal " "point %s" % d) structures.append(Poscar.from_file(poscar[0]).structure) else: outcars.append(Outcar(outcar[0])) structures.append(Poscar.from_file(contcar[0]).structure) return NEBAnalysis.from_outcars(outcars, structures, **kwargs)
def band_structure(): check_matplotlib() step_count = 1 filename = 'vasprun.xml' check_file(filename) proc_str = "Reading Data From " + filename + " File ..." procs(proc_str, step_count, sp='-->>') vsr = Vasprun(filename) step_count += 1 filename = 'KPOINTS' check_file(filename) proc_str = "Reading Data From " + filename + " File ..." procs(proc_str, step_count, sp='-->>') bands = vsr.get_band_structure(filename, line_mode=True, efermi=vsr.efermi) step_count += 1 filename = 'OUTCAR' check_file(filename) proc_str = "Reading Data From " + filename + " File ..." procs(proc_str, step_count, sp='-->>') outcar = Outcar('OUTCAR') mag = outcar.as_dict()['total_magnetization'] if vsr.is_spin: proc_str = "This Is a Spin-polarized Calculation." procs(proc_str, 0, sp='-->>') tdos = vsr.tdos SpinUp_gap = tdos.get_gap(spin=Spin.up) cbm_vbm_up = tdos.get_cbm_vbm(spin=Spin.up) SpinDown_gap = tdos.get_gap(spin=Spin.down) cbm_vbm_down = tdos.get_cbm_vbm(spin=Spin.up) if SpinUp_gap > min_gap and SpinDown_gap > min_gap: is_metal = False is_semimetal = False elif SpinUp_gap > min_gap and SpinDown_gap < min_gap: is_metal = False is_semimetal = True elif SpinUp_gap < min_gap and SpinDown_gap > min_gap: is_metal = False is_semimetal = True elif SpinUp_gap < min_gap and SpinDown_gap < min_gap: is_metal = True is_semimetal = False if is_metal: proc_str = "This Material Is a Metal." procs(proc_str, 0, sp='-->>') if not is_metal and is_semimetal: proc_str = "This Material Is a Semimetal." procs(proc_str, 0, sp='-->>') else: proc_str = "This Material Is a Semiconductor." procs(proc_str, 0, sp='-->>') proc_str = "Total magnetization is " + str(mag) procs(proc_str, 0, sp='-->>') if mag > min_mag: proc_str = "SpinUp : vbm=%f eV cbm=%f eV gap=%f eV" % ( cbm_vbm_up[1], cbm_vbm_up[0], SpinUp_gap) procs(proc_str, 0, sp='-->>') proc_str = "SpinDown: vbm=%f eV cbm=%f eV gap=%f eV" % ( cbm_vbm_down[1], cbm_vbm_down[0], SpinUp_gap) procs(proc_str, 0, sp='-->>') else: proc_str = "SpinUp : vbm=%f eV cbm=%f eV gap=%f eV" % ( cbm_vbm_up[1], cbm_vbm_up[0], SpinUp_gap) procs(proc_str, 0, sp='-->>') step_count += 1 filename = "BAND.dat" proc_str = "Writting Band Structure Data to " + filename + " File ..." procs(proc_str, step_count, sp='-->>') band_data_up = bands.bands[Spin.up] band_data_down = bands.bands[Spin.down] y_data_up = band_data_up.reshape( 1, band_data_up.shape[0] * band_data_up.shape[1])[0] - vsr.efermi #shift fermi level to 0 y_data_down = band_data_down.reshape( 1, band_data_down.shape[0] * band_data_down.shape[1])[0] - vsr.efermi #shift fermi level to 0 x_data = np.array(bands.distance * band_data_up.shape[0]) data = np.vstack((x_data, y_data_up, y_data_down)).T head_line = "#%(key1)+12s%(key2)+13s%(key3)+15s" % { 'key1': 'K-Distance', 'key2': 'UpEnergy(ev)', 'key3': 'DownEnergy(ev)' } write_col_data(filename, data, head_line, band_data_up.shape[1]) else: if vsr.parameters['LNONCOLLINEAR']: proc_str = "This Is a Non-Collinear Calculation." else: proc_str = "This Is a Non-Spin Calculation." procs(proc_str, 0, sp='-->>') cbm = bands.get_cbm()['energy'] vbm = bands.get_vbm()['energy'] gap = bands.get_band_gap()['energy'] if not bands.is_metal(): proc_str = "This Material Is a Semiconductor." procs(proc_str, 0, sp='-->>') proc_str = "vbm=%f eV cbm=%f eV gap=%f eV" % (vbm, cbm, gap) procs(proc_str, 0, sp='-->>') else: proc_str = "This Material Is a Metal." procs(proc_str, 0, sp='-->>') step_count += 1 filename3 = "BAND.dat" proc_str = "Writting Band Structure Data to " + filename3 + " File ..." procs(proc_str, step_count, sp='-->>') band_data = bands.bands[Spin.up] y_data = band_data.reshape( 1, band_data.shape[0] * band_data.shape[1])[0] - vsr.efermi #shift fermi level to 0 x_data = np.array(bands.distance * band_data.shape[0]) data = np.vstack((x_data, y_data)).T head_line = "#%(key1)+12s%(key2)+13s" % { 'key1': 'K-Distance', 'key2': 'Energy(ev)' } write_col_data(filename3, data, head_line, band_data.shape[1]) step_count += 1 bsp = BSPlotter(bands) filename4 = "HighSymmetricPoints.dat" proc_str = "Writting Label infomation to " + filename4 + " File ..." procs(proc_str, step_count, sp='-->>') head_line = "#%(key1)+12s%(key2)+12s%(key3)+12s" % { 'key1': 'index', 'key2': 'label', 'key3': 'position' } line = head_line + '\n' for i, label in enumerate(bsp.get_ticks()['label']): new_line = "%(key1)12d%(key2)+12s%(key3)12f\n" % { 'key1': i, 'key2': label, 'key3': bsp.get_ticks()['distance'][i] } line += new_line line += '\n' write_col_data(filename4, line, '', str_data=True) try: step_count += 1 filename5 = "BAND.png" proc_str = "Saving Plot to " + filename5 + " File ..." procs(proc_str, step_count, sp='-->>') bsp.save_plot(filename5, img_format="png") except: print("Figure output fails !!!")