def converged(self): """Check if configuration is relaxed. This is called when self.rundir[-1] is complete and not a constant volume job. Convergence criteria is: at least 2 relaxation jobs are complete, and: 1) the last job completed with <= 3 ionic steps or 2) the last two jobs had final E0 differ by less than self.settings["nrg_convergence"] """ outfilename = self.settings["outfilename"] if len(self.rundir) >= 2: if qeio.ionic_steps(outfilename, self.rundir[-1]) <= 3: return True if self.settings["nrg_convergence"] != None: if qeio.job_complete(outfilename, self.rundir[-1]) and qeio.job_complete( outfilename, self.rundir[-2]): o1 = qeio.Outfile( os.path.join(self.rundir[-1], outfilename)) o2 = qeio.Outfile( os.path.join(self.rundir[-2], outfilename)) if abs(o1.E[-1] - o2.E[-1]) < self.settings["nrg_convergence"]: return True return False
def complete(self): """Check if the Quantum Espresso relaxation is complete. Completion criteria: .../config/qe/relax/run.final/outfilename exists and is complete """ outfilename = self.settings["outfilename"] myoutfile = os.path.join(self.finaldir, outfilename) if not os.path.isfile(myoutfile): return False if not qeio.Outfile(myoutfile).complete(): return False return True
def error(self, outfilename, line=None, jobdir=None): """ Check if QE appears frozen Returns true if: 1) no file has been modified for 5 minutes 2) 'total cpu time+' exists in Outfile and no output file has been modified in 5x the time for the slowest loop """ # Check if any files modified in last 300 s most_recent = None most_recent_file = None for f in os.listdir(jobdir): t = time.time() - os.path.getmtime(os.path.join(jobdir, f)) if most_recent == None: most_recent = t most_recent_file = f elif t < most_recent: most_recent = t most_recent_file = f print "Most recent file output (" + f + "):", most_recent, " seconds ago." sys.stdout.flush() if t < 300: return False myoutfile = qeio.Outfile(os.path.join(jobdir, outfilename)) if myoutfile.complete: print "outfile.complete:", myoutfile.complete sys.stdout.flush() return False elif myoutfile.slowest_loop != None and most_recent > 5.0 * myoutfile.slowest_loop: print "slowest_loop:", myoutfile.slowest_loop print "5.0*slowest_loop:", 5.0 * myoutfile.slowest_loop print "most_recent:", most_recent sys.stdout.flush() return True return False
def status(self): """ Determine the status of a quantum espresso 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 = continuedir or "relax" or "constant" or None) The first value is the status of the entire relaxation. The second value is the current task, where 'continuedir' is the path to a quantum espresso job directory that is not yet completed, "relax" indicates another volume relaxation job is required, and "constant" that a constant volume run is required. """ infilename = self.settings["infilename"] outfilename = self.settings["outfilename"] # check if all complete if qeio.job_complete(outfilename, self.finaldir): return ("complete", None) # check status of relaxation runs self.update_rundir() # if not yet started if len(self.rundir) == 0: return ("incomplete", "setup") # if the latest run is complete: if qeio.job_complete(outfilename, self.rundir[-1]): # if it is a final constant volume run if qeio.get_infile_tag("title", infilename, self.rundir[-1]) != None: print qeio.get_infile_tag( "title", infilename, self.rundir[-1])[1:-1].split()[-1].strip().lower() if qeio.get_infile_tag("title", infilename, self.rundir[-1])[1:-1].split( )[-1].strip().lower() == "final": return ("complete", None) # elif constant volume run (but not the final one) if qeio.get_infile_tag( "calculation", infilename, self.rundir[-1]) in ['relax', 'scf', 'nscf']: if qeio.get_infile_tag( "nsteps", infilename, self.rundir[-1]) == len( qeio.Outfile( os.path.join(self.rundir[-1], outfilename)).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])