def surface_energy(args, console, table): perfect_oszicar = Oszicar(os.path.join(args.perfect, "OSZICAR")) defect_oszicar = Oszicar(os.path.join(args.defect, "OSZICAR")) defect_contcar = Poscar.from_file(os.path.join(args.defect, "CONTCAR")) matrix = defect_contcar.structure.lattice.matrix calc_area = lambda i, j: np.linalg.norm(np.cross(matrix[i], matrix[j])) if args.plane == "xy": area = calc_area(0, 1) elif args.plane == "xz": area = calc_area(0, 2) elif args.plane == "yz": area = calc_area(1, 2) else: console.print( "[bold red]ERROR:[/bold red] invalid option for argument `plane`") exit() defect_energy = defect_oszicar.final_energy perfect_energy = perfect_oszicar.final_energy res = (defect_energy - perfect_energy) / (area * 2.0) fmt = "{:.4f}" table.add_row("Perfect System Total Energy", fmt.format(perfect_energy), "eV") table.add_row("Defective System Total Energy", fmt.format(defect_energy), "eV") table.add_row("Surface Area", fmt.format(area), "A^2") table.add_row("Surface Formation Energy", fmt.format(res), "eV/A^2")
def test_init(self): filepath = os.path.join(test_dir, 'OSZICAR') oszicar = Oszicar(filepath) self.assertEqual(len(oszicar.electronic_steps), len(oszicar.ionic_steps)) self.assertEqual(len(oszicar.all_energies), 60) self.assertAlmostEqual(oszicar.final_energy, -526.63928)
def energies(): arr = dict() for i in range(0, 21): o = Oszicar(f'{i:02d}/OSZICAR') arr[i] = o.final_energy for k, v in arr.items(): if v <= min(arr.values()): print(k, v)
def get_all_oszicars(self, dirslist, root_path='./'): oszicar = [] if self.checkstart(dirslist) and self.checkend(dirslist): for i in range(0, len(dirslist)): path = os.path.join(root_path, dirslist[i], "OSZICAR") oszicar.append(Oszicar(path)) else: assert 0 == 1, "Check your start and end directories. OSZICAR may be missing" return oszicar
def check_electronic_convergence(path): ediff = get_incar_value(path, 'EDIFF') Os = Oszicar(opj(path, 'OSZICAR')) steps = Os.electronic_steps last = steps[-1][-1]['dE'] if abs(last) < ediff: return True else: return False
def get_mag_single(rundict): """get magnetization from the oszicar for a given rundict return np.nan if parsing failed """ try: mag_tot = Oszicar(os.path.join(rundict.job_folder, "OSZICAR")).ionic_steps[-1]["mag"] return mag_tot / len(rundict.structure.indices_from_symbol("Mn")) except Exception: print("could not define mag for", rundict.name_tag) return np.nan
def check(self): oszicar = Oszicar(self.output_filename) esteps = oszicar.electronic_steps # OSZICAR file can be empty, thus we need try-except here. try: max_energy = max([es["E"] for es in esteps[-1]]) # except (IndexError, KeyError): return False if max_energy > 10**6: return True
def magnetic_moment(oszicar=""): """ Obtain total orbital magnetic moment Magnetic moment info is found in both OSZICAR and OUTCAR We prefer OSZICAR values Args: oszicar: path to OSZICAR Returns: magmom: orbital magnetic moment in Bohr-magneton """ magmom = Oszicar(oszicar).ionic_steps[-1]["mag"] # magmom_out=out.total_mag #for outcar return magmom
def read_oszicar(self, path=None): """ Get Pymatgen OSZICAR object by reading "OSZICAR" file Parameters ---------- path : (str), optional Path of "OSZICAR" file. The default is None. If None "path" attribute is used. Returns ------- Oszicar object """ path = path if path else self.path return Oszicar(os.path.join(path, 'OSZICAR'))
def _get_step_limit_reached(self): """ Reads number of ionic steps from the OSZICAR file with Pymatgen and returns True if is equal to the step limit in INCAR file (NSW tag) """ limit_reached = True image_dirs = self.image_dirs for d in image_dirs: if d != image_dirs[0] and d != image_dirs[-1]: if not os.path.isfile(os.path.join( d, 'OSZICAR')): # check if OSZICAR files are present limit_reached = False else: n_steps = len( Oszicar(os.path.join(d, 'OSZICAR')).ionic_steps) nsw = Incar.from_file(op.join(self.path, 'INCAR'))[ 'NSW'] # check NSW from INCAR in parent directory if nsw != n_steps: limit_reached = False return limit_reached
distances = list() mag_moms = list() for site, mag in zip(structure, magnetization): if site.specie.symbol == "Co": mag_moms.append(mag) neighbors = structure.get_neighbors(site, radius) distances += [d for (_, d) in neighbors] distances = np.array(distances) ave_dist = distances.mean() std_dist = distances.std() mag_moms = np.array(mag_moms) ave_mag = mag_moms.mean() std_mag = mag_moms.std() osz = Oszicar(folder + "/OSZICAR") total_mag = osz.ionic_steps[-1]["mag"] lines += f"{ui:>8s} {si:>8s} " lines += f"{ave_mag:10.4f} {std_mag:10.4f} " lines += f"{total_mag:10.4f} " lines += f"{ave_dist:10.4f} {std_dist:10.4f} " lines += "".join([f"{d:6.3f}" for d in distances]) lines += "\n" with open("data.dat", "w") as f: f.write(lines)
help="enables memory usage comparison") parser.add_argument("--time", action="store_true", help="enables elapsed time comparison") args = parser.parse_args() if args.ignore is None: args.ignore = [] data = { "energy": {}, "memory": {}, "time": {}, } for dirname in os.listdir(): if not os.path.isdir(dirname): continue if dirname in args.ignore: continue oszicar = Oszicar(os.path.join(dirname, "OSZICAR")) data["energy"][dirname] = oszicar.final_energy outcar = Outcar(os.path.join(dirname, "OUTCAR")) data["memory"][dirname] = outcar.run_stats["Maximum memory used (kb)"] data["time"][dirname] = outcar.run_stats["Elapsed time (sec)"] if args.energy: plot_energy(data, console) if args.memory: plot_memory(data, console) if args.time: plot_time(data, console)
def run_job(mat=None,incar=None,kpoints=None,jobname='',copy_file=[]): """ Generic function to run a VASP job, error correction implemented using custodian package A jobname+.json file is produced after successful completion of the job A first_cust.py file is generated which is invoked using python command Args: mat: Poscar object with structure information incar: Incar object with control information kpoints: Kpoints object with mesh information jobname: a uniq name for a job-type, say MAIN-ELAST for elastic properties copy_file: copy file from previous runs, say CHGCAR for Non-SCF bandstructure calculations Returns: f_energy: final energy contcar: path to final relaxed structure """ #hostname=str(socket.gethostname()) poscar_list=[(mat)] cwd=str(os.getcwd()) job_name=str(mat.comment) job_dir=str(jobname) run_file = str(os.getcwd())+str('/')+str(jobname)+str('.json') run_dir = str(os.getcwd())+str('/')+str(jobname) if mat.comment.startswith('Surf'): [a,b,c]=kpoints.kpts[0] kpoints.kpts=[[a,b,1]] try: pol=check_polar(mat.structure) if pol==True: ase_atoms = AseAtomsAdaptor().get_atoms(mat.structure) COM=ase_atoms.get_center_of_mass(scaled=True) print ("COM=",COM) print ('Found polar surface, will be setting dipole corrections') incar.update({"LDIPOL": '.TRUE.',"IDIPOL":3,"ISYM": 0,"DIPOL":str(COM[0])+str(" ")+str(COM[2])+str(" ")+str(COM[2])}) print ("Polar surface encountered in run_job",mat.comment) except: pass wait=False json_file=str(jobname)+str('.json') print ('json should be here=',str(os.getcwd())+str('/')+str(json_file)) #print ('json should be=',json_file,run_file,os.getcwd()) if os.path.exists(str(os.getcwd())+str('/')+str(json_file)): try: data_cal=loadfn(str(os.getcwd())+str('/')+str(json_file),cls=MontyDecoder) tmp_outcar=str(os.getcwd())+str('/')+str(json_file.split('.json')[0])+str('/OUTCAR') print ('outcar is',tmp_outcar) wait=main_outcar(tmp_outcar) #True print ('outcar status',wait) if wait==True: f_energy=data_cal[0]['final_energy'] contcar=str(os.getcwd())+str('/')+str(json_file.split('.json')[0])+str('/CONTCAR') return f_energy,contcar except: pass while wait==False: print ("Setting up POTCAR") with open(pot_yaml, 'r') as f: doc = yaml.load(f) pots=doc['POTCAR'] new_symb=[] for el in mat.site_symbols: new_symb.append(pots[el]) #potcar = Potcar(symbols=new_symb,functional=functional) try: potcar = Potcar(symbols=new_symb,functional=functional) except: print ('JARVIS-ERROR: Could not set POTCAR, check POTCAR yaml file and VASP_PSP_DIR') pass if not os.path.exists(run_dir): print ('Starting new job') os.makedirs(run_dir) os.chdir(run_dir) incar.write_file("INCAR") potcar.write_file("POTCAR") kpoints.write_file("KPOINTS") mat.write_file("POSCAR") for i in copy_file: print ('copying',i) shutil.copy2(i,'./') #f=open('job.out','w') cmd=str('python first_cust.py >out_dat')+'\n' cust_file=open("first_cust.py","w") cline=str('from pymatgen.io.vasp.inputs import Incar, Poscar, VaspInput,Potcar, Kpoints')+'\n' cust_file.write(cline) cline=str('import os,shutil')+'\n' cust_file.write(cline) cline=str('from custodian.vasp.jobs import VaspJob')+'\n' cust_file.write(cline) cline=str('from custodian.vasp.handlers import VaspErrorHandler, UnconvergedErrorHandler,MeshSymmetryErrorHandler, NonConvergingErrorHandler, PotimErrorHandler')+'\n' cust_file.write(cline) cline=str('from custodian.vasp.validators import VaspFilesValidator,VasprunXMLValidator')+'\n' cust_file.write(cline) cline=str('from custodian.custodian import Custodian')+'\n' cust_file.write(cline) cline=str('inc=Incar.from_file("INCAR")')+'\n' cust_file.write(cline) cline=str('pot=Potcar.from_file("POTCAR")')+'\n' cust_file.write(cline) cline=str('pos=Poscar.from_file("POSCAR")')+'\n' cust_file.write(cline) cline=str('kp=Kpoints.from_file("KPOINTS")')+'\n' cust_file.write(cline) cline=str("shutil.copy2('")+vdw_dat+str("','./')")+'\n' cust_file.write(cline) cline=str('vinput = VaspInput.from_directory(".")')+'\n' cust_file.write(cline) cline=str("job=VaspJob(['mpirun', '")+str(main_exe)+str("'], final=False, backup=False)")+'\n' if mat.comment.startswith('Surf'): cline=str("job=VaspJob(['mpirun', '")+str(surf_exe)+str("'], final=False, backup=False)")+'\n' if 'SOC' in jobname: cline=str("job=VaspJob(['mpirun', '")+str(soc_exe)+str("'], final=False, backup=False)")+'\n' cust_file.write(cline) cline=str('handlers = [VaspErrorHandler(), MeshSymmetryErrorHandler(),UnconvergedErrorHandler(), NonConvergingErrorHandler(),PotimErrorHandler()]')+'\n' cust_file.write(cline) cline=str('validators = [VasprunXMLValidator()]')+'\n' #cline=str('validators = [VaspFilesValidator()]')+'\n' cust_file.write(cline) cline=str('c = Custodian(handlers, [job],max_errors=5,validators=validators)')+'\n' cust_file.write(cline) cline=str('c.run()')+'\n' cust_file.write(cline) cust_file.close() print ("I AM HERE 2") os.system(cmd) if os.path.isfile('OUTCAR'): try: wait=main_outcar('OUTCAR') #Vasprun("vasprun.xml").converged except: pass print ("End of the first loop",os.getcwd(),wait) else : print ('Jobs seens to have started before') os.chdir(run_dir) wait=False if os.path.isfile('OUTCAR'): try: wait=main_outcar('OUTCAR') #Vasprun("vasprun.xml").converged #wait=Vasprun("vasprun.xml").converged except: pass print ("Tried to find OUTCAR, wait is=",wait) if wait==False: incar.write_file("INCAR") kpoints.write_file("KPOINTS") mat.write_file("POSCAR") try: potcar.write_file("POTCAR") print ('FOUND OLD CONTCAR in', os.getcwd()) old_contcar=Poscar.from_file('CONTCAR') #old_contcar.write_file('POSCAR') copy_cmd=str('cp CONTCAR POSCAR') print ('copy_cmd=',copy_cmd) if 'ELAST' not in jobname: #Because in ELASTIC calculations structures are deformed os.system(copy_cmd) #time.sleep(3) except: pass for i in copy_file: print ('copying',i) shutil.copy2(i,'./') cmd=str('python first_cust.py >out_dat')+'\n' cust_file=open("first_cust.py","w") cline=str('from pymatgen.io.vasp.inputs import Incar, Poscar, VaspInput,Potcar, Kpoints')+'\n' cust_file.write(cline) cline=str('import os,shutil')+'\n' cust_file.write(cline) cline=str('from custodian.vasp.jobs import VaspJob')+'\n' cust_file.write(cline) cline=str('from custodian.vasp.handlers import VaspErrorHandler, UnconvergedErrorHandler,MeshSymmetryErrorHandler, NonConvergingErrorHandler, PotimErrorHandler')+'\n' cust_file.write(cline) cline=str('from custodian.vasp.validators import VaspFilesValidator,VasprunXMLValidator')+'\n' cust_file.write(cline) cline=str('from custodian.custodian import Custodian')+'\n' cust_file.write(cline) cline=str('inc=Incar.from_file("INCAR")')+'\n' cust_file.write(cline) cline=str('pot=Potcar.from_file("POTCAR")')+'\n' cust_file.write(cline) cline=str('pos=Poscar.from_file("POSCAR")')+'\n' cust_file.write(cline) cline=str('kp=Kpoints.from_file("KPOINTS")')+'\n' cust_file.write(cline) cline=str("shutil.copy2('")+vdw_dat+str("','./')")+'\n' cust_file.write(cline) cline=str('vinput = VaspInput.from_directory(".")')+'\n' cust_file.write(cline) cline=str("job=VaspJob(['mpirun', '")+str(main_exe)+str("'], final=False, backup=False)")+'\n' if mat.comment.startswith('Surf'): cline=str("job=VaspJob(['mpirun', '")+str(surf_exe)+str("'], final=False, backup=False)")+'\n' if 'SOC' in jobname: cline=str("job=VaspJob(['mpirun', '")+str(soc_exe)+str("'], final=False, backup=False)")+'\n' cust_file.write(cline) cline=str('handlers = [VaspErrorHandler(), MeshSymmetryErrorHandler(),UnconvergedErrorHandler(), NonConvergingErrorHandler(),PotimErrorHandler()]')+'\n' cust_file.write(cline) #cline=str('validators = [VaspFilesValidator()]')+'\n' cline=str('validators = [VasprunXMLValidator()]')+'\n' cust_file.write(cline) cline=str('c = Custodian(handlers, [job],max_errors=5,validators=validators)')+'\n' cust_file.write(cline) cline=str('c.run()')+'\n' cust_file.write(cline) cust_file.close() os.system(cmd) if os.path.isfile('OUTCAR'): try: wait=main_outcar('OUTCAR') #Vasprun("vasprun.xml").converged #wait=Vasprun("vasprun.xml").converged except: pass f_energy='na' enp='na' contcar=str(os.getcwd())+str('/')+str('CONTCAR') final_str=Structure.from_file(contcar) try: oszicar = Oszicar("OSZICAR") f_energy=float(oszicar.final_energy) enp=float(oszicar.final_energy)/float(final_str.composition.num_atoms) except: print ('Error in OSZICAR file during re-run jpb') pass natoms=final_str.composition.num_atoms os.chdir('../') if wait==True: data_cal=[] data_cal.append({'jobname':jobname,'poscar_initial':mat.as_dict(),'poscar_final':final_str.as_dict(),'incar':incar.as_dict(),'kpoints':kpoints.as_dict(),'final_energy':(f_energy),'contcar':final_str.as_dict()}) json_file=str(jobname)+str('.json') f_json=open(json_file,'w') f_json.write(json.dumps(data_cal,indent=4,cls=MontyEncoder)) f_json.close() print ('Wrote json file',contcar) return f_energy,contcar
def assimilate(self, path): """ Assimilate data in a directory path into a ComputedEntry object. Args: path: directory path Returns: ComputedEntry """ files = os.listdir(path) try: files_to_parse = {} if "relax1" in files and "relax2" in files: for filename in ("INCAR", "POTCAR", "POSCAR"): search_str = os.path.join(path, "relax1", filename + "*") files_to_parse[filename] = glob.glob(search_str)[0] for filename in ("CONTCAR", "OSZICAR"): search_str = os.path.join(path, "relax2", filename + "*") files_to_parse[filename] = glob.glob(search_str)[-1] else: for filename in ( "INCAR", "POTCAR", "CONTCAR", "OSZICAR", "POSCAR", "DYNMAT" ): files = sorted(glob.glob(os.path.join(path, filename + "*"))) if len(files) < 1: continue if len(files) == 1 or filename == "INCAR" or \ filename == "POTCAR" or filename == "DYNMAT": files_to_parse[filename] = files[-1] \ if filename == "POTCAR" else files[0] elif len(files) > 1: # Since multiple files are ambiguous, we will always # use the first one for POSCAR and the last one # alphabetically for CONTCAR and OSZICAR. if filename == "POSCAR": files_to_parse[filename] = files[0] else: files_to_parse[filename] = files[-1] warnings.warn( "%d files found. %s is being parsed." % (len(files), files_to_parse[filename])) poscar, contcar, incar, potcar, oszicar, dynmat = [None] * 6 if 'POSCAR' in files_to_parse: poscar = Poscar.from_file(files_to_parse["POSCAR"]) if 'CONTCAR' in files_to_parse: contcar = Poscar.from_file(files_to_parse["CONTCAR"]) if 'INCAR' in files_to_parse: incar = Incar.from_file(files_to_parse["INCAR"]) if 'POTCAR' in files_to_parse: potcar = Potcar.from_file(files_to_parse["POTCAR"]) if 'OSZICAR' in files_to_parse: oszicar = Oszicar(files_to_parse["OSZICAR"]) if 'DYNMAT' in files_to_parse: dynmat = Dynmat(files_to_parse["DYNMAT"]) param = {"hubbards": {}} if poscar is not None and incar is not None and "LDAUU" in incar: param["hubbards"] = dict(zip(poscar.site_symbols, incar["LDAUU"])) param["is_hubbard"] = (incar.get("LDAU", True) and sum(param["hubbards"].values()) > 0) \ if incar is not None else False param["run_type"] = None param["potcar_spec"] = potcar.spec if potcar is not None else None energy = oszicar.final_energy if oszicar is not None else Vasprun.final_energy structure = contcar.structure if contcar is not None \ else poscar.structure initial_vol = poscar.structure.volume if poscar is not None else \ None final_vol = contcar.structure.volume if contcar is not None else \ None delta_volume = None if initial_vol is not None and final_vol is not None: delta_volume = (final_vol / initial_vol - 1) data = {"filename": path, "delta_volume": delta_volume} if dynmat is not None: data['phonon_frequencies'] = dynmat.get_phonon_frequencies() if self._inc_structure: entry = ComputedStructureEntry( structure, energy, parameters=param, data=data ) else: entry = ComputedEntry( structure.composition, energy, parameters=param, data=data ) return entry except Exception as ex: logger.debug("error in {}: {}".format(path, ex)) return None
def get_O2_release_enthalpy(rundict): """ compare energies of normal and O deficient runs check the existence of the O2 deficient vasp result in the run folder get the run with the lowest energy compare energies of normal and O deficient runs (w/ and wo/ WdW correction) return H without VdW correction""" run_list = [] # check the existence of the O2 deficient vasp result in the run folder o_deficient_list = [ os.path.join(rundict.job_folder, f) for f in os.listdir(rundict.job_folder) if f.startswith("O_deficient") ] if len(o_deficient_list) == 0: print("no O_deficient folder") return (None) print(o_deficient_list) for project_folder in o_deficient_list: for job_folder in [ os.path.join(project_folder, f) for f in os.listdir(project_folder) ]: # print(job_folder) run = read.collect_single_folder(job_folder) if run.status >= 3: run_list.append(run) if len(run_list) == 0: print("no O_deficient converged run") return (None) # print("valid run lst {}".format(run_list)) # get the run with the lowest energy run_list = sorted(run_list, key=lambda x: x.energy) o_def_rundict = run_list[0] # ============= IN CASE OF VDW CORRECTION ========================= E_plus_vdw_O_def = o_def_rundict.energy E_no_vdw_O_def = Oszicar(o_def_rundict.job_folder + "/OSZICAR").electronic_steps[-1][-1]["E"] # print("Energies 0 deficient : base {:.4f} // VDW {:.4f} (corr : {:.6f})".format( # E_no_vdw_O_def, E_plus_vdw_O_def, E_plus_vdw_O_def - E_no_vdw_O_def ) # ) # nbO_final = len(o_def_vasprun.final_structure.indices_from_symbol("O")) E_plus_vdw_normal = rundict.energy E_no_vdw_normal = Oszicar(rundict.job_folder + "/OSZICAR").electronic_steps[-1][-1]["E"] # print("Energies : base {} // VDW {} (corr : {})".format( # E_no_vdw_normal, E_plus_vdw_normal, E_plus_vdw_normal - E_no_vdw_normal # ) ) # nbO_init = len(runDict['structure'].indices_from_symbol("O")) # H = E(normal) - E(O_deficient) - 1/2 E(O2) # runDict['ediff'] = runDict.energy_per_fu / runDict["nb_cell"] # eV -9.8897568 (no Wdv energy from dft O2 ) + 1.36 (ceder correction) EO2 = -8.52 print("{}\n".format(rundict.name_tag)) for VDW, E_normal, E_O_def in \ [("with VdW correction", E_plus_vdw_normal, E_plus_vdw_O_def), ("without VdW correction", E_no_vdw_normal, E_no_vdw_O_def)]: H = E_O_def + 0.5 * EO2 - E_normal # Normalized By atom of oxygen extracted print( "{} \nE_O_def + 1/2.EO2 - E_normal = H \n{:.5f} + {:.5f} - 1/2.{:.5f} = {:.5f} " .format(VDW, E_O_def, EO2, E_normal, H)) # H = 2*H # normalized by O2 molecules # return H without VdW correction return H
oszicar = [f for f in os.listdir("./") if "OSZICAR_" in f] oszicar.sort(key=lambda x: int(x.strip("OSZICAR_"))) # CONTCAR files contcar = [f for f in os.listdir("./") if "CONTCAR_" in f] contcar.sort(key=lambda x: int(x.strip("CONTCAR_"))) save = 0.0 # boucle sur les points k for cont, osz in zip(contcar, oszicar): i = int(cont.strip("CONTCAR_")) # chargement de la structure p = Poscar.from_file(cont) a, b, c = p.structure.lattice.abc alpha, beta, gamma = p.structure.lattice.angles # lecture du fichier OSZICAR o = Oszicar(osz) elast = o.final_energy singlePoint = o.ionic_steps[0]["E0"] # affiche les resultats print("%4d %7.3f %7.3f %7.3f %6.1f %6.1f %6.1f %12.7f %12.7f %12.3f" % (i, a, b, c, alpha, beta, gamma, elast, singlePoint, (singlePoint - save) * 1000.)) # save energy to compute convergence save = singlePoint
def assimilate(self, path): """ Assimilate data in a directory path into a ComputedEntry object. Args: path: directory path Returns: ComputedEntry """ files = os.listdir(path) try: files_to_parse = {} filenames = {"INCAR", "POTCAR", "CONTCAR", "OSZICAR", "POSCAR", "DYNMAT"} if "relax1" in files and "relax2" in files: for filename in ("INCAR", "POTCAR", "POSCAR"): search_str = os.path.join(path, "relax1", filename + "*") files_to_parse[filename] = glob.glob(search_str)[0] for filename in ("CONTCAR", "OSZICAR"): search_str = os.path.join(path, "relax2", filename + "*") files_to_parse[filename] = glob.glob(search_str)[-1] else: for filename in filenames: files = sorted(glob.glob(os.path.join(path, filename + "*"))) if len(files) == 1 or filename in ("INCAR", "POTCAR"): files_to_parse[filename] = files[0] elif len(files) == 1 and filename == "DYNMAT": files_to_parse[filename] = files[0] elif len(files) > 1: # Since multiple files are ambiguous, we will always # use the first one for POSCAR and the last one # alphabetically for CONTCAR and OSZICAR. files_to_parse[filename] = files[0] if filename == "POSCAR" else files[-1] warnings.warn("%d files found. %s is being parsed." % (len(files), files_to_parse[filename])) if not set(files_to_parse.keys()).issuperset({"INCAR", "POTCAR", "CONTCAR", "OSZICAR", "POSCAR"}): raise ValueError( "Unable to parse %s as not all necessary files are present! " "SimpleVaspToComputedEntryDrone requires INCAR, POTCAR, CONTCAR, OSZICAR, POSCAR " "to be present. Only %s detected" % str(files_to_parse.keys()) ) poscar = Poscar.from_file(files_to_parse["POSCAR"]) contcar = Poscar.from_file(files_to_parse["CONTCAR"]) incar = Incar.from_file(files_to_parse["INCAR"]) potcar = Potcar.from_file(files_to_parse["POTCAR"]) oszicar = Oszicar(files_to_parse["OSZICAR"]) param = {"hubbards": {}} if "LDAUU" in incar: param["hubbards"] = dict(zip(poscar.site_symbols, incar["LDAUU"])) param["is_hubbard"] = incar.get("LDAU", True) and sum(param["hubbards"].values()) > 0 param["run_type"] = None param["potcar_spec"] = potcar.spec energy = oszicar.final_energy structure = contcar.structure initial_vol = poscar.structure.volume final_vol = contcar.structure.volume delta_volume = final_vol / initial_vol - 1 data = {"filename": path, "delta_volume": delta_volume} if "DYNMAT" in files_to_parse: dynmat = Dynmat(files_to_parse["DYNMAT"]) data["phonon_frequencies"] = dynmat.get_phonon_frequencies() if self._inc_structure: return ComputedStructureEntry(structure, energy, parameters=param, data=data) return ComputedEntry(structure.composition, energy, parameters=param, data=data) except Exception as ex: logger.debug(f"error in {path}: {ex}") return None
# read from CONTCAR using pymatgen from pymatgen.core import Structure opt_struct = Structure.from_file(dir_name + '/' + "CONTCAR") spg_symbol_opt = SpacegroupAnalyzer( opt_struct, symprec=.1).get_space_group_symbol() spg_number_opt = SpacegroupAnalyzer( opt_struct, symprec=.1).get_space_group_number() # update the Spg_num_opt column in df_100 using spg_number_opt df_100.loc[df_100['id'] == cid, 'Spg_num_opt'] = spg_number_opt df_100.loc[df_100['id'] == cid, 'Spg_sym_opt'] = spg_symbol_opt # how many atoms in the opt_struct n_atoms = opt_struct.num_sites # print(spg_symbol_opt) # read the final energy E0 from OSZICAR if OSZICAR exists using pymatgen, otherwise raise error try: oszicar = Oszicar(dir_name + '/' + "OSZICAR") E0 = oszicar.final_energy E0_per_atom = round(E0 / n_atoms, 8) # enthalpy eV normalized to per atom # save E0_per_atom in the column E_eV_atom of df_100 df_100.loc[df_100['id'] == cid, 'E_eV_atom'] = round(E0_per_atom, 8) except: raise FileNotFoundError('OSZICAR does not exist in the folder ' + dir_name) # read the final EENTRO (i.e. free energy TOTEN) from OUTCAR using pymatgen if OUTCAR exists, # otherwise raise error try: outcar = Outcar(dir_name + '/' + "OUTCAR") EENTRO = outcar.data[
def parse_md_data(self, input): """ Parses the md run data from a directory. Args: input: directory for the md run containing a vasprun.xml and OSZICAR file Returns: None """ if os.path.isfile(os.path.join(input, 'vasprun.xml.gz')): v = Vasprun(os.path.join(input, 'vasprun.xml.gz')) elif os.path.isfile(os.path.join(input, 'vasprun.xml')): v = Vasprun(os.path.join(input, 'vasprun.xml')) else: raise FileNotFoundError if os.path.isfile(os.path.join(input, 'OSZICAR.gz')): o = Oszicar(os.path.join(input, 'OSZICAR.gz')) elif os.path.isfile(os.path.join(input, 'OSZICAR')): o = Oszicar(os.path.join(input, 'OSZICAR')) else: raise FileNotFoundError self.composition = v.structures[0].composition self.volume = v.structures[0].volume nsteps = v.nionic_steps self.nsteps += nsteps if self.time: starttime = self.time[-1] self.time.extend( np.add( np.arange(0, nsteps) * v.parameters['POTIM'], starttime)) else: self.time.extend(np.arange(0, nsteps) * v.parameters['POTIM']) pressure = [] etot = [] ekin = [] temp = [] for i, step in enumerate(o.ionic_steps): temp.append(step['T']) for i, step in enumerate(v.ionic_steps): ekin.append(step['kinetic']) etot.append(step['total']) stress = step['stress'] kinP = (2 / 3) * ekin[i] pressure.append((1 / 3) * np.trace(stress) + kinP) self.md_data['pressure'].extend(pressure) self.md_data['etot'].extend(etot) self.md_data['ekin'].extend(ekin) self.md_data['temp'].extend(temp) self.md_acfs['pressure'] = autocorrelation(self.md_data['pressure'], normalize=True) self.md_acfs['pressure'] = autocorrelation(self.md_data['pressure'], normalize=True) self.md_acfs['pressure'] = autocorrelation(self.md_data['pressure'], normalize=True) self.md_acfs['pressure'] = autocorrelation(self.md_data['pressure'], normalize=True)
def assimilate(self, path): files = os.listdir(path) try: files_to_parse = {} if "relax1" in files and "relax2" in files: for filename in ("INCAR", "POTCAR", "POSCAR"): search_str = os.path.join(path, "relax1", filename + "*") files_to_parse[filename] = glob.glob(search_str)[0] for filename in ("CONTCAR", "OSZICAR"): search_str = os.path.join(path, "relax2", filename + "*") files_to_parse[filename] = glob.glob(search_str)[-1] else: for filename in ( "INCAR", "POTCAR", "CONTCAR", "OSZICAR", "POSCAR", "DYNMAT" ): files = glob.glob(os.path.join(path, filename + "*")) if len(files) < 1: continue if len(files) == 1 or filename == "INCAR" or \ filename == "POTCAR" or filename == "DYNMAT": files_to_parse[filename] = files[-1]\ if filename == "POTCAR" else files[0] elif len(files) > 1: """ This is a bit confusing, since there maybe be multiple steps. By default, assimilate will try to find a file simply named filename, filename.bz2, or filename.gz. Failing which it will try to get a relax2 from a custodian double relaxation style run if possible. Or else, a random file is chosen. """ for fname in files: if fnmatch.fnmatch(os.path.basename(fname), r"{}(\.gz|\.bz2)*" .format(filename)): files_to_parse[filename] = fname break if fname == "POSCAR" and \ re.search(r"relax1", fname): files_to_parse[filename] = fname break if (fname in ("CONTCAR", "OSZICAR") and re.search(r"relax2", fname)): files_to_parse[filename] = fname break files_to_parse[filename] = fname poscar, contcar, incar, potcar, oszicar, dynmat = [None]*6 if 'POSCAR' in files_to_parse: poscar = Poscar.from_file(files_to_parse["POSCAR"]) if 'CONTCAR' in files_to_parse: contcar = Poscar.from_file(files_to_parse["CONTCAR"]) if 'INCAR' in files_to_parse: incar = Incar.from_file(files_to_parse["INCAR"]) if 'POTCAR' in files_to_parse: potcar = Potcar.from_file(files_to_parse["POTCAR"]) if 'OSZICAR' in files_to_parse: oszicar = Oszicar(files_to_parse["OSZICAR"]) if 'DYNMAT' in files_to_parse: dynmat = Dynmat(files_to_parse["DYNMAT"]) param = {"hubbards":{}} if poscar is not None and incar is not None and "LDAUU" in incar: param["hubbards"] = dict(zip(poscar.site_symbols, incar["LDAUU"])) param["is_hubbard"] = ( incar.get("LDAU", False) and sum(param["hubbards"].values()) > 0 ) if incar is not None else False param["run_type"] = None if incar is not None: param["run_type"] = "GGA+U" if param["is_hubbard"] else "GGA" param["history"] = _get_transformation_history(path) param["potcar_spec"] = potcar.spec if potcar is not None else None energy = oszicar.final_energy if oszicar is not None else 1e10 structure = contcar.structure if contcar is not None\ else poscar.structure initial_vol = poscar.structure.volume if poscar is not None else \ None final_vol = contcar.structure.volume if contcar is not None else \ None delta_volume = None if initial_vol is not None and final_vol is not None: delta_volume = (final_vol / initial_vol - 1) data = {"filename": path, "delta_volume": delta_volume} if dynmat is not None: data['phonon_frequencies'] = dynmat.get_phonon_frequencies() if self._inc_structure: entry = ComputedStructureEntry( structure, energy, parameters=param, data=data ) else: entry = ComputedEntry( structure.composition, energy, parameters=param, data=data ) return entry except Exception as ex: logger.debug("error in {}: {}".format(path, ex)) return None
def run_task(self, fw_spec): try: OSZICAR = Oszicar('OSZICAR') except VaspParserError as err: print(err) else: if len(OSZICAR.ionic_steps) == 1: new_name = "{}-{}".format(self.get("name"), "final") calc_locs = list(fw_spec.get("calc_locs", [])) calc_locs.append({ "name": new_name, "filesystem": env_chk(self.get('filesystem', None), fw_spec), "path": self.get("path", os.getcwd()) }) return FWAction(mod_spec=[{ '_push_all': { 'calc_locs': calc_locs } }]) else: stru = Structure.from_file("CONTCAR") kpoint_set = Generate_kpoints(stru, 0.03) if self.get("vasp_input_set", None) is not None: vasp_input_set_temp = self.get("vasp_input_set") tempdict = dict(vasp_input_set_temp.incar.items()) vasp_input_set = MPRelaxSet( stru, user_incar_settings=tempdict, user_kpoints_settings=kpoint_set) else: vasp_input_set_params = self.get("vasp_input_set_params") vasp_input_set = MPRelaxSet( stru, user_incar_settings=vasp_input_set_params, user_kpoints_settings=kpoint_set) vasp_cmd = self.get("vasp_cmd") db_file = self.get("db_file") name = self.get("name") count = self.get("count") kwargs = self.get("kwargs", {}) calc_locs = list(fw_spec.get("calc_locs", [])) calc_locs.append({ "name": "{}-{}".format(name, str(count)), "filesystem": env_chk(self.get('filesystem', None), fw_spec), "path": self.get("path", os.getcwd()) }) count = count + 1 from aicon.myfireworks import MyOptimizeFW new_fw = MyOptimizeFW(structure=stru, vasp_input_set=vasp_input_set, vasp_cmd=vasp_cmd, db_file=db_file, name=name, count=count, **kwargs) return FWAction(mod_spec=[{ '_push_all': { 'calc_locs': calc_locs } }], detours=new_fw)
def correct(self): backup(orig_handlers.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 } } }) # ----- added --------------------------------------------------- if "plane_wave_coeff" in self.errors: actions.append({ "file": "WAVECAR", "action": { "_file_delete": { 'mode': "actual" } } }) actions.append({ "file": "CHGCAR", "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. If a static run # try turning off symmetry. 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 } } }) elif vi["INCAR"].get("NSW", 0) == 0 \ or vi["INCAR"].get("ISIF", 0) in range(3): actions.append({ "dict": "INCAR", "action": { "_set": { "ISYM": 0 } } }) 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. if vi["INCAR"].get("ICHARG", 0) < 10: actions.append({ "file": "CHGCAR", "action": { "_file_delete": { 'mode': "actual" } } }) actions.append({ "file": "WAVECAR", "action": { "_file_delete": { 'mode': "actual" } } }) if self.errors.intersection(["subspacematrix"]): if self.error_count["subspacematrix"] == 0: actions.append({ "dict": "INCAR", "action": { "_set": { "LREAL": False } } }) else: actions.append({ "dict": "INCAR", "action": { "_set": { "PREC": "Accurate" } } }) self.error_count["subspacematrix"] += 1 if self.errors.intersection(["rspher", "real_optlay", "nicht_konv"]): s = vi["POSCAR"].structure if len(s) < self.natoms_large_cell: actions.append({ "dict": "INCAR", "action": { "_set": { "LREAL": False } } }) else: # for large supercell, try an in-between option LREAL = True # prior to LREAL = False if self.error_count['real_optlay'] == 0: # use real space projectors generated by pot actions.append({ "dict": "INCAR", "action": { "_set": { "LREAL": True } } }) elif self.error_count['real_optlay'] == 1: actions.append({ "dict": "INCAR", "action": { "_set": { "LREAL": False } } }) self.error_count['real_optlay'] += 1 if self.errors.intersection(["tetirr", "incorrect_shift"]): # --Modified------------------------------------------------------ if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst or \ vi["KPOINTS"].kpts_shift != [0.0, 0.0, 0.0]: actions.append({ "dict": "KPOINTS", "action": { "_set": { "generation_style": "Gamma", "usershift": [0.0, 0.0, 0.0] } } }) # ----------------------------------------------------------- if "rot_matrix" in self.errors: # --Modified------------------------------------------------------ if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst or \ vi["KPOINTS"].kpts_shift != [0.0, 0.0, 0.0]: actions.append({ "dict": "KPOINTS", "action": { "_set": { "generation_style": "Gamma", "usershift": [0.0, 0.0, 0.0] } } }) # ----------------------------------------------------------- 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: # Modified so as not to use IBRION=1 as it does not show the # eigenvalues in vasprun.xml >>>>>>>>>>>> actions.append({ "dict": "INCAR", "action": { "_set": { "ADDGRID": True } } }) actions.append({ "file": "CONTCAR", "action": { "_file_copy": { "dest": "POSCAR" } } }) # actions.append({"dict": "INCAR", # "action": {"_set": {"IBRION": 1}}}) # actions.append({"file": "CONTCAR", # "action": {"_file_copy": {"dest": "POSCAR"}}}) # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 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 } } }) if vi["INCAR"].get("ICHARG", 0) < 10: actions.append({ "file": "CHGCAR", "action": { "_file_delete": { 'mode': "actual" } } }) actions.append({ "file": "WAVECAR", "action": { "_file_delete": { 'mode': "actual" } } }) if "edddav" in self.errors: if vi["INCAR"].get("ICHARG", 0) < 10: actions.append({ "file": "CHGCAR", "action": { "_file_delete": { 'mode': "actual" } } }) actions.append({ "dict": "INCAR", "action": { "_set": { "ALGO": "All" } } }) if "grad_not_orth" in self.errors: if vi["INCAR"].get("ISMEAR", 1) < 0: actions.append({ "dict": "INCAR", "action": { "_set": { "ISMEAR": "0" } } }) if "zheev" in self.errors: if vi["INCAR"].get("ALGO", "Fast").lower() != "exact": actions.append({ "dict": "INCAR", "action": { "_set": { "ALGO": "Exact" } } }) if "elf_kpar" in self.errors: actions.append({"dict": "INCAR", "action": {"_set": {"KPAR": 1}}}) if "rhosyg" in self.errors: if vi["INCAR"].get("SYMPREC", 1e-4) == 1e-4: actions.append({ "dict": "INCAR", "action": { "_set": { "ISYM": 0 } } }) actions.append({ "dict": "INCAR", "action": { "_set": { "SYMPREC": 1e-4 } } }) if "posmap" in self.errors: actions.append({ "dict": "INCAR", "action": { "_set": { "SYMPREC": 1e-6 } } }) if "point_group" in self.errors: actions.append({"dict": "INCAR", "action": {"_set": {"ISYM": 0}}}) ViseVaspModder(vi=vi).apply_actions(actions) return {"errors": list(self.errors), "actions": actions}