From f7c92fa76adf9ef89adaf9a7b370146f64a974e6 Mon Sep 17 00:00:00 2001 From: Janosh Riebesell Date: Wed, 15 Nov 2023 12:02:36 -0800 Subject: [PATCH] Define `PBE64Base.yaml` for new VASP PBE_64 POTCARs (#3470) * add pymatgen/io/vasp/PBE64Base.yaml * update MatPESStaticSet PARENT to PBE64Base * update MatPES known_hash and add PBE64Base hash in test_sets.py * fix TestMatPESStaticSet to expect PBE_64 as default POTCARs * use monty zpath in generate_fake_potcar_libraries * fix TestWavecar.test_standard ValueError Invalid rtag=-9223372036854775808, must be one of {45200, 45210, 53300, 53310} /home/runner/work/pymatgen/pymatgen/pymatgen/io/vasp/outputs.py:4252 --- dev_scripts/potcar_scrambler.py | 9 +-- pymatgen/apps/borg/hive.py | 3 +- pymatgen/io/vasp/MatPESStaticSet.yaml | 2 +- pymatgen/io/vasp/PBE64Base.yaml | 101 ++++++++++++++++++++++++++ pymatgen/io/vasp/outputs.py | 2 +- pymatgen/io/vasp/sets.py | 9 ++- tests/io/vasp/test_sets.py | 25 ++++--- 7 files changed, 127 insertions(+), 24 deletions(-) create mode 100644 pymatgen/io/vasp/PBE64Base.yaml diff --git a/dev_scripts/potcar_scrambler.py b/dev_scripts/potcar_scrambler.py index 358cdc6d799..e7487819359 100644 --- a/dev_scripts/potcar_scrambler.py +++ b/dev_scripts/potcar_scrambler.py @@ -5,6 +5,7 @@ import warnings import numpy as np +from monty.os.path import zpath from monty.serialization import zopen from pymatgen.core import SETTINGS @@ -51,7 +52,7 @@ def _rand_float_from_str_with_prec(self, input_str: str, bloat: float = 1.5): def _read_fortran_str_and_scramble(self, input_str: str, bloat: float = 1.5): input_str = input_str.strip() - if input_str.lower() in ["t", "f"] or input_str.lower() in ["true", "false"]: + if input_str.lower() in ("t", "f", "true", "false"): return bool(np.random.randint(2)) if input_str.upper() == input_str.lower() and input_str[0].isnumeric(): @@ -128,10 +129,8 @@ def generate_fake_potcar_libraries(): for psp_name in psp_variants: rebase_dir = f"{output_dir}/{func_dir}/{psp_name}/" paths_to_try = [ - f"{func_dir}/POTCAR.{psp_name}", - f"{func_dir}/POTCAR.{psp_name}.gz", - f"{func_dir}/{psp_name}/POTCAR", - f"{func_dir}/{psp_name}/POTCAR.gz", + zpath(f"{func_dir}/POTCAR.{psp_name}"), + zpath(f"{func_dir}/{psp_name}/POTCAR"), ] if not any(map(os.path.isfile, paths_to_try)): warnings.warn(f"Could not find {psp_name} in {paths_to_try}") diff --git a/pymatgen/apps/borg/hive.py b/pymatgen/apps/borg/hive.py index 46294b59d93..c1256c68884 100644 --- a/pymatgen/apps/borg/hive.py +++ b/pymatgen/apps/borg/hive.py @@ -195,8 +195,7 @@ class SimpleVaspToComputedEntryDrone(VaspToComputedEntryDrone): def __init__(self, inc_structure=False): """ Args: - inc_structure (bool): Set to True if you want - ComputedStructureEntries to be returned instead of + inc_structure (bool): Set to True if you want ComputedStructureEntries to be returned instead of ComputedEntries. Structure will be parsed from the CONTCAR. """ self._inc_structure = inc_structure diff --git a/pymatgen/io/vasp/MatPESStaticSet.yaml b/pymatgen/io/vasp/MatPESStaticSet.yaml index ddcc90f6d86..4238bfe5c30 100644 --- a/pymatgen/io/vasp/MatPESStaticSet.yaml +++ b/pymatgen/io/vasp/MatPESStaticSet.yaml @@ -1,7 +1,7 @@ # Default VASP settings for static calculations in the MatPES Project # using the Regularized-Restored Strongly Constrained and Appropriately # Normed functional (default PBE, PBE+U or R2SCAN or R2SCAN+U). -PARENT: PBE54Base +PARENT: PBE64Base INCAR: ALGO: Normal # Normal for PBE, ALL for R2SCAN, included to have some reasonable default EDIFF: 1.e-05 diff --git a/pymatgen/io/vasp/PBE64Base.yaml b/pymatgen/io/vasp/PBE64Base.yaml new file mode 100644 index 00000000000..af0236253ed --- /dev/null +++ b/pymatgen/io/vasp/PBE64Base.yaml @@ -0,0 +1,101 @@ +# POTCARs for PBE_64 +PARENT: VASPIncarBase +POTCAR_FUNCTIONAL: PBE_64 +POTCAR: + Ac: Ac + Ag: Ag + Al: Al + Am: Am + Ar: Ar + As: As + At: At + Au: Au + B: B + Ba: Ba_sv + Be: Be_sv + Bi: Bi + Br: Br + C: C + Ca: Ca_sv + Cd: Cd + Ce: Ce + Cf: Cf + Cl: Cl + Cm: Cm + Co: Co + Cr: Cr_pv + Cs: Cs_sv + Cu: Cu_pv + Dy: Dy_3 + Er: Er_3 + Eu: Eu + F: F + Fe: Fe_pv + Fr: Fr_sv + Ga: Ga_d + Gd: Gd + Ge: Ge_d + H: H + He: He + Hf: Hf_pv + Hg: Hg + Ho: Ho_3 + I: I + In: In_d + Ir: Ir + K: K_sv + Kr: Kr + La: La + Li: Li_sv + Lu: Lu_3 + Mg: Mg_pv + Mn: Mn_pv + Mo: Mo_pv + N: N + Na: Na_pv + Nb: Nb_pv + Nd: Nd_3 + Ne: Ne + Ni: Ni_pv + Np: Np + O: O + Os: Os_pv + P: P + Pa: Pa + Pb: Pb_d + Pd: Pd + Pm: Pm_3 + Po: Po_d + Pr: Pr_3 + Pt: Pt + Pu: Pu + Ra: Ra_sv + Rb: Rb_sv + Re: Re_pv + Rh: Rh_pv + Rn: Rn + Ru: Ru_pv + S: S + Sb: Sb + Sc: Sc_sv + Se: Se + Si: Si + Sm: Sm_3 + Sn: Sn_d + Sr: Sr_sv + Ta: Ta_pv + Tb: Tb_3 + Tc: Tc_pv + Te: Te + Th: Th + Ti: Ti_pv + Tl: Tl_d + Tm: Tm_3 + U: U + V: V_pv + W: W_sv + Xe: Xe + Y: Y_sv + Yb: Yb_3 + Zn: Zn + Zr: Zr_sv diff --git a/pymatgen/io/vasp/outputs.py b/pymatgen/io/vasp/outputs.py index 2f3bbc2fee3..ff5d840944c 100644 --- a/pymatgen/io/vasp/outputs.py +++ b/pymatgen/io/vasp/outputs.py @@ -596,7 +596,7 @@ def hubbards(self) -> dict[str, float]: if len(js) != len(us): js = [0] * len(us) if len(us) == len(symbols): - return {symbols[i]: us[i] - js[i] for i in range(len(symbols))} + return {symbols[idx]: us[idx] - js[idx] for idx in range(len(symbols))} if sum(us) == 0 and sum(js) == 0: return {} raise VaspParseError("Length of U value parameters and atomic symbols are mismatched") diff --git a/pymatgen/io/vasp/sets.py b/pymatgen/io/vasp/sets.py index 027c758237b..1dde636684f 100644 --- a/pymatgen/io/vasp/sets.py +++ b/pymatgen/io/vasp/sets.py @@ -1270,9 +1270,12 @@ def __init__( self._config_dict["INCAR"].pop("GGA", None) if xc_functional.upper().endswith("+U"): self._config_dict["INCAR"]["LDAU"] = True - user_potcar_functional = kwargs.get("user_potcar_functional", "PBE_54") - if user_potcar_functional.upper() != "PBE_54": - warnings.warn(f"{user_potcar_functional=} is inconsistent with the recommended PBE_54.", UserWarning) + default_potcars = self.CONFIG["PARENT"].replace("PBE", "PBE_").replace("BASE", "") # PBE64BASE -> PBE_64 + user_potcar_functional = kwargs.get("user_potcar_functional", default_potcars) + if user_potcar_functional.upper() != default_potcars: + warnings.warn( + f"{user_potcar_functional=} is inconsistent with the recommended {default_potcars}.", UserWarning + ) self.kwargs = kwargs self.xc_functional = xc_functional diff --git a/tests/io/vasp/test_sets.py b/tests/io/vasp/test_sets.py index 5d4fb26be4c..6ef2efe2507 100644 --- a/tests/io/vasp/test_sets.py +++ b/tests/io/vasp/test_sets.py @@ -111,7 +111,7 @@ def test_sets_changed(self): hashes[name] = hashlib.sha1(text).hexdigest() known_hashes = { - "MatPESStaticSet.yaml": "8789f974913c935f21ff2fbffc0502714ca39470", + "MatPESStaticSet.yaml": "8edecff2bbd1932c53159f56a8e6340e900aaa2f", "MITRelaxSet.yaml": "1a0970f8cad9417ec810f7ab349dc854eaa67010", "MPAbsorptionSet.yaml": "5931e1cb3cf8ba809b3d4f4a5960d728c682adf1", "MPHSERelaxSet.yaml": "0d0d96a620461071cfd416ec9d5d6a8d2dfd0855", @@ -120,12 +120,13 @@ def test_sets_changed(self): "MVLGWSet.yaml": "104ae93c3b3be19a13b0ee46ebdd0f40ceb96597", "MVLRelax52Set.yaml": "4cfc6b1bd0548e45da3bde4a9c65b3249da13ecd", "PBE54Base.yaml": "ec317781a7f344beb54c17a228db790c0eb49282", + "PBE64Base.yaml": "a0d6cd02c6ff8e24b0005e30c56a33b155c2280b", "VASPIncarBase.yaml": "19762515f8deefb970f2968fca48a0d67f7964d4", "vdW_parameters.yaml": "04bb09bb563d159565bcceac6a11e8bdf0152b79", } for input_set in hashes: - assert hashes[input_set] == known_hashes[input_set], f"{input_set} got {hashes[input_set]}\n\n{msg}" + assert hashes[input_set] == known_hashes[input_set], f"{input_set=}\n{msg}" class TestDictSet(PymatgenTest): @@ -774,12 +775,12 @@ def test_default(self): assert incar["PREC"] == "Accurate" assert incar["SIGMA"] == 0.05 assert incar["LMAXMIX"] == 6 - # test POTCAR files are default PBE_54 PSPs and functional + # test POTCAR files are default PBE_64 PSPs and functional assert input_set.potcar_symbols == ["Fe_pv", "P", "O"] - assert input_set.potcar.functional == "PBE_54" + assert input_set.potcar.functional == "PBE_64" assert input_set.kpoints is None - assert str(input_set.potcar[0]) == str(PotcarSingle.from_symbol_and_functional("Fe_pv", "PBE_54")) + assert str(input_set.potcar[0]) == str(PotcarSingle.from_symbol_and_functional("Fe_pv", "PBE_64")) def test_with_prev_incar(self): default_prev = MatPESStaticSet(structure=self.struct, prev_incar=self.prev_incar) @@ -811,9 +812,9 @@ def test_with_prev_incar(self): assert incar["NSW"] == 0 assert incar["PREC"] == "Accurate" assert incar["SIGMA"] == 0.05 - # test POTCAR files are default PBE_54 PSPs and functional + # test POTCAR files are default PBE_64 PSPs and functional assert default_prev.potcar_symbols == ["Fe_pv", "P", "O"] - assert default_prev.potcar.functional == "PBE_54" + assert default_prev.potcar.functional == "PBE_64" assert default_prev.kpoints is None def test_r2scan(self): @@ -823,9 +824,9 @@ def test_r2scan(self): assert incar_scan.get("GGA") is None assert incar_scan["ALGO"] == "All" assert incar_scan.get("LDAU") is None - # test POTCAR files are default PBE_54 PSPs and functional + # test POTCAR files are default PBE_64 PSPs and functional assert scan.potcar_symbols == ["Fe_pv", "P", "O"] - assert scan.potcar.functional == "PBE_54" + assert scan.potcar.functional == "PBE_64" assert scan.kpoints is None def test_default_u(self): @@ -834,10 +835,10 @@ def test_default_u(self): assert incar_u["LDAU"] is True assert incar_u["GGA"] == "Pe" assert incar_u["ALGO"] == "Normal" - # test POTCAR files are default PBE_54 PSPs and functional + # test POTCAR files are default PBE_64 PSPs and functional assert incar_u["LDAUU"] == [5.3, 0, 0] assert default_u.potcar_symbols == ["Fe_pv", "P", "O"] - assert default_u.potcar.functional == "PBE_54" + assert default_u.potcar.functional == "PBE_64" assert default_u.kpoints is None def test_functionals(self): @@ -847,7 +848,7 @@ def test_functionals(self): ): MatPESStaticSet(self.struct, xc_functional=xc_functional) - with pytest.warns(UserWarning, match="inconsistent with the recommended PBE_54"): + with pytest.warns(UserWarning, match="inconsistent with the recommended PBE_64"): diff_potcar = MatPESStaticSet(self.struct, user_potcar_functional="PBE") assert str(diff_potcar.potcar[0]) == str(PotcarSingle.from_symbol_and_functional("Fe_pv", "PBE"))