Skip to content

Commit

Permalink
rearrange large sigma handler logic to allow for data missing in outcar
Browse files Browse the repository at this point in the history
  • Loading branch information
esoteric-ephemera committed Dec 3, 2024
1 parent f3ac76b commit ee739fc
Showing 1 changed file with 27 additions and 23 deletions.
50 changes: 27 additions & 23 deletions src/custodian/vasp/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1365,7 +1365,7 @@ class LargeSigmaHandler(ErrorHandler):

is_monitor: bool = True

def __init__(self, e_entropy_tol: float = 1e-3, min_sigma: float = 0.01, output_filename: str = "OUTCAR") -> None:
def __init__(self, e_entropy_tol: float = 1e-3, min_sigma: float = 0.001, output_filename: str = "OUTCAR") -> None:
"""Initializes the handler with a buffer time."""
self.e_entropy_tol = e_entropy_tol
self.min_sigma = min_sigma
Expand All @@ -1374,13 +1374,13 @@ def __init__(self, e_entropy_tol: float = 1e-3, min_sigma: float = 0.01, output_
def check(self, directory="./") -> bool:
"""Check for error."""
incar = Incar.from_file(os.path.join(directory, "INCAR"))
if incar.get("ISMEAR", 1) < 0:
# skip check
return False

try:
outcar = load_outcar(os.path.join(directory, self.output_filename))
except Exception:
# Can't perform check if outcar not valid
return False

if incar.get("ISMEAR", 1) >= 0:
# get entropy terms, ionic step counts, and number of completed ionic steps
outcar.read_pattern(
{"smearing_entropy": r"entropy T\*S.*= *(\D\d*\.\d*)"},
Expand All @@ -1396,25 +1396,29 @@ def check(self, directory="./") -> bool:
)
outcar.read_pattern({"completed_ionic_steps": r"(aborting loop)"}, reverse=False, terminate_on_match=False)

completed_ionic_steps = len(outcar.data.get("completed_ionic_steps"))
entropies_per_atom = [0.0 for _ in range(completed_ionic_steps)]
n_atoms = len(Structure.from_file(os.path.join(directory, "POSCAR")))
except Exception:
# Can't perform check if outcar not valid, or data is missing
return False

# `Iteration (#ionic step # electronic step)` always written before entropy
e_step_idx = [step[0] for step in outcar.data.get("electronic_steps", [])]
smearing_entropy = outcar.data.get("smearing_entropy", [0.0 for _ in e_step_idx])
for ie_step_idx, ie_step in enumerate(e_step_idx):
# Because this handler monitors OUTCAR dynamically, it sometimes tries
# to retrieve data in OUTCAR before that data is written. To avoid this,
# we have two checks for list length here
if ie_step <= completed_ionic_steps and ie_step_idx < len(smearing_entropy):
entropies_per_atom[ie_step - 1] = smearing_entropy[ie_step_idx]

if len(entropies_per_atom) > 0:
n_atoms = len(Structure.from_file(os.path.join(directory, "POSCAR")))
self.entropy_per_atom = np.max(np.abs(entropies_per_atom)) / n_atoms
if self.entropy_per_atom > self.e_entropy_tol:
return True
completed_ionic_steps = len(outcar.data.get("completed_ionic_steps"))
entropies_per_atom = [0.0 for _ in range(completed_ionic_steps)]
n_atoms = len(Structure.from_file(os.path.join(directory, "POSCAR")))

# `Iteration (#ionic step # electronic step)` always written before entropy
e_step_idx = [step[0] for step in outcar.data.get("electronic_steps", [])]
smearing_entropy = outcar.data.get("smearing_entropy", [0.0 for _ in e_step_idx])
for ie_step_idx, ie_step in enumerate(e_step_idx):
# Because this handler monitors OUTCAR dynamically, it sometimes tries
# to retrieve data in OUTCAR before that data is written. To avoid this,
# we have two checks for list length here
if ie_step <= completed_ionic_steps and ie_step_idx < len(smearing_entropy):
entropies_per_atom[ie_step - 1] = smearing_entropy[ie_step_idx]

if len(entropies_per_atom) > 0:
n_atoms = len(Structure.from_file(os.path.join(directory, "POSCAR")))
self.entropy_per_atom = np.max(np.abs(entropies_per_atom)) / n_atoms
if self.entropy_per_atom > self.e_entropy_tol:
return True

return False

Expand Down

0 comments on commit ee739fc

Please sign in to comment.