From 55c7a05208e48f66232b41ed89b0e47927631c56 Mon Sep 17 00:00:00 2001 From: "Andrew S. Rosen" Date: Sat, 17 Feb 2024 14:03:42 -0800 Subject: [PATCH 1/6] Don't raise a `BadInputSetWarning` if relaxing a likely metal with ISMEAR = 0 and small SIGMA Closes #3633. Relaxing a metal with ISMEAR = 0 is fine, as noted in the VASP manual, provided SIGMA is sufficiently small (< 0.05 is the recommendation in the VASP manual). Signed-off-by: Andrew S. Rosen --- pymatgen/io/vasp/sets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pymatgen/io/vasp/sets.py b/pymatgen/io/vasp/sets.py index 0b841500cd2..05700c65e1e 100644 --- a/pymatgen/io/vasp/sets.py +++ b/pymatgen/io/vasp/sets.py @@ -743,9 +743,9 @@ def incar(self) -> Incar: BadInputSetWarning, ) - if all(k.is_metal for k in structure.composition) and incar.get("NSW", 0) > 0 and incar.get("ISMEAR", 1) < 1: + if all(k.is_metal for k in structure.composition) and incar.get("NSW", 0) > 0 and (incar.get("ISMEAR", 1) < 0 or (incar.get("ISMEAR", 1) == 1 and incar.get("SIGMA", 0.2) > 0.05)): warnings.warn( - "Relaxation of likely metal with ISMEAR < 1 detected. See VASP " + "Relaxation of likely metal with ISMEAR < 0 or ISMEAR = 1 with a small SIGMA detected. See VASP " "recommendations on ISMEAR for metals.", BadInputSetWarning, ) From d2e3336c23abbfc0ba76cd36acba116c5478f6cc Mon Sep 17 00:00:00 2001 From: "Andrew S. Rosen" Date: Sat, 17 Feb 2024 14:04:48 -0800 Subject: [PATCH 2/6] Update sets.py Signed-off-by: Andrew S. Rosen --- pymatgen/io/vasp/sets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymatgen/io/vasp/sets.py b/pymatgen/io/vasp/sets.py index 05700c65e1e..c5ca3a80ab0 100644 --- a/pymatgen/io/vasp/sets.py +++ b/pymatgen/io/vasp/sets.py @@ -743,7 +743,7 @@ def incar(self) -> Incar: BadInputSetWarning, ) - if all(k.is_metal for k in structure.composition) and incar.get("NSW", 0) > 0 and (incar.get("ISMEAR", 1) < 0 or (incar.get("ISMEAR", 1) == 1 and incar.get("SIGMA", 0.2) > 0.05)): + if all(k.is_metal for k in structure.composition) and incar.get("NSW", 0) > 0 and (incar.get("ISMEAR", 1) < 0 or (incar.get("ISMEAR", 1) == 0 and incar.get("SIGMA", 0.2) > 0.05)): warnings.warn( "Relaxation of likely metal with ISMEAR < 0 or ISMEAR = 1 with a small SIGMA detected. See VASP " "recommendations on ISMEAR for metals.", From ad967b84c860e35fcdf33977de24836acbc6cf91 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 22:05:47 +0000 Subject: [PATCH 3/6] pre-commit auto-fixes --- pymatgen/io/vasp/sets.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pymatgen/io/vasp/sets.py b/pymatgen/io/vasp/sets.py index c5ca3a80ab0..b74500fcd0c 100644 --- a/pymatgen/io/vasp/sets.py +++ b/pymatgen/io/vasp/sets.py @@ -743,7 +743,11 @@ def incar(self) -> Incar: BadInputSetWarning, ) - if all(k.is_metal for k in structure.composition) and incar.get("NSW", 0) > 0 and (incar.get("ISMEAR", 1) < 0 or (incar.get("ISMEAR", 1) == 0 and incar.get("SIGMA", 0.2) > 0.05)): + if ( + all(k.is_metal for k in structure.composition) + and incar.get("NSW", 0) > 0 + and (incar.get("ISMEAR", 1) < 0 or (incar.get("ISMEAR", 1) == 0 and incar.get("SIGMA", 0.2) > 0.05)) + ): warnings.warn( "Relaxation of likely metal with ISMEAR < 0 or ISMEAR = 1 with a small SIGMA detected. See VASP " "recommendations on ISMEAR for metals.", From 11ffc06fdd1a9c8f05a7b593fe0c98b8491ca207 Mon Sep 17 00:00:00 2001 From: "Andrew S. Rosen" Date: Sat, 17 Feb 2024 14:17:33 -0800 Subject: [PATCH 4/6] Update test_sets.py Signed-off-by: Andrew S. Rosen --- tests/io/vasp/test_sets.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/io/vasp/test_sets.py b/tests/io/vasp/test_sets.py index d041523ea0f..0f8c3135058 100644 --- a/tests/io/vasp/test_sets.py +++ b/tests/io/vasp/test_sets.py @@ -203,8 +203,7 @@ def test_metal_check(self): with pytest.warns( BadInputSetWarning, - match="Relaxation of likely metal with ISMEAR < 1 detected. " - "See VASP recommendations on ISMEAR for metals.", + match="Relaxation of likely metal with ISMEAR", ) as warns_metal: vis = self.set(structure) _ = vis.incar From b5e91d9b5009081f3d506f4ca112555e5143acea Mon Sep 17 00:00:00 2001 From: Janosh Riebesell Date: Wed, 21 Feb 2024 15:37:33 +0100 Subject: [PATCH 5/6] case-specific warnings same changes as in https://github.com/materialsproject/atomate2/pull/727/commits/fc165eb3 --- pymatgen/io/vasp/sets.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/pymatgen/io/vasp/sets.py b/pymatgen/io/vasp/sets.py index b74500fcd0c..cccd5ac45b0 100644 --- a/pymatgen/io/vasp/sets.py +++ b/pymatgen/io/vasp/sets.py @@ -743,15 +743,23 @@ def incar(self) -> Incar: BadInputSetWarning, ) + ismear = incar.get("ISMEAR", 1) + sigma = incar.get("SIGMA", 0.2) if ( - all(k.is_metal for k in structure.composition) + all(elem.is_metal for elem in structure.composition) and incar.get("NSW", 0) > 0 - and (incar.get("ISMEAR", 1) < 0 or (incar.get("ISMEAR", 1) == 0 and incar.get("SIGMA", 0.2) > 0.05)) + and (ismear < 0 or (ismear == 0 and sigma > 0.05)) ): + ismear_docs = "https://www.vasp.at/wiki/index.php/ISMEAR" + msg = "" + if ismear < 0: + msg = f"Relaxation of likely metal with ISMEAR < 0 ({ismear})." + elif ismear == 0 and sigma > 0.05: + msg = f"ISMEAR = 0 with a small SIGMA ({sigma}) detected." warnings.warn( - "Relaxation of likely metal with ISMEAR < 0 or ISMEAR = 1 with a small SIGMA detected. See VASP " - "recommendations on ISMEAR for metals.", + f"{msg} See VASP recommendations on ISMEAR for metals ({ismear_docs}).", BadInputSetWarning, + stacklevel=1, ) return incar From cf348fd66f48731b1b3f786d39b57eeb0450f19a Mon Sep 17 00:00:00 2001 From: Janosh Riebesell Date: Wed, 21 Feb 2024 15:39:08 +0100 Subject: [PATCH 6/6] test both cases --- tests/files/.pytest-split-durations | 2 +- tests/io/vasp/test_sets.py | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/tests/files/.pytest-split-durations b/tests/files/.pytest-split-durations index 7f5492de099..465fac2bb5f 100644 --- a/tests/files/.pytest-split-durations +++ b/tests/files/.pytest-split-durations @@ -2210,7 +2210,7 @@ "tests/io/vasp/test_sets.py::TestMITMPRelaxSet::test_hubbard_off_and_ediff_override": 0.004546375945210457, "tests/io/vasp/test_sets.py::TestMITMPRelaxSet::test_incar_lmaxmix": 0.008337250037584454, "tests/io/vasp/test_sets.py::TestMITMPRelaxSet::test_lda_potcar": 0.035044250020291656, - "tests/io/vasp/test_sets.py::TestMITMPRelaxSet::test_metal_check": 0.006276416010223329, + "tests/io/vasp/test_sets.py::TestMITMPRelaxSet::test_warnings": 0.006276416010223329, "tests/io/vasp/test_sets.py::TestMITMPRelaxSet::test_nelect": 1.6427247499814257, "tests/io/vasp/test_sets.py::TestMITMPRelaxSet::test_poscar": 0.006406874977983534, "tests/io/vasp/test_sets.py::TestMITMPRelaxSet::test_potcar_special_defaults": 0.008440207981038839, diff --git a/tests/io/vasp/test_sets.py b/tests/io/vasp/test_sets.py index 0f8c3135058..d44dffae87f 100644 --- a/tests/io/vasp/test_sets.py +++ b/tests/io/vasp/test_sets.py @@ -198,22 +198,33 @@ def test_no_structure_init(self): assert vis.as_dict()["structure"] is not None assert "structure" not in vis.as_dict(verbosity=1) - def test_metal_check(self): + def test_warnings(self): structure = Structure.from_spacegroup("Fm-3m", Lattice.cubic(3), ["Cu"], [[0, 0, 0]]) - with pytest.warns( - BadInputSetWarning, - match="Relaxation of likely metal with ISMEAR", - ) as warns_metal: - vis = self.set(structure) + vis = self.set(structure) + with pytest.warns(BadInputSetWarning) as warns_metal: _ = vis.incar assert len(warns_metal) == 1 + vasp_docs_link = "See VASP recommendations on ISMEAR for metals (https://www.vasp.at/wiki/index.php/ISMEAR)." + assert ( + str(warns_metal[0].message) + == f"Relaxation of likely metal with ISMEAR < 0 ({vis.incar['ISMEAR']}). {vasp_docs_link}" + ) + + # test different warning for ismear == 0 and sigma > 0.05 + vis = self.set(structure, user_incar_settings={"ISMEAR": 0, "SIGMA": 0.1}) + with pytest.warns(BadInputSetWarning) as warns_metal: + _ = vis.incar + assert len(warns_metal) == 1 + assert ( + str(warns_metal[0].message) + == f"ISMEAR = 0 with a small SIGMA ({vis.incar['SIGMA']}) detected. {vasp_docs_link}" + ) with pytest.warns( BadInputSetWarning, match="Large KSPACING value detected with ISMEAR = -5. Ensure that VASP " - "generates an adequate number of KPOINTS, lower KSPACING, or " - "set ISMEAR = 0", + "generates an adequate number of KPOINTS, lower KSPACING, or set ISMEAR = 0", ) as warns_kspacing: vis = self.set(structure, user_incar_settings={"KSPACING": 1, "ISMEAR": -5}) _ = vis.incar