diff --git a/src/atomate2/vasp/jobs/mp.py b/src/atomate2/vasp/jobs/mp.py index 6bf576a2ab..3a1cdbcee6 100644 --- a/src/atomate2/vasp/jobs/mp.py +++ b/src/atomate2/vasp/jobs/mp.py @@ -55,7 +55,9 @@ class MPGGARelaxMaker(BaseVaspMaker): name: str = "MP GGA relax" input_set_generator: VaspInputGenerator = field( - default_factory=lambda: MPRelaxSet(force_gamma=True, auto_metal_kpoints=True) + default_factory=lambda: MPRelaxSet( + force_gamma=True, auto_metal_kpoints=True, inherit_incar=False + ) ) @@ -90,7 +92,9 @@ class MPGGAStaticMaker(BaseVaspMaker): name: str = "MP GGA static" input_set_generator: VaspInputGenerator = field( - default_factory=lambda: MPStaticSet(force_gamma=True, auto_metal_kpoints=True) + default_factory=lambda: MPStaticSet( + force_gamma=True, auto_metal_kpoints=True, inherit_incar=False + ) ) @@ -127,6 +131,7 @@ class MPPreRelaxMaker(BaseVaspMaker): input_set_generator: VaspInputGenerator = field( default_factory=lambda: MPScanRelaxSet( auto_ismear=False, + inherit_incar=False, user_incar_settings={ "EDIFFG": -0.05, "GGA": "PS", @@ -172,6 +177,7 @@ class MPMetaGGARelaxMaker(BaseVaspMaker): input_set_generator: VaspInputGenerator = field( default_factory=lambda: MPScanRelaxSet( auto_ismear=False, + inherit_incar=False, user_incar_settings={ "GGA": None, # unset GGA, shouldn't be set anyway but best be sure "LCHARG": True, diff --git a/tests/vasp/jobs/test_mp.py b/tests/vasp/jobs/test_mp.py index 1b09858c76..3b5a25685c 100644 --- a/tests/vasp/jobs/test_mp.py +++ b/tests/vasp/jobs/test_mp.py @@ -1,3 +1,6 @@ +from collections.abc import Callable +from pathlib import Path + import pytest from emmet.core.tasks import TaskDoc from jobflow import run_locally @@ -6,6 +9,7 @@ from atomate2.vasp.jobs.mp import ( MPGGARelaxMaker, + MPGGAStaticMaker, MPMetaGGARelaxMaker, MPMetaGGAStaticMaker, MPPreRelaxMaker, @@ -32,6 +36,7 @@ def test_mp_pre_relax_maker_default_values(): for key, expected in expected_incar.items(): actual = maker.input_set_generator.config_dict["INCAR"][key] assert actual == expected, f"{key=}, {actual=}, {expected=}" + assert maker.input_set_generator.inherit_incar is False def test_mp_meta_gga_relax_maker_default_values(): @@ -41,9 +46,12 @@ def test_mp_meta_gga_relax_maker_default_values(): for key, expected in expected_incar.items(): actual = maker.input_set_generator.config_dict["INCAR"][key] assert actual == expected, f"{key=}, {actual=}, {expected=}" + assert maker.input_set_generator.inherit_incar is False -def test_mp_meta_gga_static_maker(mock_vasp, clean_dir, vasp_test_dir): +def test_mp_meta_gga_static_maker( + mock_vasp: Callable, clean_dir: None, vasp_test_dir: Path +): # map from job name to directory containing reference input/output files ref_paths = { "MP meta-GGA static": "Si_mp_meta_gga_relax/r2scan_final_static", @@ -57,11 +65,11 @@ def test_mp_meta_gga_static_maker(mock_vasp, clean_dir, vasp_test_dir): mock_vasp(ref_paths, fake_run_vasp_kwargs) - job = MPMetaGGAStaticMaker( - input_set_generator=MPScanRelaxSet( - bandgap=0.8249, user_incar_settings={"LWAVE": True, "LCHARG": True} - ) - ).make(si_struct) + input_set_gen = MPScanRelaxSet( + bandgap=0.8249, user_incar_settings={"LWAVE": True, "LCHARG": True} + ) + maker = MPMetaGGAStaticMaker(input_set_generator=input_set_gen) + job = maker.make(si_struct) # ensure flow runs successfully responses = run_locally(job, create_folders=True, ensure_success=True) @@ -70,9 +78,12 @@ def test_mp_meta_gga_static_maker(mock_vasp, clean_dir, vasp_test_dir): task_doc = responses[job.uuid][1].output assert isinstance(task_doc, TaskDoc) assert task_doc.output.energy == pytest.approx(-46.8613738) + assert maker.input_set_generator.inherit_incar is False -def test_mp_meta_gga_relax_maker(mock_vasp, clean_dir, vasp_test_dir): +def test_mp_meta_gga_relax_maker( + mock_vasp: Callable, clean_dir: None, vasp_test_dir: Path +): # map from job name to directory containing reference input/output files ref_paths = { "MP meta-GGA relax": "Si_mp_meta_gga_relax/r2scan_relax", @@ -88,11 +99,11 @@ def test_mp_meta_gga_relax_maker(mock_vasp, clean_dir, vasp_test_dir): mock_vasp(ref_paths, fake_run_vasp_kwargs) - job = MPMetaGGARelaxMaker( - input_set_generator=MPScanRelaxSet( - bandgap=0.4786, user_incar_settings={"LWAVE": True, "LCHARG": True} - ) - ).make(si_struct) + input_set_gen = MPScanRelaxSet( + bandgap=0.4786, user_incar_settings={"LWAVE": True, "LCHARG": True} + ) + maker = MPMetaGGARelaxMaker(input_set_generator=input_set_gen) + job = maker.make(si_struct) # ensure flow runs successfully responses = run_locally(job, create_folders=True, ensure_success=True) @@ -101,9 +112,10 @@ def test_mp_meta_gga_relax_maker(mock_vasp, clean_dir, vasp_test_dir): task_doc = responses[job.uuid][1].output assert isinstance(task_doc, TaskDoc) assert task_doc.output.energy == pytest.approx(-46.86703814) + assert maker.input_set_generator.inherit_incar is False -def test_mp_gga_relax_maker(mock_vasp, clean_dir, vasp_test_dir): +def test_mp_gga_relax_maker(mock_vasp: Callable, clean_dir: None, vasp_test_dir: Path): # map from job name to directory containing reference input/output files ref_paths = { "MP GGA relax": "Si_mp_gga_relax/GGA_Relax_1", @@ -117,7 +129,8 @@ def test_mp_gga_relax_maker(mock_vasp, clean_dir, vasp_test_dir): mock_vasp(ref_paths, fake_run_vasp_kwargs) - job = MPGGARelaxMaker().make(si_struct) + maker = MPGGARelaxMaker() + job = maker.make(si_struct) # ensure flow runs successfully responses = run_locally(job, create_folders=True, ensure_success=True) @@ -126,3 +139,17 @@ def test_mp_gga_relax_maker(mock_vasp, clean_dir, vasp_test_dir): task_doc = responses[job.uuid][1].output assert isinstance(task_doc, TaskDoc) assert task_doc.output.energy == pytest.approx(-10.84140641) + assert maker.input_set_generator.inherit_incar is False + + +# TODO ideally should have a set of ref files and a full test for an MP static calc +def test_mp_gga_static_maker_prev_dir(vasp_test_dir: Path): + prev_dir = f"{vasp_test_dir}/Si_hse_band_structure/hse_static/outputs" + structure = Structure.from_file(f"{prev_dir}/POSCAR.gz") + + maker = MPGGAStaticMaker() + input_set = maker.input_set_generator.get_input_set( + structure=structure, potcar_spec=True, prev_dir=prev_dir + ) + assert input_set.incar["ENCUT"] == 520 + assert maker.input_set_generator.inherit_incar is False