Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new error handlers, add tests for NonConvergingErrorHandler #313

Merged
merged 9 commits into from
Feb 2, 2024
42 changes: 34 additions & 8 deletions custodian/vasp/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from math import prod

import numpy as np
from monty.io import zopen
from monty.os.path import zpath
from monty.serialization import loadfn
from pymatgen.core.structure import Structure
Expand Down Expand Up @@ -92,7 +93,10 @@ class VaspErrorHandler(ErrorHandler):
"zpotrf": ["LAPACK: Routine ZPOTRF failed", "Routine ZPOTRF ZTRTRI"],
"amin": ["One of the lattice vectors is very long (>50 A), but AMIN"],
"zbrent": ["ZBRENT: fatal internal in", "ZBRENT: fatal error in bracketing"],
# Note that PSSYEVX and PDSYEVX errors are identical up to LAPACK routine:
# P<prec>SYEVX uses <prec> = S(ingle) or D(ouble) precision
"pssyevx": ["ERROR in subspace rotation PSSYEVX"],
"pdsyevx": ["ERROR in subspace rotation PDSYEVX"],
"eddrmm": ["WARNING in EDDRMM: call to ZHEGV failed"],
"edddav": ["Error EDDDAV: Call to ZHEGV failed"],
"algo_tet": ["ALGO=A and IALGO=5X tend to fail"],
Expand All @@ -105,6 +109,7 @@ class VaspErrorHandler(ErrorHandler):
"rhosyg": ["RHOSYG"],
"posmap": ["POSMAP"],
"point_group": ["group operation missing"],
"pricelv": ["PRICELV: current lattice and primitive lattice are incommensurate"],
"symprec_noise": ["determination of the symmetry of your systems shows a strong"],
"dfpt_ncore": ["PEAD routines do not work for NCORE", "remove the tag NPAR from the INCAR file"],
"bravais": ["Inconsistent Bravais lattice"],
Expand Down Expand Up @@ -160,7 +165,7 @@ def check(self):
incar = Incar.from_file("INCAR")
self.errors = set()
error_msgs = set()
with open(self.output_filename) as file:
with zopen(self.output_filename, mode="rt") as file:
text = file.read()

# Check for errors
Expand Down Expand Up @@ -470,7 +475,7 @@ def correct(self):
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}}})

if "pssyevx" in self.errors and vi["INCAR"].get("ALGO", "Normal").lower() != "normal":
if self.errors & {"pssyevx", "pdsyevx"} and vi["INCAR"].get("ALGO", "Normal").lower() != "normal":
actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "Normal"}}})

if "eddrmm" in self.errors:
Expand Down Expand Up @@ -564,18 +569,24 @@ def correct(self):
else:
actions.append({"dict": "INCAR", "action": {"_set": {"ISYM": 0}}})

if "posmap" in self.errors:
if symprec_errors := self.errors & {"posmap", "pricelv"}:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some fancy code here 👍 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I learned from the best!

# VASP advises to decrease or increase SYMPREC by an order of magnitude
# the default SYMPREC value is 1e-5
if self.error_count["posmap"] == 0:
# For PRICELV, see https://www.vasp.at/forum/viewtopic.php?p=25608
if all(self.error_count[key] == 0 for key in symprec_errors):
# first, reduce by 10x
orig_symprec = vi["INCAR"].get("SYMPREC", 1e-5)
actions.append({"dict": "INCAR", "action": {"_set": {"SYMPREC": orig_symprec / 10}}})
elif self.error_count["posmap"] == 1:
elif all(self.error_count[key] <= 1 for key in symprec_errors):
# next, increase by 100x (10x the original)
orig_symprec = vi["INCAR"].get("SYMPREC", 1e-6)
actions.append({"dict": "INCAR", "action": {"_set": {"SYMPREC": orig_symprec * 100}}})
self.error_count["posmap"] += 1
elif any(self.error_count[key] > 1 for key in symprec_errors) and vi["INCAR"].get("ISYM", 2) > 0:
# Failing that, disable symmetry
actions.append({"dict": "INCAR", "action": {"_set": {"ISYM": 0}}})

for key in symprec_errors:
self.error_count[key] += 1

if "point_group" in self.errors and vi["INCAR"].get("ISYM", 2) > 0:
actions.append({"dict": "INCAR", "action": {"_set": {"ISYM": 0}}})
Expand Down Expand Up @@ -1118,12 +1129,27 @@ def correct(self):

if actions:
vi = VaspInput.from_directory(".")

# Check for PSMAXN errors - see extensive discussion here
# https://github.com/materialsproject/custodian/issues/133
# Only correct PSMAXN when run couldn't converge for any reason
errors = ["Unconverged"]
if os.path.isfile("OUTCAR"):
with open("OUTCAR") as file:
outcar_as_str = file.read()
if "PSMAXN for non-local potential too small" in outcar_as_str:
if vi["INCAR"].get("LREAL", False) not in [False, "False", "false"]:
actions += [
{"dict": "INCAR", "action": {"_set": {"LREAL": False}}},
]
errors += ["psmaxn"]

backup(VASP_BACKUP_FILES)
VaspModder(vi=vi).apply_actions(actions)
return {"errors": ["Unconverged"], "actions": actions}
return {"errors": errors, "actions": actions}

# Unfixable error. Just return None for actions.
return {"errors": ["Unconverged"], "actions": None}
return {"errors": errors, "actions": None}


class IncorrectSmearingHandler(ErrorHandler):
Expand Down
2 changes: 1 addition & 1 deletion tests/feff/test_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
TEST_DIR = f"{TEST_FILES}/feff_unconverged"


def test_to_from_dict():
def test_as_from_dict():
f = FeffJob("hello")
f2 = FeffJob.from_dict(f.as_dict())
assert type(f) == type(f2)
Expand Down
43 changes: 17 additions & 26 deletions tests/files/cp2k/cp2k.inp
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
A 13.397596 0.0 7.735104
B 4.465864 12.631372 7.735104
C 0.0 0.0 15.470208
&END CELL
&END
&KIND Si
ELEMENT Si
MAGNETIZATION 0.0
BASIS_SET DZVP-MOLOPT-GTH
POTENTIAL GTH-PBE
&END KIND
&END SUBSYS
&END
&END
&DFT
BASIS_SET_FILE_NAME BASIS_MOLOPT
POTENTIAL_FILE_NAME GTH_POTENTIALS
Expand All @@ -23,52 +23,43 @@
METHOD GPW
EPS_DEFAULT 1e-06
EXTRAPOLATION ASPC
&END QS
&END
&SCF
MAX_SCF 20
EPS_SCF 1e-07
SCF_GUESS RESTART
ADDED_MOS 1000
&OT
MINIMIZER DIIS
PRECONDITIONER FULL_SINGLE_INVERSE
ENERGY_GAP 0.01
MINIMIZER CG
&END OT
&END
&OUTER_SCF
MAX_SCF 20
EPS_SCF 1e-07
&END OUTER_SCF
&MIXING
METHOD BROYDEN_MIXING
ALPHA 0.1
&END MIXING
&SMEAR
ELEC_TEMP 300
METHOD FERMI_DIRAC
&END SMEAR
&END SCF
&END
&END
&MGRID
CUTOFF 1200 ! Cutoff in [Ry] for finest level of the MG.
REL_CUTOFF 80 ! Controls which gaussians are mapped to which level of the MG
NGRIDS 5
PROGRESSION_FACTOR 3
&END MGRID
&END
&XC
&XC_FUNCTIONAL PBE
&END XC_FUNCTIONAL
&END XC
&END
&END
&PRINT
&PDOS
NLUMO -1
COMPONENTS
&LDOS
COMPONENTS
&END LDOS
&END PDOS
&END PRINT
&END DFT
&END FORCE_EVAL
&END
&END
&END
&END
&END
&GLOBAL
PROJECT_NAME CP2K
RUN_TYPE DEBUG
&END GLOBAL
&END
13 changes: 13 additions & 0 deletions tests/files/nonconv/CONTCAR
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Si2
1.000000000000000
3.5955661429273054 -0.0000000000000002 2.0759013720700468
1.1985220476424352 3.3899309303295633 2.0759013720700468
0.0000000000000001 -0.0000000000000002 4.1518027441400935
Si
2
Direct
0.8750000000000000 0.8750000000000000 0.8750000000000000
0.1250000000000000 0.1250000000000000 0.1250000000000000

0.00000000E+00 -0.00000000E+00 -0.00000000E+00
0.00000000E+00 -0.00000000E+00 -0.00000000E+00
18 changes: 18 additions & 0 deletions tests/files/nonconv/INCAR
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
ALGO = Fast
EDIFF = 0.000001
EDIFFG = -0.001
ENCUT = 520
IBRION = 2
ISIF = 3
ISMEAR = -5
ISPIN = 2
LASPH = True
LORBIT = 11
LREAL = Auto
LWAVE = False
MAGMOM = 2*0.6
NELMDL = -5
NELM = 10
NSW = 6
PREC = Accurate
SIGMA = 0.05
4 changes: 4 additions & 0 deletions tests/files/nonconv/KPOINTS
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pymatgen with grid density = 456 / number of atoms
0
Gamma
6 6 6
48 changes: 48 additions & 0 deletions tests/files/nonconv/OSZICAR
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
N E dE d eps ncg rms rms(c)
DAV: 1 0.703944930940E+01 0.70394E+01 -0.19464E+03 8192 0.343E+01
DAV: 2 -0.139346823929E+01 -0.84329E+01 -0.83568E+01 12288 0.403E+00
DAV: 3 -0.140089696347E+01 -0.74287E-02 -0.74302E-02 8192 0.204E-01
DAV: 4 -0.140090631749E+01 -0.93540E-05 -0.93686E-05 16384 0.693E-03
DAV: 5 -0.140090631776E+01 -0.26540E-09 -0.15989E-10 8192 0.104E-05 0.227E+00
RMM: 6 -0.173205760878E+01 -0.33115E+00 -0.72387E-02 8192 0.154E-01 0.128E+00
RMM: 7 -0.201443785221E+01 -0.28238E+00 -0.35841E-02 8192 0.122E-01 0.369E-01
RMM: 8 -0.214093866532E+01 -0.12650E+00 -0.17600E-02 8192 0.693E-02 0.127E-01
RMM: 9 -0.215082349171E+01 -0.98848E-02 -0.12921E-03 8192 0.226E-02 0.592E-02
RMM: 10 -0.215146727548E+01 -0.64378E-03 -0.26061E-04 8192 0.111E-02
1 F= -.21514673E+01 E0= -.21514673E+01 d E =-.215147E+01 mag= 4.0068
N E dE d eps ncg rms rms(c)
DAV: 1 -0.228829248386E+01 -0.13747E+00 -0.18848E+00 10496 0.409E-01 0.980E-01
RMM: 2 -0.221735296379E+01 0.70940E-01 -0.10290E-02 8192 0.567E-02 0.511E-01
RMM: 3 -0.215060301952E+01 0.66750E-01 -0.14132E-02 8192 0.596E-02 0.138E-01
RMM: 4 -0.220312681258E+01 -0.52524E-01 -0.62735E-03 8192 0.401E-02 0.596E-02
RMM: 5 -0.221199904183E+01 -0.88722E-02 -0.47942E-04 8192 0.139E-02 0.276E-02
RMM: 6 -0.221747706815E+01 -0.54780E-02 -0.14386E-04 8192 0.880E-03 0.161E-02
RMM: 7 -0.221859674176E+01 -0.11197E-02 -0.78013E-05 8192 0.630E-03 0.921E-03
RMM: 8 -0.221878210095E+01 -0.18536E-03 -0.18785E-05 8192 0.349E-03 0.491E-03
RMM: 9 -0.221931909298E+01 -0.53699E-03 -0.72773E-06 8192 0.162E-03 0.268E-03
RMM: 10 -0.221955173113E+01 -0.23264E-03 -0.36802E-06 8191 0.111E-03
2 F= -.22195517E+01 E0= -.22195517E+01 d E =-.680845E-01 mag= 4.0000
N E dE d eps ncg rms rms(c)
DAV: 1 -0.316959309399E+01 -0.95027E+00 -0.19290E+01 9344 0.136E+00 0.314E+00
RMM: 2 -0.172018293853E+01 0.14494E+01 -0.19613E-01 8192 0.236E-01 0.142E+00
RMM: 3 -0.204637227740E+01 -0.32619E+00 -0.22694E-01 8192 0.239E-01 0.532E-01
RMM: 4 -0.239495964246E+01 -0.34859E+00 -0.19537E-01 8192 0.170E-01 0.220E-01
RMM: 5 -0.243755282820E+01 -0.42593E-01 -0.76494E-03 8192 0.496E-02 0.106E-01
RMM: 6 -0.245384902743E+01 -0.16296E-01 -0.79556E-04 8192 0.205E-02 0.597E-02
RMM: 7 -0.246830766093E+01 -0.14459E-01 -0.10299E-03 8192 0.202E-02 0.340E-02
RMM: 8 -0.246689303109E+01 0.14146E-02 -0.15154E-04 8192 0.901E-03 0.155E-02
RMM: 9 -0.246889137035E+01 -0.19983E-02 -0.56301E-05 8192 0.570E-03 0.144E-02
RMM: 10 -0.246914398112E+01 -0.25261E-03 -0.30098E-05 8192 0.347E-03
3 F= -.24691440E+01 E0= -.24691440E+01 d E =-.317677E+00 mag= 4.0000
N E dE d eps ncg rms rms(c)
DAV: 1 -0.690154619460E+01 -0.44327E+01 -0.10144E+02 9856 0.340E+00 0.772E+00
RMM: 2 -0.332844236562E+01 0.35731E+01 -0.61238E-01 8192 0.488E-01 0.375E+00
RMM: 3 -0.232620533798E+01 0.10022E+01 -0.67498E-01 8192 0.444E-01 0.130E+00
RMM: 4 -0.310893338163E+01 -0.78273E+00 -0.78965E-02 8192 0.195E-01 0.614E-01
RMM: 5 -0.321743055578E+01 -0.10850E+00 -0.11156E-02 8192 0.728E-02 0.796E-01
RMM: 6 -0.327976095815E+01 -0.62330E-01 -0.30354E-03 8192 0.386E-02 0.854E-01
RMM: 7 -0.340337072568E+01 -0.12361E+00 -0.72175E-03 8192 0.503E-02 0.589E-01
RMM: 8 -0.347695337351E+01 -0.73583E-01 -0.10548E-02 8192 0.603E-02 0.195E-01
RMM: 9 -0.350846830738E+01 -0.31515E-01 -0.15609E-02 8192 0.738E-02 0.199E-01
RMM: 10 -0.350789443403E+01 0.57387E-03 -0.21768E-03 8192 0.300E-02
4 F= -.35078944E+01 E0= -.35078944E+01 d E =-.135643E+01 mag= -0.4164
10 changes: 10 additions & 0 deletions tests/files/nonconv/POSCAR
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Si2
1.0
7.2005176799999999 0.0000000000000000 4.1572202400000000
2.4001725600000001 6.7887158399999992 4.1572202400000000
0.0000000000000000 0.0000000000000000 8.3144404800000000
Si
2
direct
0.8750000000000000 0.8750000000000000 0.8750000000000000 Si
0.1250000000000000 0.1250000000000000 0.1250000000000000 Si
Loading
Loading