Skip to content

Commit

Permalink
Add a VASP handler (warning) for too high NBANDS (#324)
Browse files Browse the repository at this point in the history
* Add an auto NBANDS handler

* Fix rounding error

* pre-commit auto-fixes

* pre-commit auto-fixes

* ruff

* fix

* pre-commit auto-fixes

* fx

* Add tests

* pre-commit auto-fixes

* fix test

* fix

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
Andrew-S-Rosen and pre-commit-ci[bot] authored Jun 24, 2024
1 parent c296ace commit 2412b87
Show file tree
Hide file tree
Showing 4 changed files with 1,953 additions and 15 deletions.
44 changes: 29 additions & 15 deletions custodian/vasp/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class VaspErrorHandler(ErrorHandler):
"coef": ["while reading plane", "while reading WAVECAR"],
"set_core_wf": ["internal error in SET_CORE_WF"],
"read_error": ["Error reading item", "Error code was IERR= 5"],
"auto_nbands": ["The number of bands has been changed"],
}

def __init__(
Expand Down Expand Up @@ -512,21 +513,7 @@ def correct(self, directory="./"):

if "too_few_bands" in self.errors:
nbands = None
if "NBANDS" in vi["INCAR"]:
nbands = vi["INCAR"]["NBANDS"]
else:
with open(os.path.join(directory, "OUTCAR")) as file:
for line in file:
# Have to take the last NBANDS line since sometimes VASP
# updates it automatically even if the user specifies it.
# The last one is marked by NBANDS= (no space).
if "NBANDS=" in line:
try:
d = line.split("=")
nbands = int(d[-1].strip())
break
except (IndexError, ValueError):
pass
nbands = vi["INCAR"]["NBANDS"] if "NBANDS" in vi["INCAR"] else self._get_nbands_from_outcar(directory)
if nbands:
new_nbands = max(int(1.1 * nbands), nbands + 1) # This handles the case when nbands is too low (< 8).
actions.append({"dict": "INCAR", "action": {"_set": {"NBANDS": new_nbands}}})
Expand Down Expand Up @@ -737,9 +724,36 @@ def correct(self, directory="./"):
)
self.error_count["algo_tet"] += 1

if "auto_nbands" in self.errors and (nbands := self._get_nbands_from_outcar(directory)):
nelect = load_outcar(os.path.join(directory, "OUTCAR")).nelect
if nelect and nbands > 2 * nelect:
self.error_count["auto_nbands"] += 1
warnings.warn(
"NBANDS seems to be too high. The electronic structure may be inaccurate. "
"You may want to rerun this job with a smaller number of cores.",
UserWarning,
)

VaspModder(vi=vi, directory=directory).apply_actions(actions)
return {"errors": list(self.errors), "actions": actions}

@staticmethod
def _get_nbands_from_outcar(directory: str) -> int | None:
nbands = None
with open(os.path.join(directory, "OUTCAR")) as file:
for line in file:
# Have to take the last NBANDS line since sometimes VASP
# updates it automatically even if the user specifies it.
# The last one is marked by NBANDS= (no space).
if "NBANDS=" in line:
try:
d = line.split("=")
nbands = int(d[-1].strip())
break
except (IndexError, ValueError):
pass
return nbands


class LrfCommutatorHandler(ErrorHandler):
"""
Expand Down
Loading

0 comments on commit 2412b87

Please sign in to comment.