Skip to content

Commit

Permalink
Add eddiag error handling and fix AMIN error handling in VaspErrorHan…
Browse files Browse the repository at this point in the history
…dler (#302)

* Added AMIN handler and unit test to VaspErrorHander logic, corrected eddrm handler to avoid custodian inducing algo_tet errors

* Added eddiag error handling and unit test

* Tuning zheev/eddiag to remove OOM issues

* pre-commit auto-fixes

* pre-commit fix

* Fix tests, ensure that custodian does not induce algo_tet errors

* simplify custodian/vasp/tests/test_validators.py

* Remove error files with too few bands.

---------

Co-authored-by: Aaron David Kaplan <esoteric@login10.chn>
Co-authored-by: Aaron Kaplan <aaronkaplan@Aarons-MBP.dhcp.lbl.gov>
Co-authored-by: Janosh Riebesell <janosh.riebesell@gmail.com>
  • Loading branch information
4 people authored Nov 14, 2023
1 parent d200876 commit 53b031c
Show file tree
Hide file tree
Showing 11 changed files with 289 additions and 39 deletions.
27 changes: 18 additions & 9 deletions custodian/vasp/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class VaspErrorHandler(ErrorHandler):
"grad_not_orth": ["EDWAV: internal error, the gradient is not orthogonal"],
"nicht_konv": ["ERROR: SBESSELITER : nicht konvergent"],
"zheev": ["ERROR EDDIAG: Call to routine ZHEEV failed!"],
"eddiag": ["ERROR in EDDIAG: call to ZHEEV/ZHEEVX/DSYEV/DSYEVX failed"],
"elf_kpar": ["ELF: KPAR>1 not implemented"],
"elf_ncl": ["WARNING: ELF not implemented for non collinear case"],
"rhosyg": ["RHOSYG"],
Expand Down Expand Up @@ -207,6 +208,11 @@ def correct(self):
actions.append({"dict": "INCAR", "action": {"_set": {"ISMEAR": 0, "SIGMA": 0.05}}})
self.error_count[err_type] += 1

# Missing AMIN error handler:
# previously, custodian would kill the job without letting it run if AMIN was flagged
if "amin" in self.errors and vi["INCAR"].get("AMIN", 0.1) > 0.01:
actions.append({"dict": "INCAR", "action": {"_set": {"AMIN": 0.01}}})

if "inv_rot_mat" in self.errors and vi["INCAR"].get("SYMPREC", 1e-5) > 1e-8:
actions.append({"dict": "INCAR", "action": {"_set": {"SYMPREC": 1e-8}}})

Expand Down Expand Up @@ -536,16 +542,18 @@ def correct(self):
UserWarning,
)

if "zheev" in self.errors:
if self.errors & {"zheev", "eddiag"}:
# Copy CONTCAR to POSCAR if CONTCAR has already been populated.
try:
is_contcar = Poscar.from_file("CONTCAR")
except Exception:
is_contcar = False
if is_contcar:
actions.append({"file": "CONTCAR", "action": {"_file_copy": {"dest": "POSCAR"}}})
if vi["INCAR"].get("ALGO", "Normal").lower() != "exact":
actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "Exact"}}})
if vi["INCAR"].get("ALGO", "Normal").lower() == "fast":
actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "Normal"}}})
elif vi["INCAR"].get("ALGO", "Normal").lower() == "normal":
actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "exact"}}})

if "elf_kpar" in self.errors and vi["INCAR"].get("KPAR", 1) != 1:
actions.append({"dict": "INCAR", "action": {"_set": {"KPAR": 1}}})
Expand Down Expand Up @@ -645,7 +653,7 @@ def correct(self):
# This time try the recovery below.
actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "Fast"}}})
#
# We will only hit the 2nd algo_teet error if the ALGO was changed back from Fast to All/Damped
# We will only hit the 2nd algo_tet error if the ALGO was changed back from Fast to All/Damped
# by e.g. NonConvergingErrorHandler
# NOTE this relies on self.errors being reset on empty set on every .check call
if self.error_count["algo_tet"] > 0:
Expand Down Expand Up @@ -1052,9 +1060,8 @@ def correct(self):

if (
v.incar.get("ISMEAR", -1) >= 0
or not 50 <= v.incar.get("IALGO", 38) <= 59
and v.incar.get("METAGGA", "--") != "--"
and algo != "all"
and (algo != "all" or (not 50 <= v.incar.get("IALGO", 38) <= 59))
):
# If meta-GGA, go straight to Algo = All only if ISMEAR is greater or equal 0.
# Algo = All is recommended in the VASP manual and some meta-GGAs explicitly
Expand Down Expand Up @@ -1083,7 +1090,9 @@ def correct(self):
actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "Fast"}}})
elif algo == "fast":
actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "Normal"}}})
elif algo == "normal" and (v.incar.get("ISMEAR", -1) >= 0 or not 50 <= v.incar.get("IALGO", 38) <= 59):
elif algo == "normal" and v.incar.get("ISMEAR", 1) >= 0:
# NB: default for ISMEAR is 1. To avoid algo_tet errors, only set
# ALGO = ALL if ISMEAR >= 0
actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "All"}}})
else:
# Try mixing as last resort
Expand Down Expand Up @@ -1485,9 +1494,9 @@ def correct(self):
actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "Fast"}}})
elif algo == "fast":
actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "Normal"}}})
elif algo == "normal":
elif algo == "normal" and incar.get("ISMEAR", 1) >= 0:
actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "All"}}})
elif algo == "all":
elif algo == "all" or (algo == "normal" and incar.get("ISMEAR", 1) < 0):
if amix > 0.1 and bmix > 0.01:
# Try linear mixing
actions.append(
Expand Down
32 changes: 32 additions & 0 deletions custodian/vasp/tests/test_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,38 @@ def test_read_error(self):
assert dct["errors"] == ["read_error"]
assert dct["actions"] is None

def test_amin(self):
# Cell with at least one dimension >= 50 A, but AMIN > 0.01, and calculation not yet complete
shutil.copy("INCAR.amin", "INCAR")
h = VaspErrorHandler("vasp.amin")
h.check()
d = h.correct()
assert d["errors"] == ["amin"]
assert d["actions"] == [{"action": {"_set": {"AMIN": 0.01}}, "dict": "INCAR"}]

def test_eddiag(self):
# subspace rotation error
os.remove("CONTCAR")
shutil.copy("INCAR.amin", "INCAR")
h = VaspErrorHandler("vasp.eddiag")
h.check()
d = h.correct()
assert d["errors"] == ["eddiag"]
# first check that no CONTCAR exists, only action should be updating INCAR
# ALGO = Fast --> ALGO = Normal
assert d["actions"] == [{"action": {"_set": {"ALGO": "Normal"}}, "dict": "INCAR"}]

# now copy CONTCAR and check that both CONTCAR->POSCAR
# and INCAR updates are included: ALGO = Normal --> ALGO = exact
shutil.copy("CONTCAR.eddiag", "CONTCAR")
h = VaspErrorHandler("vasp.eddiag")
h.check()
d = h.correct()
assert d["actions"] == [
{"file": "CONTCAR", "action": {"_file_copy": {"dest": "POSCAR"}}},
{"action": {"_set": {"ALGO": "exact"}}, "dict": "INCAR"},
]


class AliasingErrorHandlerTest(PymatgenTest):
def setUp(self):
Expand Down
26 changes: 4 additions & 22 deletions custodian/vasp/tests/test_validators.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import os
import shutil
import unittest

from custodian.vasp.validators import VaspAECCARValidator, VaspFilesValidator, VaspNpTMDValidator, VasprunXMLValidator

test_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", "test_files")
cwd = os.getcwd()


class VasprunXMLValidatorTest(unittest.TestCase):
class TestVasprunXMLValidator:
def test_check_and_correct(self):
os.chdir(os.path.join(test_dir, "bad_vasprun"))
h = VasprunXMLValidator()
Expand All @@ -26,12 +24,8 @@ def test_as_dict(self):
h2 = VasprunXMLValidator.from_dict(d)
assert isinstance(h2, VasprunXMLValidator)

@classmethod
def tearDownClass(cls):
os.chdir(cwd)


class VaspFilesValidatorTest(unittest.TestCase):
class TestVaspFilesValidator:
def test_check_and_correct(self):
# just an example where CONTCAR is not present
os.chdir(os.path.join(test_dir, "positive_energy"))
Expand All @@ -47,12 +41,8 @@ def test_as_dict(self):
h2 = VaspFilesValidator.from_dict(d)
assert isinstance(h2, VaspFilesValidator)

@classmethod
def tearDownClass(cls):
os.chdir(cwd)


class VaspNpTMDValidatorTest(unittest.TestCase):
class TestVaspNpTMDValidator:
def test_check_and_correct(self):
# NPT-AIMD using correct VASP
os.chdir(os.path.join(test_dir, "npt_common"))
Expand All @@ -73,18 +63,10 @@ def test_as_dict(self):
h2 = VaspNpTMDValidator.from_dict(d)
assert isinstance(h2, VaspNpTMDValidator)

@classmethod
def tearDownClass(cls):
os.chdir(cwd)


class VaspAECCARValidatorTest(unittest.TestCase):
class TestVaspAECCARValidator:
def test_check_and_correct(self):
# NPT-AIMD using correct VASP
os.chdir(os.path.join(test_dir, "bad_aeccar"))
h = VaspAECCARValidator()
assert h.check()

@classmethod
def tearDownClass(cls):
os.chdir(cwd)
87 changes: 87 additions & 0 deletions test_files/CONTCAR.eddiag
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
Cs6 U6 As12 O55
1.0
6.7346923911508014 0.0000000000000000 0.9285262282647135
0.7401923066829772 9.5890356602029918 2.1332187291702365
0.0000000000000000 0.0000000000000000 20.5988000000000007
Cs U As O
6 6 12 55
direct
0.4957000000000000 0.3319500000000000 0.9441000000000001 Cs+
0.9702000000000000 0.6994000000000000 0.6221800000000000 Cs+
0.0867000000000000 0.1105000000000000 0.6551800000000000 Cs+
0.7371000000000000 0.0299000000000000 0.2812500000000000 Cs+
0.3684000000000000 0.7777800000000000 0.9883999999999999 Cs+
0.5954000000000000 0.4774200000000000 0.3348800000000000 Cs+
0.3278000000000000 0.0356500000000000 0.1334400000000000 U6+
0.5132600000000000 0.4086600000000000 0.1459100000000000 U6+
0.5191000000000000 0.7374600000000000 0.4757300000000000 U6+
0.3550100000000000 0.7029800000000000 0.7830900000000001 U6+
0.7023400000000000 0.1031800000000000 0.4972200000000000 U6+
0.5386900000000000 0.0726599999999999 0.8021300000000000 U6+
0.7045000000000000 0.4248000000000001 0.7374800000000000 As5+
0.8314000000000000 0.7236000000000000 0.8419200000000000 As5+
0.1380000000000000 0.3702000000000000 0.7862400000000000 As5+
0.0282000000000000 0.9725000000000000 0.8569700000000000 As5+
0.1601000000000000 0.6777000000000000 0.1988300000000000 As5+
0.2238000000000000 0.0841000000000001 0.4373500000000000 As5+
0.8397000000000000 0.1332000000000000 0.0763900000000000 As5+
0.0284000000000000 0.8342000000000001 0.4208499999999999 As5+
0.3544000000000000 0.3844000000000000 0.5409900000000001 As5+
0.9174000000000000 0.4379999999999999 0.4948500000000000 As5+
0.0351000000000000 0.3849000000000000 0.0865900000000000 As5+
0.7351000000000000 0.7370000000000000 0.1501600000000000 As5+
0.0140000000000000 0.7305000000000000 0.7777000000000001 O2-
0.6620000000000000 0.5819000000000001 0.7579000000000000 O2-
0.8820000000000000 0.0549999999999999 0.7982000000000000 O2-
0.1780000000000000 0.7551000000000000 0.4764000000000000 O2-
0.2537000000000000 0.9265000000000000 0.8187000000000000 O2-
0.5770000000000000 0.0854999999999999 0.7158000000000000 O2-
0.6180000000000000 0.2970999999999999 0.7952000000000000 O2-
0.2400000000000000 0.2114000000000000 0.7865000000000000 O2-
0.5500000000000000 0.4950000000000000 0.0609000000000000 O2-
0.5120000000000000 0.0544000000000000 0.8902000000000000 O2-
0.6271000000000000 0.8174000000000000 0.8173000000000000 O2-
0.3250000000000000 0.6163999999999999 0.8687000000000000 O2-
0.9150000000000000 0.8182000000000000 0.8944000000000000 O2-
0.2860000000000000 0.4981000000000000 0.7553000000000000 O2-
0.4790000000000000 0.7225000000000000 0.5642000000000000 O2-
0.0300000000000000 0.3731000000000000 0.8633999999999999 O2-
0.7730000000000000 0.3075000000000001 0.5256000000000001 O2-
0.0569999999999999 0.0424000000000000 0.9189000000000001 O2-
0.2050000000000000 0.5308000000000000 0.1727000000000000 O2-
0.0490000000000000 0.0733999999999999 0.5014000000000001 O2-
0.9920000000000000 0.7711000000000000 0.3575000000000000 O2-
0.3730000000000000 0.7956000000000000 0.6982999999999999 O2-
0.9680000000000000 0.3910000000000000 0.7289000000000000 O2-
0.4000000000000000 0.2285000000000000 0.5217000000000001 O2-
0.4820000000000000 0.3148000000000000 0.2296000000000000 O2-
0.6820000000000001 0.4258000000000000 0.6598999999999999 O2-
0.8120000000000001 0.5942000000000001 0.4958000000000000 O2-
0.5430000000000000 0.7559000000000000 0.3884000000000000 O2-
0.7920000000000000 0.5724000000000000 0.8891000000000000 O2-
0.7400000000000000 0.1913000000000000 0.4115000000000000 O2-
0.2990000000000000 0.0278000000000000 0.2205000000000000 O2-
0.8066000000000000 0.8840000000000000 0.4604000000000000 O2-
0.4430000000000000 0.5125000000000000 0.4799000000000000 O2-
0.0309999999999999 0.4387000000000001 0.4172000000000000 O2-
0.2260000000000000 0.6642000000000000 0.2741000000000000 O2-
0.4331000000000000 0.9927000000000000 0.4636000000000000 O2-
0.0960000000000001 0.4125000000000001 0.5504000000000000 O2-
0.8519000000000000 0.3812000000000000 0.1484000000000000 O2-
0.3780000000000000 0.3854000000000000 0.6205000000000001 O2-
0.1380000000000000 0.9863000000000000 0.3835000000000000 O2-
0.9855000000000000 0.0607000000000000 0.1336000000000000 O2-
0.6820000000000001 0.0089999999999999 0.5795000000000000 O2-
0.8610000000000000 0.7372000000000000 0.0755000000000000 O2-
0.6225000000000001 0.8922000000000000 0.1526000000000000 O2-
0.0734000000000000 0.5404000000000000 0.0379000000000000 O2-
0.8049999999999999 0.0598000000000000 0.0144000000000000 O2-
0.2590000000000000 0.2399000000000000 0.3884000000000000 O2-
0.9020000000000000 0.7111000000000000 0.2107000000000000 O2-
0.2452000000000000 0.2942000000000000 0.1141000000000000 O2-
0.6118000000000000 0.1867000000000000 0.1127000000000000 O2-
0.5870000000000000 0.6081000000000000 0.1783000000000000 O2-
0.2410000000000000 0.8121000000000000 0.1442000000000000 O2-
0.3547000000000000 0.0504000000000000 0.0454000000000000 O2-
0.9534000000000000 0.2907000000000000 0.0346000000000000 O2-
0.9690000000000000 0.2971000000000000 0.2809000000000000 O2-
26 changes: 26 additions & 0 deletions test_files/INCAR.amin
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
ADDGRID = False
ALGO = Fast
AMIN = 0.1
EDIFF = 1e-06
ENAUG = 1360
ENCUT = 680
ISMEAR = -5
ISPIN = 2
KPAR = 4
KSPACING = 0.22
LAECHG = False
LASPH = False
LCHARG = False
LELF = False
LMAXMIX = 6
LORBIT = 11
LREAL = Auto
LVTOT = False
LWAVE = False
MAGMOM = 99*0.6
NCORE = 1
NELM = 100
NSIM = 8
NSW = 0
PREC = Accurate
SIGMA = 0.05
4 changes: 2 additions & 2 deletions test_files/unconverged/vasprun.xml.electronic2
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<i name="ENCUT"> 520.00000000</i>
<v name="MAGMOM"> 5.00000000 5.00000000 5.00000000 5.00000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000</v>
<i type="string" name="LREAL"> Auto</i>
<i type="int" name="ISMEAR"> -5</i>
<i type="int" name="ISMEAR"> 0</i>
<i name="SIGMA"> 0.05000000</i>
<i type="int" name="LMAXMIX"> 4</i>
<i type="logical" name="LWAVE"> F </i>
Expand Down Expand Up @@ -215,7 +215,7 @@
<i type="int" name="NMIN"> 0</i>
<i name="EREF"> 0.00000000</i>
<separator name="electronic smearing" >
<i type="int" name="ISMEAR"> -5</i>
<i type="int" name="ISMEAR"> 0</i>
<i name="SIGMA"> 0.05000000</i>
<i name="KSPACING"> 0.50000000</i>
<i type="logical" name="KGAMMA"> T </i>
Expand Down
4 changes: 2 additions & 2 deletions test_files/unconverged/vasprun.xml.electronic_metagga_fast
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<i name="ENCUT"> 520.00000000</i>
<v name="MAGMOM"> 5.00000000 5.00000000 5.00000000 5.00000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000</v>
<i type="string" name="LREAL"> Auto</i>
<i type="int" name="ISMEAR"> -5</i>
<i type="int" name="ISMEAR"> 0</i>
<i name="SIGMA"> 0.05000000</i>
<i type="int" name="LMAXMIX"> 4</i>
<i type="logical" name="LWAVE"> F </i>
Expand Down Expand Up @@ -210,7 +210,7 @@
<i type="int" name="NMIN"> 0</i>
<i name="EREF"> 0.00000000</i>
<separator name="electronic smearing" >
<i type="int" name="ISMEAR"> -5</i>
<i type="int" name="ISMEAR"> 0</i>
<i name="SIGMA"> 0.05000000</i>
<i name="KSPACING"> 0.50000000</i>
<i type="logical" name="KGAMMA"> T </i>
Expand Down
4 changes: 2 additions & 2 deletions test_files/unconverged/vasprun.xml.electronic_normal
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<i name="ENCUT"> 520.00000000</i>
<v name="MAGMOM"> 5.00000000 5.00000000 5.00000000 5.00000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000 0.60000000</v>
<i type="string" name="LREAL"> Auto</i>
<i type="int" name="ISMEAR"> -5</i>
<i type="int" name="ISMEAR"> 0</i>
<i name="SIGMA"> 0.05000000</i>
<i type="int" name="LMAXMIX"> 4</i>
<i type="logical" name="LWAVE"> F </i>
Expand Down Expand Up @@ -210,7 +210,7 @@
<i type="int" name="NMIN"> 0</i>
<i name="EREF"> 0.00000000</i>
<separator name="electronic smearing" >
<i type="int" name="ISMEAR"> -5</i>
<i type="int" name="ISMEAR"> 0</i>
<i name="SIGMA"> 0.05000000</i>
<i name="KSPACING"> 0.50000000</i>
<i type="logical" name="KGAMMA"> T </i>
Expand Down
4 changes: 2 additions & 2 deletions test_files/unconverged/vasprun.xml.scan
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<i name="ENCUT"> 520.00000000</i>
<v name="MAGMOM"> 0.00000000 0.00000000</v>
<i type="string" name="LREAL"> Auto</i>
<i type="int" name="ISMEAR"> -5</i>
<i type="int" name="ISMEAR"> 0</i>
<i name="SIGMA"> 0.05000000</i>
<i type="logical" name="LWAVE"> F </i>
<i type="logical" name="LCHARG"> T </i>
Expand Down Expand Up @@ -485,7 +485,7 @@
<i type="int" name="NMIN"> 0</i>
<i name="EREF"> 0.00000000</i>
<separator name="electronic smearing" >
<i type="int" name="ISMEAR"> -5</i>
<i type="int" name="ISMEAR"> 0</i>
<i name="SIGMA"> 0.05000000</i>
<i name="KSPACING"> 0.50000000</i>
<i type="logical" name="KGAMMA"> T </i>
Expand Down
Loading

0 comments on commit 53b031c

Please sign in to comment.