Skip to content

Commit

Permalink
Bad vasprun handler.
Browse files Browse the repository at this point in the history
Also, properly terminate custodian with an RuntimeError when max errors or
unrecoverable error is encountered. Otherwise, any workflow with Custodian will
just keep on going!
  • Loading branch information
shyuep committed Aug 11, 2014
1 parent 88d2e8b commit 4581578
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 6 deletions.
7 changes: 4 additions & 3 deletions custodian/custodian.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,10 @@ def run(self):
if self.gzipped_output:
gzip_dir(".")

if total_errors >= self.max_errors:
logger.info("Max {} errors reached. Exited..."
.format(self.max_errors))
if total_errors >= self.max_errors or unrecoverable:
raise RuntimeError("{} errors reached. Unrecoverable? {}. "
"Exited...".format(self.max_errors,
unrecoverable))
elif not unrecoverable:
#Cleanup checkpoint files (if any) if run is successful.
Custodian._delete_checkpoints(cwd)
Expand Down
41 changes: 38 additions & 3 deletions custodian/vasp/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import datetime
import operator
import shutil
import glob

import numpy as np

Expand Down Expand Up @@ -351,7 +352,7 @@ def __str__(self):
class MaxForceErrorHandler(ErrorHandler):
"""
Checks that the desired force convergence has been achieved. Otherwise
restarts the run with smaller EDIFF. (This is necessary since energy
restarts the run with smaller EDIFF. (This is necessary since energy
and force convergence criteria cannot be set simultaneously)
"""
is_monitor = False
Expand All @@ -362,7 +363,7 @@ def __init__(self, output_filename="vasprun.xml",
Args:
input_filename (str): name of the vasp INCAR file
output_filename (str): name to look for the vasprun
max_force_threshold (float): Threshold for max force for
max_force_threshold (float): Threshold for max force for
restarting the run. (typically should be set to the value
that the creator looks for)
"""
Expand All @@ -372,7 +373,7 @@ def __init__(self, output_filename="vasprun.xml",
def check(self):
try:
v = Vasprun(self.output_filename)
max_force = max([np.linalg.norm(a) for a
max_force = max([np.linalg.norm(a) for a
in v.ionic_steps[-1]["forces"]])
if max_force > self.max_force_threshold:
return True
Expand Down Expand Up @@ -797,3 +798,37 @@ def correct(self):

def __str__(self):
return "StoppedRunHandler"


class BadVasprunXMLHandler(ErrorHandler):
"""
Handler to properly terminate a run when a bad vasprun.xml is found.
"""

is_monitor = False

is_terminating = True

def __init__(self):
self.vasprunxml = None
pass

def check(self):
try:
self.vasprunxml = _get_vasprun()
v = Vasprun(self.vasprunxml)
except:
return True
return False

def correct(self):
return {"errors": ["Bad vasprun.xml in %s." % self.vasprunxml],
"actions": None}

def __str__(self):
return "BadVasprunXMLHandler"


def _get_vasprun(path="."):
vaspruns = glob.glob(os.path.join(path, "vasprun.xml*"))
return sorted(vaspruns, reverse=True)[0] if vaspruns else None

0 comments on commit 4581578

Please sign in to comment.