diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index dd5d8f93dc..58d36f0190 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -58,7 +58,7 @@ jobs: - name: Install conda dependencies run: | - micromamba install -n a2 -c conda-forge enumlib packmol bader openbabel openff-toolkit==0.16.2 openff-interchange==0.3.22 --yes + micromamba install -n a2 -c conda-forge enumlib packmol bader --yes - name: Install dependencies run: | @@ -87,7 +87,7 @@ jobs: # However this `splitting-algorithm` means that tests cannot depend sensitively on the order they're executed in. run: | micromamba activate a2 - pytest --splits 3 --group ${{ matrix.split }} --durations-path tests/.pytest-split-durations --splitting-algorithm least_duration --ignore=tests/ase --cov=atomate2 --cov-report=xml + pytest --splits 3 --group ${{ matrix.split }} --durations-path tests/.pytest-split-durations --splitting-algorithm least_duration --ignore=tests/ase --ignore=tests/openff_md --ignore=tests/openmm_md --cov=atomate2 --cov-report=xml - uses: codecov/codecov-action@v1 @@ -97,6 +97,62 @@ jobs: name: coverage${{ matrix.split }} file: ./coverage.xml + test-openff: + # prevent this action from running on forks + if: github.repository == 'materialsproject/atomate2' + + services: + local_mongodb: + image: mongo:4.0 + ports: + - 27017:27017 + + runs-on: ubuntu-latest + defaults: + run: + shell: bash -l {0} # enables conda/mamba env activation by reading bash profile + strategy: + matrix: + python-version: ["3.10","3.11","3.12"] + + steps: + - name: Check out repo + uses: actions/checkout@v4 + + - name: Set up micromamba + uses: mamba-org/setup-micromamba@main + + - name: Create mamba environment + run: | + micromamba create -n a2 python=${{ matrix.python-version }} --yes + + - name: Install uv + run: micromamba run -n a2 pip install uv + + - name: Install conda dependencies + run: | + micromamba install -n a2 -c conda-forge enumlib packmol bader openbabel openff-toolkit==0.16.2 openff-interchange==0.3.22 --yes + + - name: Install dependencies + run: | + micromamba activate a2 + python -m pip install --upgrade pip + uv pip install .[strict-openff,tests] + + - name: Install pymatgen from master if triggered by pymatgen repo dispatch + if: github.event_name == 'repository_dispatch' && github.event.action == 'pymatgen-ci-trigger' + run: | + micromamba activate a2 + uv pip install --upgrade 'git+https://github.com/materialsproject/pymatgen@${{ github.event.client_payload.pymatgen_ref }}' + + - name: Test split ${{ matrix.split }} + env: + MP_API_KEY: ${{ secrets.MP_API_KEY }} + + run: | + micromamba activate a2 + pytest tests/{openff_md,openmm_md} + test-notebooks-and-ase: # prevent this action from running on forks if: github.repository == 'materialsproject/atomate2' diff --git a/pyproject.toml b/pyproject.toml index 3aafaeea17..9993055d39 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ dependencies = [ "custodian>=2024.4.18", "emmet-core>=0.84.3rc3", "jobflow>=0.1.11", - "monty>=2024.7.30", + "monty>=2024.12.10", "numpy", "pydantic-settings>=2.0.3", "pydantic>=2.0.1", @@ -104,23 +104,27 @@ strict = [ "ijson==3.3.0", "jobflow==0.1.19", "lobsterpy==0.4.9", - "mdanalysis==2.7.0", - "monty==2024.10.21", - "mp-api==0.43.0", + "monty==2025.1.9", + "mp-api==0.45.3", "numpy", - "openmm-mdanalysis-reporter==0.1.0", - "openmm==8.1.1", "phonopy==2.30.1", "pydantic-settings==2.7.0", "pydantic==2.9.2", "pymatgen-analysis-defects==2024.10.22", - "pymatgen==2024.11.13", + "pymatgen==2025.2.18", "pymongo==4.10.1", "python-ulid==3.0.0", "seekpath==2.1.0", "tblite==0.3.0; python_version < '3.12'", "typing-extensions==4.12.2", ] +strict-openff = [ + "mdanalysis==2.7.0", + "monty==2024.12.10", + "openmm-mdanalysis-reporter==0.1.0", + "openmm==8.1.1", + "pymatgen==2024.11.13", +] strict-forcefields = [ "calorine==3.0", "chgnet==0.4.0", diff --git a/src/atomate2/common/jobs/utils.py b/src/atomate2/common/jobs/utils.py index c305a85ed2..3bc92583d6 100644 --- a/src/atomate2/common/jobs/utils.py +++ b/src/atomate2/common/jobs/utils.py @@ -2,14 +2,20 @@ from __future__ import annotations +import os from typing import TYPE_CHECKING from jobflow import Response, job +from monty.os.path import zpath +from pymatgen.command_line.bader_caller import bader_analysis_from_path from pymatgen.symmetry.analyzer import SpacegroupAnalyzer from atomate2 import SETTINGS if TYPE_CHECKING: + from collections.abc import Sequence + from pathlib import Path + from pymatgen.core import Structure @@ -137,3 +143,62 @@ def retrieve_structure_from_materials_project( output=structure, stored_data={"task_id": task_id, "database_version": database_version}, ) + + +@job +def remove_workflow_files( + directories: Sequence[str], file_names: Sequence[str], allow_zpath: bool = True +) -> list[str]: + """ + Remove files from previous jobs. + + For example, at the end of an MP flow, WAVECAR files are generated + that take up a lot of disk space. + This utility can automatically remove them following a workflow. + + Parameters + ---------- + makers : Sequence[Maker, Flow, Job] + Jobs in the flow on which to remove files. + file_names : Sequence[str] + The list of file names to remove, ex. ["WAVECAR"] rather than a full path + allow_zpath : bool = True + Whether to allow checking for gzipped output using `monty.os.zpath` + + Returns + ------- + list[str] : list of removed files + """ + abs_paths = [os.path.abspath(dir_name.split(":")[-1]) for dir_name in directories] + + removed_files = [] + for job_dir in abs_paths: + for file in file_names: + file_name = os.path.join(job_dir, file) + if allow_zpath: + file_name = zpath(file_name) + + if os.path.isfile(file_name): + removed_files.append(file_name) + os.remove(file_name) + + return removed_files + + +@job +def bader_analysis(dir_name: str | Path, suffix: str | None = None) -> dict: + """Run Bader charge analysis as a job. + + Parameters + ---------- + dir_name : str or Path + The name of the directory to run Bader in. + suffix : str or None (default) + Suffixes of the files to filter by. + + Returns + ------- + dict of bader charge analysis which is JSONable. + """ + dir_name = os.path.abspath(str(dir_name).split(":")[-1]) + return bader_analysis_from_path(dir_name, suffix=suffix or "") diff --git a/src/atomate2/common/utils.py b/src/atomate2/common/utils.py index ce7e0c4da8..d8e3c1bc43 100644 --- a/src/atomate2/common/utils.py +++ b/src/atomate2/common/utils.py @@ -194,3 +194,18 @@ def parse_additional_json(dir_name: Path) -> dict[str, Any]: if key not in ("custodian", "transformations", "FW"): additional_json[key] = loadfn(filename, cls=None) return additional_json + + +def _recursive_get_dir_names(jobs: list, dir_names: list) -> None: + """Recursively get all `output.dir_name` from a list of jobs. + + Parameters + ---------- + jobs : list of jobs, Makers, Flows, etc. + dir_names : a list to add the `dir_name`'s to. + """ + for a_job in jobs: + if (sub_jobs := getattr(a_job, "jobs", None)) is not None: + _recursive_get_dir_names(sub_jobs, dir_names) + else: + dir_names.append(a_job.output.dir_name) diff --git a/src/atomate2/vasp/flows/mp.py b/src/atomate2/vasp/flows/mp.py index 76bce471aa..d2a0490883 100644 --- a/src/atomate2/vasp/flows/mp.py +++ b/src/atomate2/vasp/flows/mp.py @@ -15,10 +15,15 @@ from jobflow import Flow, Maker from pymatgen.io.vasp.sets import LobsterSet +from atomate2.common.jobs.utils import remove_workflow_files +from atomate2.common.utils import _recursive_get_dir_names from atomate2.lobster.jobs import LobsterMaker from atomate2.vasp.flows.core import DoubleRelaxMaker from atomate2.vasp.flows.lobster import VaspLobsterMaker from atomate2.vasp.jobs.mp import ( + MP24PreRelaxMaker, + MP24RelaxMaker, + MP24StaticMaker, MPGGARelaxMaker, MPGGAStaticMaker, MPMetaGGARelaxMaker, @@ -29,6 +34,7 @@ logger = logging.getLogger(__name__) if TYPE_CHECKING: + from collections.abc import Sequence from pathlib import Path from pymatgen.core.structure import Structure @@ -194,6 +200,95 @@ def make(self, structure: Structure, prev_dir: str | Path | None = None) -> Flow return Flow(jobs=jobs, output=output, name=self.name) +@dataclass +class MP24DoubleRelaxMaker(DoubleRelaxMaker): + """MP24 PBEsol + r2SCAN double relaxation workflow. + + Parameters + ---------- + name : str + Name of the flows produced by this maker. + relax_maker1 : .BaseVaspMaker + Maker to generate the first relaxation. + relax_maker2 : .BaseVaspMaker + Maker to generate the second relaxation. + """ + + name: str = "MP24 double relax" + relax_maker1: Maker | None = field(default_factory=MP24PreRelaxMaker) + relax_maker2: Maker = field( + default_factory=lambda: MP24RelaxMaker( + copy_vasp_kwargs={"additional_vasp_files": ("WAVECAR", "CHGCAR")} + ) + ) + + +@dataclass +class MP24DoubleRelaxStaticMaker(Maker): + """MP24 workflow to relax a structure with r2SCAN. + + Optionally, files can be automatically cleaned following completion + of the workflow. By default, WAVECAR files are removed. + + Parameters + ---------- + name : str + Name of the flows produced by this maker. + relax_maker : .BaseVaspMaker + Maker to generate the relaxation. + static_maker : .BaseVaspMaker + Maker to generate the static calculation before the relaxation. + clean_files : Sequence of str or None + If a list of strings, names of files to remove following the workflow. + By default, this removes the WAVECAR files (gzipped or not). + """ + + name: str = "MP24 r2SCAN workflow" + relax_maker: Maker = field(default_factory=MP24DoubleRelaxMaker) + static_maker: Maker = field( + default_factory=lambda: MP24StaticMaker( + copy_vasp_kwargs={"additional_vasp_files": ("WAVECAR", "CHGCAR")} + ) + ) + clean_files: Sequence[str] | None = ("WAVECAR",) + + def make(self, structure: Structure, prev_dir: str | Path | None = None) -> Flow: + """Relax a structure with r2SCAN. + + Parameters + ---------- + structure : .Structure + A pymatgen structure object. + prev_dir : str or Path or None + A previous VASP calculation directory to copy output files from. + + Returns + ------- + Flow + A flow containing the MP relaxation workflow. + """ + relax_flow = self.relax_maker.make(structure=structure, prev_dir=prev_dir) + + static_job = self.static_maker.make( + structure=relax_flow.output.structure, prev_dir=relax_flow.output.dir_name + ) + + jobs = [relax_flow, static_job] + + self.clean_files = self.clean_files or [] + if len(self.clean_files) > 0: + directories: list[str] = [] + _recursive_get_dir_names(jobs, directories) + cleanup = remove_workflow_files( + directories=directories, + file_names=self.clean_files, + allow_zpath=True, + ) + jobs += [cleanup] + + return Flow(jobs=jobs, output=static_job.output, name=self.name) + + # update potcars to 54, use correct W potcar # use staticmaker for compatibility @dataclass diff --git a/src/atomate2/vasp/jobs/mp.py b/src/atomate2/vasp/jobs/mp.py index 3a1cdbcee6..617c0c1363 100644 --- a/src/atomate2/vasp/jobs/mp.py +++ b/src/atomate2/vasp/jobs/mp.py @@ -12,6 +12,8 @@ from typing import TYPE_CHECKING from pymatgen.io.vasp.sets import ( + MP24RelaxSet, + MP24StaticSet, MPRelaxSet, MPScanRelaxSet, MPScanStaticSet, @@ -232,3 +234,118 @@ class MPMetaGGAStaticMaker(BaseVaspMaker): }, ) ) + + +@dataclass +class MP24PreRelaxMaker(BaseVaspMaker): + """ + Maker to create MP2024 pre-relaxation jobs with PBEsol. + + Parameters + ---------- + name : str + The job name. + input_set_generator : .VaspInputGenerator + A generator used to make the input set. + write_input_set_kwargs : dict + Keyword arguments that will get passed to :obj:`.write_vasp_input_set`. + copy_vasp_kwargs : dict + Keyword arguments that will get passed to :obj:`.copy_vasp_outputs`. + run_vasp_kwargs : dict + Keyword arguments that will get passed to :obj:`.run_vasp`. + task_document_kwargs : dict + Keyword arguments that will get passed to :obj:`.TaskDoc.from_directory`. + stop_children_kwargs : dict + Keyword arguments that will get passed to :obj:`.should_stop_children`. + write_additional_data : dict + Additional data to write to the current directory. Given as a dict of + {filename: data}. Note that if using FireWorks, dictionary keys cannot contain + the "." character which is typically used to denote file extensions. To avoid + this, use the ":" character, which will automatically be converted to ".". E.g. + ``{"my_file:txt": "contents of the file"}``. + """ + + name: str = "MP24 PBEsol pre-relaxation" + input_set_generator: VaspInputGenerator = field( + default_factory=lambda: MP24RelaxSet( + xc_functional="PBEsol", user_incar_settings={"LWAVE": True} + ) + ) + + +@dataclass +class MP24RelaxMaker(BaseVaspMaker): + """ + Maker to create MP2024 relaxation jobs with r2SCAN. + + Parameters + ---------- + name : str + The job name. + input_set_generator : .VaspInputGenerator + A generator used to make the input set. + write_input_set_kwargs : dict + Keyword arguments that will get passed to :obj:`.write_vasp_input_set`. + copy_vasp_kwargs : dict + Keyword arguments that will get passed to :obj:`.copy_vasp_outputs`. + run_vasp_kwargs : dict + Keyword arguments that will get passed to :obj:`.run_vasp`. + task_document_kwargs : dict + Keyword arguments that will get passed to :obj:`.TaskDoc.from_directory`. + stop_children_kwargs : dict + Keyword arguments that will get passed to :obj:`.should_stop_children`. + write_additional_data : dict + Additional data to write to the current directory. Given as a dict of + {filename: data}. Note that if using FireWorks, dictionary keys cannot contain + the "." character which is typically used to denote file extensions. To avoid + this, use the ":" character, which will automatically be converted to ".". E.g. + ``{"my_file:txt": "contents of the file"}``. + """ + + name: str = "MP24 r2SCAN relaxation" + input_set_generator: VaspInputGenerator = field( + default_factory=lambda: MP24RelaxSet( + xc_functional="r2SCAN", user_incar_settings={"LWAVE": True} + ) + ) + + +@dataclass +class MP24StaticMaker(BaseVaspMaker): + """ + Maker to create MP2024 static jobs with r2SCAN. + + Parameters + ---------- + name : str + The job name. + input_set_generator : .VaspInputGenerator + A generator used to make the input set. + write_input_set_kwargs : dict + Keyword arguments that will get passed to :obj:`.write_vasp_input_set`. + copy_vasp_kwargs : dict + Keyword arguments that will get passed to :obj:`.copy_vasp_outputs`. + run_vasp_kwargs : dict + Keyword arguments that will get passed to :obj:`.run_vasp`. + task_document_kwargs : dict + Keyword arguments that will get passed to :obj:`.TaskDoc.from_directory`. + stop_children_kwargs : dict + Keyword arguments that will get passed to :obj:`.should_stop_children`. + write_additional_data : dict + Additional data to write to the current directory. Given as a dict of + {filename: data}. Note that if using FireWorks, dictionary keys cannot contain + the "." character which is typically used to denote file extensions. To avoid + this, use the ":" character, which will automatically be converted to ".". E.g. + ``{"my_file:txt": "contents of the file"}``. + """ + + name: str = "MP24 r2SCAN static" + input_set_generator: VaspInputGenerator = field( + default_factory=lambda: MP24StaticSet( + xc_functional="r2SCAN", + user_incar_settings={ + "LELF": True, # want to save this data? + "KPAR": 1, # b/c LELF = True mandates KPAR = 1 + }, + ) + ) diff --git a/src/atomate2/vasp/sets/matpes.py b/src/atomate2/vasp/sets/matpes.py deleted file mode 100644 index 8886bfb479..0000000000 --- a/src/atomate2/vasp/sets/matpes.py +++ /dev/null @@ -1,65 +0,0 @@ -""" -Module defining MatPES input set generators. - -In case of questions, contact @janosh or @shyuep. -""" - -from __future__ import annotations - -from dataclasses import dataclass -from typing import TYPE_CHECKING - -from monty.dev import deprecated -from pymatgen.io.vasp.sets import MatPESStaticSet - -if TYPE_CHECKING: - from typing import Literal - - -@deprecated(replacement=MatPESStaticSet, deadline=(2025, 1, 1)) -@dataclass -class MatPesGGAStaticSetGenerator(MatPESStaticSet): - """Class to generate MP-compatible VASP GGA static input sets.""" - - xc_functional: Literal["R2SCAN", "PBE", "PBE+U"] = "PBE" - auto_ismear: bool = False - auto_kspacing: bool = False - symprec: float | None = None - - def __post_init__(self) -> None: - """Raise deprecation warning and validate.""" - if self.symprec is not None: - self.sym_prec = self.symprec - super().__post_init__() - - -@deprecated( - replacement=MatPESStaticSet, - deadline=(2025, 1, 1), - message="Be sure to use `xc_functional = 'R2SCAN'` when instantiating the class.", -) -@dataclass -class MatPesMetaGGAStaticSetGenerator(MatPESStaticSet): - """Class to generate MP-compatible VASP meta-GGA static input sets.""" - - xc_functional: Literal["R2SCAN", "PBE", "PBE+U"] = "R2SCAN" - auto_ismear: bool = False - auto_kspacing: bool = False - symprec: float | None = None - - def __post_init__(self) -> None: - """Raise deprecation warning and validate.""" - if self.symprec is not None: - self.sym_prec = self.symprec - super().__post_init__() - - @property - def incar_updates(self) -> dict: - """Get updates to the INCAR for this calculation type. - - Returns - ------- - dict - A dictionary of updates to apply. - """ - return {"GGA": None} # unset GGA diff --git a/src/atomate2/vasp/sets/mp.py b/src/atomate2/vasp/sets/mp.py deleted file mode 100644 index 6150916fc4..0000000000 --- a/src/atomate2/vasp/sets/mp.py +++ /dev/null @@ -1,144 +0,0 @@ -""" -Module defining Materials Project input set generators. - -Reference: https://doi.org/10.1103/PhysRevMaterials.6.013801 - -In case of questions, consult @Andrew-S-Rosen, @esoteric-ephemera or @janosh. -""" - -from __future__ import annotations - -from dataclasses import dataclass - -from monty.dev import deprecated -from pymatgen.io.vasp.sets import ( - MPRelaxSet, - MPScanRelaxSet, - MPScanStaticSet, - MPStaticSet, -) - - -@deprecated(replacement=MPRelaxSet, deadline=(2025, 1, 1)) -@dataclass -class MPGGARelaxSetGenerator(MPRelaxSet): - """Class to generate MP-compatible VASP GGA relaxation input sets. - - reciprocal_density (int): For static calculations, we usually set the - reciprocal density by volume. This is a convenience arg to change - that, rather than using user_kpoints_settings. Defaults to 100, - which is ~50% more than that of standard relaxation calculations. - small_gap_multiply ([float, float]): If the gap is less than - 1st index, multiply the default reciprocal_density by the 2nd - index. - **kwargs: kwargs supported by RelaxSetGenerator. - """ - - auto_ismear: bool = False - auto_kspacing: bool = False - inherit_incar: bool | None = False - bandgap_tol: float = None - force_gamma: bool = True - auto_metal_kpoints: bool = True - symprec: float | None = None - - def __post_init__(self) -> None: - """Raise deprecation warning and validate.""" - if self.symprec is not None: - self.sym_prec = self.symprec - super().__post_init__() - - -@deprecated(replacement=MPStaticSet, deadline=(2025, 1, 1)) -@dataclass -class MPGGAStaticSetGenerator(MPStaticSet): - """Class to generate MP-compatible VASP GGA static input sets.""" - - auto_ismear: bool = False - auto_kspacing: bool = False - bandgap_tol: float = None - inherit_incar: bool | None = False - force_gamma: bool = True - auto_metal_kpoints: bool = True - symprec: float | None = None - - def __post_init__(self) -> None: - """Raise deprecation warning and validate.""" - if self.symprec is not None: - self.sym_prec = self.symprec - super().__post_init__() - - -@deprecated(replacement=MPScanStaticSet, deadline=(2025, 1, 1)) -@dataclass -class MPMetaGGAStaticSetGenerator(MPScanStaticSet): - """Class to generate MP-compatible VASP GGA static input sets.""" - - auto_ismear: bool = False - auto_kspacing: bool = True - bandgap_tol: float = 1e-4 - inherit_incar: bool | None = False - symprec: float | None = None - - def __post_init__(self) -> None: - """Raise deprecation warning and validate.""" - if self.symprec is not None: - self.sym_prec = self.symprec - super().__post_init__() - - @property - def incar_updates(self) -> dict: - """Get updates to the INCAR for this calculation type. - - Returns - ------- - dict - A dictionary of updates to apply. - """ - return super().incar_updates | { - "ALGO": "FAST", - "GGA": None, # unset GGA, shouldn't be set anyway but best be sure - "LCHARG": True, - "LWAVE": False, - "LVHAR": False, # this is not needed - "LELF": False, # prevents KPAR > 1 - } - - -@deprecated(replacement=MPScanRelaxSet, deadline=(2025, 1, 1)) -@dataclass -class MPMetaGGARelaxSetGenerator(MPScanRelaxSet): - """Class to generate MP-compatible VASP metaGGA relaxation input sets. - - Parameters - ---------- - config_dict: dict - The config dict. - bandgap_tol: float - Tolerance for metallic bandgap. If bandgap < bandgap_tol, KSPACING will be 0.22, - otherwise it will increase with bandgap up to a max of 0.44. - """ - - bandgap_tol: float = 1e-4 - auto_ismear: bool = False - auto_kspacing: bool = True - inherit_incar: bool | None = False - symprec: float | None = None - - def __post_init__(self) -> None: - """Raise deprecation warning and validate.""" - if self.symprec is not None: - self.sym_prec = self.symprec - super().__post_init__() - - @property - def incar_updates(self) -> dict: - """Get updates to the INCAR for this calculation type. - - Returns - ------- - dict - A dictionary of updates to apply. - """ - # unset GGA, shouldn't be set anyway but doesn't hurt to be sure - return {"LCHARG": True, "LWAVE": True, "GGA": None, "LELF": False} diff --git a/tests/vasp/sets/test_matpes.py b/tests/vasp/sets/test_matpes.py deleted file mode 100644 index f29b31c870..0000000000 --- a/tests/vasp/sets/test_matpes.py +++ /dev/null @@ -1,53 +0,0 @@ -"""Confirm with @janosh before changing any of the expected values below.""" - -import pytest -from pymatgen.io.vasp.sets import MatPESStaticSet - -from atomate2.vasp.sets.base import VaspInputGenerator -from atomate2.vasp.sets.matpes import ( - MatPesGGAStaticSetGenerator, - MatPesMetaGGAStaticSetGenerator, -) - - -@pytest.mark.parametrize( - "set_generator", - [MatPesGGAStaticSetGenerator, MatPesMetaGGAStaticSetGenerator], -) -def test_matpes_sets(set_generator: VaspInputGenerator) -> None: - with pytest.warns(FutureWarning): - matpes_set: VaspInputGenerator = set_generator() - - assert {*matpes_set.as_dict()} >= { - "@class", - "@module", - "@version", - "auto_ismear", - "auto_ispin", - "auto_kspacing", - "auto_lreal", - "auto_metal_kpoints", - "config_dict", - "constrain_total_magmom", - "force_gamma", - "inherit_incar", - "sort_structure", - "sym_prec", - "use_structure_charge", - "user_incar_settings", - "user_kpoints_settings", - "user_potcar_functional", - "user_potcar_settings", - "validate_magmom", - "vdw", - } - assert matpes_set.potcar_functional == "PBE_64" - assert isinstance(matpes_set.inherit_incar, list | tuple) - assert set(matpes_set.inherit_incar) == set(MatPESStaticSet.inherit_incar) - assert matpes_set.auto_ismear is False - assert matpes_set.auto_kspacing is False - assert matpes_set.auto_lreal is False - assert matpes_set.sort_structure is True - assert matpes_set.sym_prec == 0.1 - assert matpes_set.use_structure_charge is False - assert matpes_set.vdw is None diff --git a/tests/vasp/sets/test_mp.py b/tests/vasp/sets/test_mp.py deleted file mode 100644 index de35f6f05c..0000000000 --- a/tests/vasp/sets/test_mp.py +++ /dev/null @@ -1,65 +0,0 @@ -"""Confirm with @janosh before changing any of the expected values below.""" - -import pytest - -from atomate2.vasp.sets.base import VaspInputGenerator -from atomate2.vasp.sets.mp import ( - MPGGARelaxSetGenerator, - MPGGAStaticSetGenerator, - MPMetaGGARelaxSetGenerator, - MPMetaGGAStaticSetGenerator, -) - - -@pytest.mark.parametrize( - "set_generator", - [ - MPGGAStaticSetGenerator, - MPMetaGGAStaticSetGenerator, - MPGGARelaxSetGenerator, - MPMetaGGARelaxSetGenerator, - ], -) -def test_mp_sets(set_generator: VaspInputGenerator) -> None: - with pytest.warns(FutureWarning): - mp_set: VaspInputGenerator = set_generator() - assert {*mp_set.as_dict()} >= { - "@class", - "@module", - "@version", - "auto_ismear", - "auto_ispin", - "auto_kspacing", - "auto_lreal", - "auto_metal_kpoints", - "config_dict", - "constrain_total_magmom", - "force_gamma", - "inherit_incar", - "sort_structure", - "sym_prec", - "use_structure_charge", - "user_incar_settings", - "user_kpoints_settings", - "user_potcar_functional", - "user_potcar_settings", - "validate_magmom", - "vdw", - } - assert ( - mp_set.potcar_functional == "PBE_54" - if "Meta" in set_generator.__name__ - else "PBE" - ) - assert mp_set.inherit_incar is False - assert mp_set.auto_ismear is False - assert mp_set.auto_kspacing is ("Meta" in set_generator.__name__) - assert mp_set.auto_lreal is False - assert mp_set.auto_metal_kpoints is ("Meta" not in set_generator.__name__) - assert mp_set.force_gamma is ("Meta" not in set_generator.__name__) - assert mp_set.sort_structure is True - assert mp_set.sym_prec == 0.1 - assert mp_set.use_structure_charge is False - assert mp_set.vdw is None - bandgap_tol = getattr(mp_set, "bandgap_tol", None) - assert bandgap_tol == (1e-4 if "Meta" in set_generator.__name__ else None)