Skip to content

Commit 266e85a

Browse files
esoteric-ephemerapre-commit-ci[bot]shyuep
authored
Add new MP input sets / concurrently update MatPES POTCARs (#3916)
* add new MP24 input sets * pre-commit auto-fixes * typing for config updates * pre-commit auto-fixes * skip json in codespell check * still trying to skip codespell json checks * update base PBE 64 pseudopotentials, add hash for MP24 sets to sets * fix matpes set to remove the GGA tag for r2SCAN runs * slight tweak * pre-commit auto-fixes * fixes * pre-commit auto-fixes * disable auto_ismear * fix bandap --> kspacing * pre-commit auto-fixes * Add GGA_COMPAT False tag * Add full test, clean up vdw stuff (prev unused) * Add citation info --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Shyue Ping Ong <[email protected]>
1 parent e2baa68 commit 266e85a

File tree

4 files changed

+342
-18
lines changed

4 files changed

+342
-18
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Default VASP settings for calculations in the Materials Project
2+
# using the Regularized-Restored Strongly Constrained and Appropriately
3+
# Normed functional (r2SCAN).
4+
PARENT: PBE64Base
5+
INCAR:
6+
ALGO: Normal
7+
EDIFF: 1.e-05
8+
EDIFFG: -0.02
9+
ENAUG: 1360
10+
ENCUT: 680
11+
GGA_COMPAT: False
12+
IBRION: 2
13+
ISIF: 3
14+
ISMEAR: 0 # included to have some reasonable default
15+
ISPIN: 2
16+
KSPACING: 0.22 # included to have some reasonable default
17+
LAECHG: True
18+
LASPH: True
19+
LCHARG: True
20+
LELF: False # LELF = True restricts calculation to KPAR = 1
21+
LMAXMIX: 6 # per benchmark
22+
LMIXTAU: True
23+
LORBIT: 11
24+
LREAL: False # per benchmark
25+
LVTOT: True
26+
LWAVE: False
27+
METAGGA: R2SCAN
28+
NELM: 200
29+
NSW: 99
30+
PREC: Accurate
31+
SIGMA: 0.05 # included to have some reasonable default

src/pymatgen/io/vasp/PBE64Base.yaml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ POTCAR:
1111
At: At
1212
Au: Au
1313
B: B
14-
Ba: Ba_sv
14+
Ba: Ba_sv_GW
1515
Be: Be_sv
1616
Bi: Bi
1717
Br: Br
@@ -26,8 +26,8 @@ POTCAR:
2626
Cr: Cr_pv
2727
Cs: Cs_sv
2828
Cu: Cu_pv
29-
Dy: Dy_3
30-
Er: Er_3
29+
Dy: Dy_h
30+
Er: Er_h
3131
Eu: Eu
3232
F: F
3333
Fe: Fe_pv
@@ -39,7 +39,7 @@ POTCAR:
3939
He: He
4040
Hf: Hf_pv
4141
Hg: Hg
42-
Ho: Ho_3
42+
Ho: Ho_h
4343
I: I
4444
In: In_d
4545
Ir: Ir
@@ -54,7 +54,7 @@ POTCAR:
5454
N: N
5555
Na: Na_pv
5656
Nb: Nb_pv
57-
Nd: Nd_3
57+
Nd: Nd_h
5858
Ne: Ne
5959
Ni: Ni_pv
6060
Np: Np
@@ -64,9 +64,9 @@ POTCAR:
6464
Pa: Pa
6565
Pb: Pb_d
6666
Pd: Pd
67-
Pm: Pm_3
67+
Pm: Pm_h
6868
Po: Po_d
69-
Pr: Pr_3
69+
Pr: Pr_h
7070
Pt: Pt
7171
Pu: Pu
7272
Ra: Ra_sv
@@ -80,22 +80,22 @@ POTCAR:
8080
Sc: Sc_sv
8181
Se: Se
8282
Si: Si
83-
Sm: Sm_3
83+
Sm: Sm_h
8484
Sn: Sn_d
8585
Sr: Sr_sv
8686
Ta: Ta_pv
87-
Tb: Tb_3
87+
Tb: Tb_h
8888
Tc: Tc_pv
8989
Te: Te
9090
Th: Th
9191
Ti: Ti_pv
9292
Tl: Tl_d
93-
Tm: Tm_3
93+
Tm: Tm_h
9494
U: U
9595
V: V_pv
9696
W: W_sv
97-
Xe: Xe
97+
Xe: Xe_GW
9898
Y: Y_sv
99-
Yb: Yb_3
99+
Yb: Yb_h
100100
Zn: Zn
101101
Zr: Zr_sv

src/pymatgen/io/vasp/sets.py

Lines changed: 200 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@
8484

8585

8686
def _load_yaml_config(fname):
87-
config = loadfn(f"{MODULE_DIR}/{fname}.yaml")
87+
fname = f"{MODULE_DIR}/{fname}"
88+
if not fname.endswith(".yaml"):
89+
fname += ".yaml"
90+
config = loadfn(fname)
8891
if "PARENT" in config:
8992
parent_config = _load_yaml_config(config["PARENT"])
9093
for k, v in parent_config.items():
@@ -623,7 +626,11 @@ def incar(self) -> Incar:
623626
elif key == "KSPACING" and self.auto_kspacing:
624627
# Default to metal if no prev calc available
625628
bandgap = 0 if self.bandgap is None else self.bandgap
626-
incar[key] = auto_kspacing(bandgap, self.bandgap_tol)
629+
if new_kspacing := getattr(self, "kspacing_update", None):
630+
# allow custom KSPACING update
631+
incar[key] = new_kspacing
632+
else:
633+
incar[key] = auto_kspacing(bandgap, self.bandgap_tol)
627634

628635
else:
629636
incar[key] = setting
@@ -1294,7 +1301,7 @@ class MPRelaxSet(VaspInputSet):
12941301

12951302
@due.dcite(
12961303
Doi("10.1021/acs.jpclett.0c02405"),
1297-
description="AccurAccurate and Numerically Efficient r2SCAN Meta-Generalized Gradient Approximation",
1304+
description="Accurate and Numerically Efficient r2SCAN Meta-Generalized Gradient Approximation",
12981305
)
12991306
@due.dcite(
13001307
Doi("10.1103/PhysRevLett.115.036402"),
@@ -1352,7 +1359,7 @@ class MPScanRelaxSet(VaspInputSet):
13521359
13531360
James W. Furness, Aaron D. Kaplan, Jinliang Ning, John P. Perdew, and Jianwei Sun.
13541361
Accurate and Numerically Efficient r2SCAN Meta-Generalized Gradient Approximation.
1355-
The Journal of Physical Chemistry Letters 0, 11 DOI: 10.1021/acs.jpclett.0c02405
1362+
The Journal of Physical Chemistry Letters 11, 8208-8215 (2022) DOI: 10.1021/acs.jpclett.0c02405
13561363
"""
13571364

13581365
bandgap: float | None = None
@@ -1375,6 +1382,149 @@ def __post_init__(self) -> None:
13751382
self._config_dict["INCAR"].pop(k, None)
13761383

13771384

1385+
@dataclass
1386+
class MP24RelaxSet(VaspInputSet):
1387+
"""
1388+
Materials Project relax set after a 2023-2024 benchmarking effort.
1389+
1390+
By default, this uses r2SCAN as the xc functional.
1391+
For discussion around this benchmarking effort, see:
1392+
https://github.com/materialsproject/foundation/pull/26
1393+
1394+
Citation info:
1395+
- r2SCAN:
1396+
James W. Furness, Aaron D. Kaplan, Jinliang Ning, John P. Perdew, and Jianwei Sun.
1397+
Accurate and Numerically Efficient r2SCAN Meta-Generalized Gradient Approximation.
1398+
J. Phys. Chem. Lett. 11, 8208-8215 (2022) DOI: 10.1021/acs.jpclett.0c02405
1399+
- r2SCAN-rVV10:
1400+
Jinliang Ning, Manish Kothakonda, James W. Furness, Aaron D. Kaplan, Sebastian Ehlert,
1401+
Jan Gerit Brandenburg, John P. Perdew, and Jianwei Sun.
1402+
Workhorse minimally empirical dispersion-corrected density functional with tests for
1403+
weakly bound systems: r2SCAN+rVV10.
1404+
Phys. Rev. B 106, 075422 (2022) DOI: 10.1103/PhysRevB.106.075422
1405+
- r2SCAN-D4:
1406+
Sebastian Ehlert, Uwe Huniar, Jinliang Ning, James W. Furness, Jianwei Sun,
1407+
Aaron D. Kaplan, John P. Perdew, and Jan Gerit Brandenburg.
1408+
r2SCAN-D4: Dispersion corrected meta-generalized gradient approximation for general chemical applications.
1409+
J. Chem. Phys. 154, 061101 (2021) DOI: 10.1063/5.0041008
1410+
- PBE:
1411+
John P. Perdew, Kieron Burke, and Matthias Ernzerhof,
1412+
Generalized Gradient Approximation Made Simple,
1413+
Phys. Rev. Lett. 77, 3865 (1996) DOI: 10.1103/PhysRevLett.77.3865
1414+
- PBEsol:
1415+
John P. Perdew, Adrienn Ruzsinszky, Gábor I. Csonka, Oleg A. Vydrov,
1416+
Gustavo E. Scuseria, Lucian A. Constantin, Xiaolan Zhou, and Kieron Burke.
1417+
Restoring the Density-Gradient Expansion for Exchange in Solids and Surfaces.
1418+
Phys. Rev. Lett. 100, 136406 (2009) DOI: 10.1103/PhysRevLett.100.136406
1419+
- PBE-D4 and PBEsol-D4:
1420+
Eike Caldeweyher,Jan-Michael Mewes, Sebastian Ehlert, and Stefan Grimme.
1421+
Extension and evaluation of the D4 London-dispersion model for periodic systems.
1422+
Phys. Chem. Chem. Phys. 22, 8499-8512 (2020) DOI: 10.1039/D0CP00502A
1423+
"""
1424+
1425+
xc_functional: Literal["r2SCAN", "PBE", "PBEsol"] = "r2SCAN"
1426+
dispersion: Literal["rVV10", "D4"] | None = None
1427+
CONFIG = _load_yaml_config("MP24RelaxSet")
1428+
auto_ismear: bool = False
1429+
auto_kspacing: bool = True
1430+
inherit_incar: bool = False
1431+
1432+
def __post_init__(self) -> None:
1433+
super().__post_init__()
1434+
1435+
to_func = {
1436+
"r2SCAN": "R2SCAN",
1437+
"PBE": "PE",
1438+
"PBEsol": "PS",
1439+
}
1440+
1441+
config_updates: dict[str, Any] = {}
1442+
if self.xc_functional == "r2SCAN":
1443+
config_updates |= {"METAGGA": to_func[self.xc_functional]}
1444+
self._config_dict["INCAR"].pop("GGA", None)
1445+
elif self.xc_functional in ["PBE", "PBEsol"]:
1446+
config_updates |= {"GGA": to_func[self.xc_functional]}
1447+
self._config_dict["INCAR"].pop("METAGGA", None)
1448+
else:
1449+
raise ValueError(f"Unknown XC functional {self.xc_functional}!")
1450+
1451+
if self.dispersion == "rVV10":
1452+
if self.xc_functional == "r2SCAN":
1453+
config_updates |= {"BPARAM": 11.95, "CPARAM": 0.0093, "LUSE_VDW": True}
1454+
else:
1455+
raise ValueError(
1456+
"Use of rVV10 with functionals other than r2 / SCAN is not currently supported in VASP."
1457+
)
1458+
1459+
elif self.dispersion == "D4":
1460+
d4_pars = {
1461+
"r2SCAN": {
1462+
"S6": 1.0,
1463+
"S8": 0.60187490,
1464+
"A1": 0.51559235,
1465+
"A2": 5.77342911,
1466+
},
1467+
"PBE": {
1468+
"S6": 1.0,
1469+
"S8": 0.95948085,
1470+
"A1": 0.38574991,
1471+
"A2": 4.80688534,
1472+
},
1473+
"PBEsol": {
1474+
"S6": 1.0,
1475+
"S8": 1.71885698,
1476+
"A1": 0.47901421,
1477+
"A2": 5.96771589,
1478+
},
1479+
}
1480+
config_updates |= {"IVDW": 13, **{f"VDW_{k}": v for k, v in d4_pars[self.xc_functional].items()}}
1481+
1482+
if len(config_updates) > 0:
1483+
self._config_dict["INCAR"].update(config_updates)
1484+
1485+
@staticmethod
1486+
def _sigmoid_interp(
1487+
bg, min_dk: float = 0.22, max_dk: float = 0.5, shape: float = 0.43, center: float = 4.15, fac: float = 12.0
1488+
):
1489+
delta = shape * (bg - center)
1490+
sigmoid = delta / (1.0 + delta**fac) ** (1.0 / fac)
1491+
return 0.5 * (min_dk + max_dk + (max_dk - min_dk) * sigmoid)
1492+
1493+
def _multi_sigmoid_interp(
1494+
self,
1495+
bandgap: float,
1496+
dks: tuple[float, ...] = (0.22, 0.44, 0.5),
1497+
shape: tuple[float, ...] = (1.1, 2.5),
1498+
center: tuple[float, ...] = (2.35, 6.1),
1499+
fac: tuple[float, ...] = (8, 8),
1500+
bg_cut: tuple[float, ...] = (4.5,),
1501+
):
1502+
if bandgap < self.bandgap_tol:
1503+
return dks[0]
1504+
1505+
min_bds = [self.bandgap_tol, *bg_cut]
1506+
max_bds = [*bg_cut, np.inf]
1507+
1508+
for icut, min_bd in enumerate(min_bds):
1509+
if min_bd <= bandgap < max_bds[icut]:
1510+
return self._sigmoid_interp(
1511+
bandgap,
1512+
min_dk=dks[icut],
1513+
max_dk=dks[icut + 1],
1514+
shape=shape[icut],
1515+
center=center[icut],
1516+
fac=fac[icut],
1517+
)
1518+
1519+
return None
1520+
1521+
@property
1522+
def kspacing_update(self):
1523+
if self.bandgap is None:
1524+
return 0.22
1525+
return self._multi_sigmoid_interp(self.bandgap)
1526+
1527+
13781528
@dataclass
13791529
class MPMetalRelaxSet(VaspInputSet):
13801530
"""
@@ -1571,7 +1721,8 @@ def __post_init__(self) -> None:
15711721
)
15721722

15731723
if self.xc_functional.upper() == "R2SCAN":
1574-
self._config_dict["INCAR"].update({"METAGGA": "R2SCAN", "ALGO": "ALL", "GGA": None})
1724+
self._config_dict["INCAR"].update({"METAGGA": "R2SCAN", "ALGO": "ALL"})
1725+
self._config_dict["INCAR"].pop("GGA", None)
15751726
if self.xc_functional.upper().endswith("+U"):
15761727
self._config_dict["INCAR"]["LDAU"] = True
15771728

@@ -1601,6 +1752,7 @@ class MPScanStaticSet(MPScanRelaxSet):
16011752
def incar_updates(self) -> dict[str, Any]:
16021753
"""Updates to the INCAR config for this calculation type."""
16031754
updates: dict[str, Any] = {
1755+
"ALGO": "Fast",
16041756
"LREAL": False,
16051757
"NSW": 0,
16061758
"LORBIT": 11,
@@ -1626,6 +1778,49 @@ def incar_updates(self) -> dict[str, Any]:
16261778
return updates
16271779

16281780

1781+
@dataclass
1782+
class MP24StaticSet(MP24RelaxSet):
1783+
"""Create input files for a static calculation using MP24 parameters.
1784+
1785+
For class information, refer to `MP24RelaxSet`.
1786+
If you use this set, please consider citing the appropriate papers in `MP24RelaxSet`.
1787+
1788+
Args:
1789+
structure (Structure): Structure from previous run.
1790+
bandgap (float): Bandgap of the structure in eV. The bandgap is used to
1791+
compute the appropriate k-point density and determine the smearing settings.
1792+
lepsilon (bool): Whether to add static dielectric calculation
1793+
lcalcpol (bool): Whether to turn on evaluation of the Berry phase approximations
1794+
for electronic polarization.
1795+
**kwargs: Keywords supported by MP24RelaxSet.
1796+
"""
1797+
1798+
lepsilon: bool = False
1799+
lcalcpol: bool = False
1800+
inherit_incar: bool = False
1801+
auto_kspacing: bool = True
1802+
1803+
@property
1804+
def incar_updates(self) -> dict[str, Any]:
1805+
"""Updates to the INCAR config for this calculation type."""
1806+
updates: dict[str, Any] = {
1807+
"NSW": 0,
1808+
"LORBIT": 11,
1809+
"ISMEAR": -5,
1810+
}
1811+
1812+
if self.lepsilon:
1813+
# LPEAD=T: numerical evaluation of overlap integral prevents
1814+
# LRF_COMMUTATOR errors and can lead to better expt. agreement
1815+
# but produces slightly different results
1816+
updates |= {"IBRION": 8, "LEPSILON": True, "LPEAD": True, "NSW": 1, "NPAR": None}
1817+
1818+
if self.lcalcpol:
1819+
updates["LCALCPOL"] = True
1820+
1821+
return updates
1822+
1823+
16291824
@dataclass
16301825
class MPHSEBSSet(VaspInputSet):
16311826
"""Implementation of a VaspInputSet for HSE band structure computations.

0 commit comments

Comments
 (0)