def fix(self, err_jobdir, new_jobdir, settings): """ First attempt: Set IBRION = 2 Second attempt: Reduce POTIM to 0.1 Final attempt: Reduce POTIM to 0.01 """ continue_job(err_jobdir, new_jobdir, settings) if io.get_incar_tag("IBRION", jobdir=new_jobdir) != 2: print(" Set IBRION = 2") io.set_incar_tag({"IBRION": 2}, jobdir=new_jobdir) elif io.get_incar_tag("POTIM", jobdir=new_jobdir) > 0.1: print(" Set POTIM = 0.1") sys.stdout.flush() io.set_incar_tag({"POTIM": 0.1}, jobdir=new_jobdir) elif io.get_incar_tag("POTIM", jobdir=new_jobdir) > 0.01: print(" Set POTIM = 0.01") sys.stdout.flush() io.set_incar_tag({"POTIM": 0.01}, jobdir=new_jobdir)
def status(self): """ Determine the status of a vasp convergence series of runs. Individual runs in the series are in directories labeled "run.0", "run.1", etc. Returns a tuple: (status = "incomplete" or "complete" or "not_converging", task = continuedir or "relax" or "constant" or None) The first value is the status of the entire convergence. The second value is the current task, where 'continuedir' is the path to a vasp job directory that is not yet completed, "relax" indicates another volume convergence job is required, and "constant" that a constant volume run is required. """ # check if all complete if io.job_complete(self.finaldir): return ("complete", None) # check status of convergence runs self.update_rundir() # if not yet started if len(self.rundir) == 0: return ("incomplete", "setup") # if the latest run is complete: if io.job_complete(self.rundir[-1]): # if it is a final constant volume run if io.get_incar_tag("SYSTEM", self.rundir[-1]) != None: if io.get_incar_tag("SYSTEM", self.rundir[-1]).split()[-1].strip().lower( ) == "final": # if io.get_incar_tag("ISIF", self.rundir[-1]) == 2 and \ # io.get_incar_tag("NSW", self.rundir[-1]) == 0 and \ # io.get_incar_tag("ISMEAR", self.rundir[-1]) == -5: return ("complete", None) # elif constant volume run (but not the final one) if io.get_incar_tag("ISIF", self.rundir[-1]) in [0, 1, 2]: if io.get_incar_tag("NSW", self.rundir[-1]) == len( io.Oszicar(os.path.join(self.rundir[-1], "OSZICAR")).E): return ("incomplete", "relax" ) # static run hit NSW limit and so isn't "done" else: return ("incomplete", "constant") # elif convergence criteria met if self.converged(): return ("incomplete", "constant") # elif not converging, return 'not_converging' error if self.not_converging(): return ("not_converging", None) # else continue relaxing else: return ("incomplete", "relax") # elif not converging, return 'not_converging' error elif self.not_converging(): return ("not_converging", None) # else if the latest run is not complete, continue running it return ("incomplete", self.rundir[-1])
def status(self): """ Determine the status of a vasp relaxation series of runs. Individual runs in the series are in directories labeled "run.0", "run.1", etc. Returns a tuple: (status = "incomplete" or "complete" or "not_converging", task = "setup" or "new_run" or None) The first value is the status of the entire relaxation. The second value is the current task, where "setup" means to start running calculations in run.0 in the current folder "new_run" indicates another calculation job is required as present run is incomplete and need to start a next run. """ # check if all complete if io.job_complete(os.path.join(self.finaldir, "01")): return ("complete", None) # check status of relaxation runs self.update_rundir() # if not yet started if len(self.rundir) == 0: return ("incomplete", "setup") # check if all complete if io.job_complete(os.path.join(self.rundir[-1], "01")): # if it is a final constant volume run if io.get_incar_tag("SYSTEM", self.rundir[-1]) != None: if io.get_incar_tag("SYSTEM", self.rundir[-1]).split()[-1].strip().lower( ) == "final": return ("complete", None) # elif constant volume run (but not the final one) if io.get_incar_tag("ISIF", self.rundir[-1]) in [0, 1, 2]: if io.get_incar_tag("NSW", self.rundir[-1]) == len( io.Oszicar( os.path.join(self.rundir[-1], "01", "OSZICAR")).E): print "first " return ("incomplete", "new_run" ) # static run hit NSW limit and so isn't "done" else: return ("incomplete", "constant") # elif convergence criteria met if self.converged(): return ("incomplete", "constant") # elif not converging, return 'not_converging' error if self.not_converging(): return ("not_converging", None) # else continue relaxing else: return ("incomplete", "new_run") # elif not converging, return 'not_converging' error elif self.not_converging(): return ("not_converging", None) # else if the latest run is not complete, continue with a new run return ("incomplete", 'new_run')
def run(self): """ Perform a series of vasp jobs to relax a structure. Performs a series of vasp calculations until convergence is reached according to the criteria in 'status()'. Then performs a final constant volume run {"ISIF":2, "ISMEAR":-5, "NSW":0, "IBRION":-1}. """ print("Begin VASP convergence run") sys.stdout.flush() # get current status of the relaxation: (status, task) = self.status() print("\n++ status:", status, " next task:", task) sys.stdout.flush() while status == "incomplete": if task == "setup": self.add_rundir() self.setup(self.rundir[-1]) elif task == "relax": self.add_rundir() continue_job(self.rundir[-2], self.rundir[-1], self.settings) shutil.copyfile(os.path.join(self.propdir, "INCAR.base"), os.path.join(self.rundir[-1], "INCAR")) elif task == "constant": self.add_rundir() continue_job(self.rundir[-2], self.rundir[-1], self.settings) # set INCAR to ISIF = 2, ISMEAR = -5, NSW = 0, IBRION = -1 if (self.settings["final"] != None) and (os.path.isfile( os.path.join(self.propdir, self.settings["final"]))): new_values = io.Incar( os.path.join(self.propdir, self.settings["final"])).tags else: new_values = { "ISIF": 2, "ISMEAR": -5, "NSW": 0, "IBRION": -1 } # set INCAR system tag to denote 'final' if io.get_incar_tag("SYSTEM", self.rundir[-1]) is None: new_values["SYSTEM"] = "final" else: new_values["SYSTEM"] = io.get_incar_tag( "SYSTEM", self.rundir[-1]) + " final" io.set_incar_tag(new_values, self.rundir[-1]) print(" Set INCAR tags:", new_values, "\n") sys.stdout.flush() else: # probably hit walltime self.add_rundir() continue_job(self.rundir[-2], self.rundir[-1], self.settings) while True: # run vasp result = run(self.rundir[-1], npar=self.settings["npar"], ncore=self.settings["ncore"], command=self.settings["vasp_cmd"], ncpus=self.settings["ncpus"], kpar=self.settings["kpar"], err_types=self.settings["err_types"]) # if no errors, continue if result is None or self.not_converging(): # Check for actions that should be taken after the initial run if len(self.rundir) == 1: if self.settings["fine_ngx"]: outcarfile = os.path.join(self.rundir[-1], "OUTCAR") if not os.path.isfile(outcarfile): # This is an error but I'm not sure what to do about it pass else: init_outcar = io.Outcar(outcarfile) if not init_outcar.complete: # This is an error but I'm not sure what to do about it pass elif (init_outcar.ngx is None or init_outcar.ngy is None or init_outcar.ngz is None): # This is an error but I'm not sure what to do about it pass else: ng_tags = { "ngx": init_outcar.ngx * 2, "ngy": init_outcar.ngy * 2, "ngz": init_outcar.ngz * 2 } print(ng_tags) io.set_incar_tag(ng_tags, self.propdir, "INCAR.base") break # else, attempt to fix first error self.add_errdir() os.mkdir(self.rundir[-1]) # self.add_rundir() err = result.itervalues().next() print("\n++ status:", "error", " next task:", "fix_error") sys.stdout.flush() print("Attempting to fix error:", str(err)) err.fix(self.errdir[-1], self.rundir[-1], self.settings) print("") sys.stdout.flush() if (self.settings["backup"] != None) and len(self.rundir) > 1: print("Restoring from backups:") for my_file in self.settings["backup"]: if os.path.isfile( os.path.join(self.rundir[-2], my_file + "_BACKUP.gz")): f_in = gzip.open( os.path.join(self.rundir[-2], my_file + "_BACKUP.gz", 'rb')) f_out = open( os.path.join(self.rundir[-1], my_file, 'wb')) f_out.write(f_in.read()) f_in.close() f_out.close() print(my_file, " restored!") sys.stdout.flush() (status, task) = self.status() print("\n++ status:", status, " next task:", task) sys.stdout.flush() if status == "complete": if not os.path.isdir(self.finaldir): # mv final results to relax.final print("mv", os.path.basename(self.rundir[-1]), os.path.basename(self.finaldir)) sys.stdout.flush() os.rename(self.rundir[-1], self.finaldir) self.rundir.pop() complete_job(self.finaldir, self.settings) return (status, task)
def run(self): """ Perform a series of vasp jobs to run calculations. Performs a series of vasp calculations until convergence is reached according to the criteria in 'status()'. """ print("Begin VASP relaxation run") sys.stdout.flush() # get current status of the relaxation: (status, task) = self.status() print("\n++ status:", status, " next task:", task) sys.stdout.flush() while status == "incomplete": if task == "setup": self.add_rundir() self.setup(self.rundir[-1], self.settings) elif task == "new_run": self.add_rundir() # if "n_images" in settings then image CONTCARs will be copied casm.vasp.continue_job(self.rundir[-2], self.rundir[-1], self.settings) shutil.copyfile( os.path.join(self.calcdir, "INCAR.base"), os.path.join(self.rundir[-1], "INCAR")) ## should it be enforced?? elif task == "constant": self.add_rundir() # if "n_images" in settings then image CONTCARs will be copied casm.vasp.continue_job(self.rundir[-2], self.rundir[-1], self.settings) # set INCAR to ISIF = 2, ISMEAR = -5, NSW = 0, IBRION = -1 if (self.settings["final"] != None) and (os.path.isfile( os.path.join(self.calcdir, self.settings["final"]))): new_values = io.Incar( os.path.join(self.calcdir, self.settings["final"])).tags else: new_values = { "ISIF": 2, "ISMEAR": -5, "NSW": 0, "IBRION": -1 } # set INCAR system tag to denote 'final' if io.get_incar_tag("SYSTEM", self.rundir[-1]) is None: new_values["SYSTEM"] = "final" else: new_values["SYSTEM"] = io.get_incar_tag( "SYSTEM", self.rundir[-1]) + " final" io.set_incar_tag(new_values, self.rundir[-1]) print(" Set INCAR tags:", new_values, "\n") sys.stdout.flush() else: ## redundent self.add_rundir() casm.vasp.continue_job(self.rundir[-2], self.rundir[-1], self.settings) while True: # run vasp result = casm.vasp.run(self.rundir[-1], stdout="stdout", npar=self.settings["npar"], ncore=self.settings["ncore"], command=self.settings["vasp_cmd"], ncpus=self.settings["ncpus"], kpar=self.settings["kpar"], err_types=self.settings["err_types"], is_neb=True) # if no errors, continue if result is None or self.not_converging(): break # else, attempt to fix first error self.add_errdir() os.mkdir(self.rundir[-1]) # self.add_rundir() err = result.itervalues().next() print("\n++ status:", "error", " next task:", "fix_error") sys.stdout.flush() print("Attempting to fix error:", str(err)) err.fix(self.errdir[-1], self.rundir[-1], self.settings) print("") sys.stdout.flush() (status, task) = self.status() print("\n++ status:", status, " next task:", task) sys.stdout.flush() if status == "complete": if not os.path.isdir(self.finaldir): # mv final results to relax.final print("mv", os.path.basename(self.rundir[-1]), os.path.basename(self.finaldir)) sys.stdout.flush() os.rename(self.rundir[-1], self.finaldir) self.rundir.pop() casm.vasp.complete_job(self.finaldir, self.settings) return (status, task)