diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 8d71ece56a..04545793ac 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -43,6 +43,13 @@ jobs: cache-dependency-path: pyproject.toml - name: Install dependencies + # ERROR: Cannot install atomate2 and atomate2[strict,tests]==0.0.1 because these package versions have conflicting dependencies. + # The conflict is caused by: + # atomate2[strict,tests] 0.0.1 depends on pymatgen>=2023.10.4 + # atomate2[strict,tests] 0.0.1 depends on pymatgen==2023.10.4; extra == "strict" + # ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-with-dependency-conflicts + # chgnet 0.2.1 depends on pymatgen>=2023.5.31 + # emmet-core 0.70.0 depends on pymatgen>=2023.10.11 run: | python -m pip install --upgrade pip pip install .[strict,tests] diff --git a/ADMIN.md b/ADMIN.md index 11d8fb87b1..af6a8873ba 100644 --- a/ADMIN.md +++ b/ADMIN.md @@ -2,6 +2,7 @@ Version releases on Pypi and GitHub are handled automatically through GitHub actions. The steps to push a new release are: + 1. Update `CHANGELOG.md` with a new version and release notes. 2. Create a tagged Git commit with the above changes: `git tag v0.0.1` 3. Push the commit and tags to GitHub using: `git push origin --tags` diff --git a/pyproject.toml b/pyproject.toml index 4245b57d27..aebc736692 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ dependencies = [ "PyYAML", "click", "custodian>=2023.3.10", - "emmet-core>=0.70.0", + "emmet-core>=0.70.5", "jobflow>=0.1.11", "monty>=2023.9.25", "numpy", @@ -66,7 +66,7 @@ strict = [ "click==8.1.7", "custodian==2023.10.9", "dscribe==2.1.0", - "emmet-core==0.70.4", + "emmet-core==0.70.5", "jobflow==0.1.14", "lobsterpy==0.3.2", "matgl==0.8.3", diff --git a/src/atomate2/vasp/flows/matpes.py b/src/atomate2/vasp/flows/matpes.py new file mode 100644 index 0000000000..7ab25ca534 --- /dev/null +++ b/src/atomate2/vasp/flows/matpes.py @@ -0,0 +1,67 @@ +""" +Module defining MatPES flows. + +In case of questions, consult @janosh or @esoteric-ephemera. Makes PBE + r2SCAN +cheaper than running both separately. +""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import TYPE_CHECKING + +from jobflow import Flow, Maker + +from atomate2.vasp.jobs.matpes import MatPesGGAStaticMaker, MatPesMetaGGAStaticMaker + +if TYPE_CHECKING: + from pathlib import Path + + from pymatgen.core import Structure + + +@dataclass +class MatPesGGAPlusMetaGGAStaticMaker(Maker): + """MatPES flow doing a GGA static followed by meta-GGA static. + + Uses the GGA WAVECAR to speed up electronic convergence on the meta-GGA static. + + Parameters + ---------- + name : str + Name of the flows produced by this maker. + static1 : .BaseVaspMaker + Maker to generate the first VASP static. + static2 : .BaseVaspMaker + Maker to generate the second VASP static. + """ + + name: str = "MatPES GGA plus meta-GGA static" + static1: Maker | None = field(default_factory=MatPesGGAStaticMaker) + static2: Maker = field( + default_factory=lambda: MatPesMetaGGAStaticMaker( + # could copy CHGCAR from GGA to meta-GGA directory too but is redundant + # since VASP can reconstruct it from WAVECAR + copy_vasp_kwargs={"additional_vasp_files": ("WAVECAR",)} + ) + ) + + def make(self, structure: Structure, prev_vasp_dir: str | Path | None = None): + """ + Create a flow with two chained statics. + + Parameters + ---------- + structure : .Structure + A pymatgen structure object. + prev_vasp_dir : str or Path or None + A previous VASP calculation directory to copy output files from. + + Returns + ------- + Flow + A flow containing two statics. + """ + static1 = self.static1.make(structure, prev_vasp_dir=prev_vasp_dir) + static2 = self.static2.make(structure, prev_vasp_dir=static1.output.dir_name) + return Flow([static1, static2], output=static2.output, name=self.name) diff --git a/src/atomate2/vasp/flows/mp.py b/src/atomate2/vasp/flows/mp.py index 858d1551ad..2e9a43142a 100644 --- a/src/atomate2/vasp/flows/mp.py +++ b/src/atomate2/vasp/flows/mp.py @@ -1,5 +1,5 @@ """ -Module defining flows for Materials Project workflows. +Module defining Materials Project workflows. Reference: https://doi.org/10.1103/PhysRevMaterials.6.013801 diff --git a/src/atomate2/vasp/jobs/matpes.py b/src/atomate2/vasp/jobs/matpes.py new file mode 100644 index 0000000000..0031c675ac --- /dev/null +++ b/src/atomate2/vasp/jobs/matpes.py @@ -0,0 +1,91 @@ +""" +Module defining MatPES job makers. + +In case of questions, contact @janosh or @shyuep. +""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import TYPE_CHECKING + +from atomate2.vasp.jobs.base import BaseVaspMaker +from atomate2.vasp.sets.matpes import ( + MatPesGGAStaticSetGenerator, + MatPesMetaGGAStaticSetGenerator, +) + +if TYPE_CHECKING: + from atomate2.vasp.sets.base import VaspInputGenerator + + +@dataclass +class MatPesGGAStaticMaker(BaseVaspMaker): + """ + Maker to create VASP static job using r2SCAN by default. + + 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 = "MatPES GGA static" + input_set_generator: VaspInputGenerator = field( + default_factory=MatPesGGAStaticSetGenerator + ) + inherit_incar: bool = False + + +@dataclass +class MatPesMetaGGAStaticMaker(BaseVaspMaker): + """ + Maker to create VASP static job using r2SCAN by default. + + 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 = "MatPES meta-GGA static" + input_set_generator: VaspInputGenerator = field( + default_factory=MatPesMetaGGAStaticSetGenerator + ) + inherit_incar: bool = False diff --git a/src/atomate2/vasp/jobs/mp.py b/src/atomate2/vasp/jobs/mp.py index a6686ef0cb..44e73f1860 100644 --- a/src/atomate2/vasp/jobs/mp.py +++ b/src/atomate2/vasp/jobs/mp.py @@ -1,5 +1,5 @@ """ -Module defining jobs for Materials Project r2SCAN workflows. +Module defining Materials Project job makers. Reference: https://doi.org/10.1103/PhysRevMaterials.6.013801 @@ -22,14 +22,6 @@ if TYPE_CHECKING: from atomate2.vasp.sets.base import VaspInputGenerator -__all__ = [ - "MPGGARelaxMaker", - "MPGGAStaticMaker", - "MPPreRelaxMaker", - "MPMetaGGARelaxMaker", - "MPMetaGGAStaticMaker", -] - @dataclass class MPGGARelaxMaker(BaseVaspMaker): diff --git a/src/atomate2/vasp/sets/matpes.py b/src/atomate2/vasp/sets/matpes.py new file mode 100644 index 0000000000..3a0ff714ad --- /dev/null +++ b/src/atomate2/vasp/sets/matpes.py @@ -0,0 +1,87 @@ +""" +Module defining MatPES input set generators. + +In case of questions, contact @janosh or @shyuep. +""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import TYPE_CHECKING + +from monty.serialization import loadfn +from pkg_resources import resource_filename + +from atomate2.vasp.sets.core import StaticSetGenerator + +if TYPE_CHECKING: + from pymatgen.core import Structure + from pymatgen.io.vasp import Outcar, Vasprun + + +# POTCAR section comes from PARENT but atomate2 does not support inheritance yet +_BASE_MATPES_PBE_STATIC_SET_NO_POTCAR = loadfn( + resource_filename("pymatgen.io.vasp", "MatPESStaticSet.yaml") +) +_BASE_PBE54_SET = loadfn(resource_filename("pymatgen.io.vasp", "PBE54Base.yaml")) +_BASE_MATPES_PBE_STATIC_SET = { + **_BASE_PBE54_SET, + **_BASE_MATPES_PBE_STATIC_SET_NO_POTCAR, +} + + +@dataclass +class MatPesGGAStaticSetGenerator(StaticSetGenerator): + """Class to generate MP-compatible VASP GGA static input sets.""" + + config_dict: dict = field(default_factory=lambda: _BASE_MATPES_PBE_STATIC_SET) + auto_ismear: bool = False + auto_kspacing: bool = True + user_incar_settings: dict = field( + # ensure _set_kspacing doesn't override input set ISMEAR + default_factory=lambda: {"ISMEAR": 0, "SIGMA": 0.05} + ) + + +@dataclass +class MatPesMetaGGAStaticSetGenerator(StaticSetGenerator): + """Class to generate MP-compatible VASP GGA static input sets.""" + + config_dict: dict = field(default_factory=lambda: _BASE_MATPES_PBE_STATIC_SET) + auto_ismear: bool = False + auto_kspacing: bool = True + user_incar_settings: dict = field( + # ensure _set_kspacing doesn't override input set ISMEAR + default_factory=lambda: {"ISMEAR": 0, "SIGMA": 0.05} + ) + + def get_incar_updates( + self, + structure: Structure, + prev_incar: dict = None, + bandgap: float = None, + vasprun: Vasprun = None, + outcar: Outcar = None, + ) -> dict: + """ + Get updates to the INCAR for this calculation type. + + Parameters + ---------- + structure + A structure. + prev_incar + An incar from a previous calculation. + bandgap + The band gap. + vasprun + A vasprun from a previous calculation. + outcar + An outcar from a previous calculation. + + Returns + ------- + dict + A dictionary of updates to apply. + """ + return {"METAGGA": "R2SCAN", "ALGO": "ALL", "GGA": None} # unset GGA diff --git a/src/atomate2/vasp/sets/mp.py b/src/atomate2/vasp/sets/mp.py index 50181f3574..a493bbe5dc 100644 --- a/src/atomate2/vasp/sets/mp.py +++ b/src/atomate2/vasp/sets/mp.py @@ -1,5 +1,5 @@ """ -Module defining jobs for Materials Project r2SCAN workflows. +Module defining Materials Project input set generators. Reference: https://doi.org/10.1103/PhysRevMaterials.6.013801 diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/inputs/INCAR b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/inputs/INCAR new file mode 100644 index 0000000000..fc405a62d1 --- /dev/null +++ b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/inputs/INCAR @@ -0,0 +1,20 @@ +ALGO = Normal +EDIFF = 1e-05 +ENAUG = 1360 +ENCUT = 680 +GGA = Pe +ISMEAR = 0 +ISPIN = 2 +KSPACING = 0.22 +LAECHG = True +LASPH = True +LCHARG = True +LMAXMIX = 6 +LMIXTAU = True +LORBIT = 11 +LREAL = False +LWAVE = False +NELM = 200 +NSW = 0 +PREC = Accurate +SIGMA = 0.05 diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/inputs/POSCAR b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/inputs/POSCAR new file mode 100644 index 0000000000..41a38bcf0c --- /dev/null +++ b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/inputs/POSCAR @@ -0,0 +1,10 @@ +Si2 +1.0 + 3.3488982826904379 0.0000000000000000 1.9334873250000004 + 1.1162994275634794 3.1573715802591895 1.9334873250000004 + 0.0000000000000000 0.0000000000000000 3.8669746500000000 +Si +2 +direct + 0.2500000000000000 0.2500000000000000 0.2500000000000000 Si + 0.0000000000000000 0.0000000000000000 0.0000000000000000 Si diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/inputs/POTCAR.spec b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/inputs/POTCAR.spec new file mode 100644 index 0000000000..e267321d2c --- /dev/null +++ b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/inputs/POTCAR.spec @@ -0,0 +1 @@ +Si diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/CONTCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/CONTCAR.gz new file mode 100644 index 0000000000..a291cdaa45 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/CONTCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/DOSCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/DOSCAR.gz new file mode 100644 index 0000000000..1c8dbc6e84 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/DOSCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/EIGENVAL.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/EIGENVAL.gz new file mode 100644 index 0000000000..e8ba0e6c9a Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/EIGENVAL.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/IBZKPT.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/IBZKPT.gz new file mode 100644 index 0000000000..4a28403396 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/IBZKPT.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/INCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/INCAR.gz new file mode 100644 index 0000000000..e194a98027 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/INCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/INCAR.orig.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/INCAR.orig.gz new file mode 100644 index 0000000000..7231321d8a Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/INCAR.orig.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/OSZICAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/OSZICAR.gz new file mode 100644 index 0000000000..b56624fc70 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/OSZICAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/OUTCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/OUTCAR.gz new file mode 100644 index 0000000000..288d3c694e Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/OUTCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/PCDAT.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/PCDAT.gz new file mode 100644 index 0000000000..e37eb60809 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/PCDAT.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/POSCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/POSCAR.gz new file mode 100644 index 0000000000..be4cb34257 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/POSCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/POSCAR.orig.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/POSCAR.orig.gz new file mode 100644 index 0000000000..092a657813 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/POSCAR.orig.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/PROCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/PROCAR.gz new file mode 100644 index 0000000000..e09bd22996 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/PROCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/REPORT.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/REPORT.gz new file mode 100644 index 0000000000..7cffaa5a69 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/REPORT.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/WAVECAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/WAVECAR.gz new file mode 100644 index 0000000000..c9dd3a45eb Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/WAVECAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/XDATCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/XDATCAR.gz new file mode 100644 index 0000000000..ad61d95c91 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/XDATCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/custodian.json.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/custodian.json.gz new file mode 100644 index 0000000000..38f34ee5b5 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/custodian.json.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/std_err.txt b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/std_err.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/vasp.out.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/vasp.out.gz new file mode 100644 index 0000000000..ae1a9bb3ed Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/vasp.out.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/vasprun.xml.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/vasprun.xml.gz new file mode 100644 index 0000000000..35c9aafcf3 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/pbe_static/outputs/vasprun.xml.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/inputs/INCAR b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/inputs/INCAR new file mode 100644 index 0000000000..b8924be9ec --- /dev/null +++ b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/inputs/INCAR @@ -0,0 +1,20 @@ +ALGO = All +EDIFF = 1e-05 +ENAUG = 1360.0 +ENCUT = 680 +ISMEAR = 0 +ISPIN = 2 +KSPACING = 0.28754316109307704 +LAECHG = True +LASPH = True +LCHARG = True +LMAXMIX = 6 +LMIXTAU = True +LORBIT = 11 +LREAL = False +LWAVE = False +METAGGA = R2scan +NELM = 200 +NSW = 0 +PREC = Accurate +SIGMA = 0.05 diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/inputs/POSCAR b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/inputs/POSCAR new file mode 100644 index 0000000000..41a38bcf0c --- /dev/null +++ b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/inputs/POSCAR @@ -0,0 +1,10 @@ +Si2 +1.0 + 3.3488982826904379 0.0000000000000000 1.9334873250000004 + 1.1162994275634794 3.1573715802591895 1.9334873250000004 + 0.0000000000000000 0.0000000000000000 3.8669746500000000 +Si +2 +direct + 0.2500000000000000 0.2500000000000000 0.2500000000000000 Si + 0.0000000000000000 0.0000000000000000 0.0000000000000000 Si diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/inputs/POTCAR.spec b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/inputs/POTCAR.spec new file mode 100644 index 0000000000..e267321d2c --- /dev/null +++ b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/inputs/POTCAR.spec @@ -0,0 +1 @@ +Si diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/CONTCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/CONTCAR.gz new file mode 100644 index 0000000000..0d7d802fbf Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/CONTCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/DOSCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/DOSCAR.gz new file mode 100644 index 0000000000..ae48ca14ce Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/DOSCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/EIGENVAL.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/EIGENVAL.gz new file mode 100644 index 0000000000..28c6a9450c Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/EIGENVAL.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/IBZKPT.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/IBZKPT.gz new file mode 100644 index 0000000000..d7f4651770 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/IBZKPT.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/INCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/INCAR.gz new file mode 100644 index 0000000000..cafcc38eee Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/INCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/INCAR.orig.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/INCAR.orig.gz new file mode 100644 index 0000000000..eda590b230 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/INCAR.orig.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/OSZICAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/OSZICAR.gz new file mode 100644 index 0000000000..1ec4bc20ac Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/OSZICAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/OUTCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/OUTCAR.gz new file mode 100644 index 0000000000..e0ed6f8386 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/OUTCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/PCDAT.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/PCDAT.gz new file mode 100644 index 0000000000..a082493eeb Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/PCDAT.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/POSCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/POSCAR.gz new file mode 100644 index 0000000000..5190cb285d Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/POSCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/POSCAR.orig.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/POSCAR.orig.gz new file mode 100644 index 0000000000..208f991a5d Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/POSCAR.orig.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/PROCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/PROCAR.gz new file mode 100644 index 0000000000..2b2bcf3c16 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/PROCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/REPORT.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/REPORT.gz new file mode 100644 index 0000000000..20b5c3e295 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/REPORT.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/WAVECAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/WAVECAR.gz new file mode 100644 index 0000000000..dfab5905d6 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/WAVECAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/XDATCAR.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/XDATCAR.gz new file mode 100644 index 0000000000..63e83b71ca Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/XDATCAR.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/custodian.json.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/custodian.json.gz new file mode 100644 index 0000000000..efae41aa18 Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/custodian.json.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/std_err.txt b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/std_err.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/vasp.out.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/vasp.out.gz new file mode 100644 index 0000000000..43fe8a6a1b Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/vasp.out.gz differ diff --git a/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/vasprun.xml.gz b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/vasprun.xml.gz new file mode 100644 index 0000000000..ad63b118dd Binary files /dev/null and b/tests/test_data/vasp/matpes_pbe_r2scan_flow/r2scan_static/outputs/vasprun.xml.gz differ diff --git a/tests/vasp/flows/test_matpes.py b/tests/vasp/flows/test_matpes.py new file mode 100644 index 0000000000..bf47c74ed5 --- /dev/null +++ b/tests/vasp/flows/test_matpes.py @@ -0,0 +1,36 @@ +from __future__ import annotations + +import pytest +from emmet.core.tasks import TaskDoc +from jobflow import run_locally +from pymatgen.core import Structure + +from atomate2.vasp.flows.matpes import MatPesGGAPlusMetaGGAStaticMaker + + +def test_mp_meta_gga_double_relax_static(mock_vasp, clean_dir, vasp_test_dir): + # map from job name to directory containing reference output files + pre_relax_dir = "matpes_pbe_r2scan_flow/pbe_static" + ref_paths = { + "MatPES GGA static": pre_relax_dir, + "MatPES meta-GGA static": "matpes_pbe_r2scan_flow/r2scan_static", + } + si_struct = Structure.from_file(f"{vasp_test_dir}/{pre_relax_dir}/inputs/POSCAR") + + mock_vasp(ref_paths) + + # generate flow + flow = MatPesGGAPlusMetaGGAStaticMaker().make(si_struct) + + assert flow.name == "MatPES GGA plus meta-GGA static" + assert len(flow) == 2 + assert [job.name for job in flow] == list(ref_paths) + + # ensure flow runs successfully + responses = run_locally(flow, create_folders=True, ensure_success=True) + + # validate output + output = responses[flow.jobs[-1].uuid][1].output + assert isinstance(output, TaskDoc) + assert output.output.energy == pytest.approx(-17.53895666) + assert output.output.bandgap == pytest.approx(0.8087999) diff --git a/tests/vasp/jobs/test_matpes.py b/tests/vasp/jobs/test_matpes.py new file mode 100644 index 0000000000..f44011e51d --- /dev/null +++ b/tests/vasp/jobs/test_matpes.py @@ -0,0 +1,134 @@ +import pytest +from emmet.core.tasks import TaskDoc +from jobflow import run_locally +from pymatgen.core import Structure + +from atomate2.vasp.jobs.base import BaseVaspMaker +from atomate2.vasp.jobs.matpes import MatPesGGAStaticMaker, MatPesMetaGGAStaticMaker +from atomate2.vasp.sets.matpes import ( + MatPesGGAStaticSetGenerator, + MatPesMetaGGAStaticSetGenerator, +) + +expected_incar = { + "ALGO": "Normal", + "EDIFF": 1e-05, + "ENAUG": 1360, + "ENCUT": 680, + "GGA": "PE", + "ISMEAR": 0, + "ISPIN": 2, + "KSPACING": 0.22, + "LAECHG": True, + "LASPH": True, + "LCHARG": True, + "LMIXTAU": True, + "LORBIT": 11, + "LREAL": False, + "LWAVE": False, + "NELM": 200, + "NSW": 0, + "PREC": "Accurate", + "SIGMA": 0.05, + "LMAXMIX": 6, + "LDAU": False, + "LDAUJ": { + "F": {"Co": 0, "Cr": 0, "Fe": 0, "Mn": 0, "Mo": 0, "Ni": 0, "V": 0, "W": 0}, + "O": {"Co": 0, "Cr": 0, "Fe": 0, "Mn": 0, "Mo": 0, "Ni": 0, "V": 0, "W": 0}, + }, + "LDAUL": { + "F": {"Co": 2, "Cr": 2, "Fe": 2, "Mn": 2, "Mo": 2, "Ni": 2, "V": 2, "W": 2}, + "O": {"Co": 2, "Cr": 2, "Fe": 2, "Mn": 2, "Mo": 2, "Ni": 2, "V": 2, "W": 2}, + }, + "LDAUTYPE": 2, + "LDAUU": { + "F": { + "Co": 3.32, + "Cr": 3.7, + "Fe": 5.3, + "Mn": 3.9, + "Mo": 4.38, + "Ni": 6.2, + "V": 3.25, + "W": 6.2, + }, + "O": { + "Co": 3.32, + "Cr": 3.7, + "Fe": 5.3, + "Mn": 3.9, + "Mo": 4.38, + "Ni": 6.2, + "V": 3.25, + "W": 6.2, + }, + }, +} + + +@pytest.mark.parametrize("maker_cls", [MatPesGGAStaticMaker, MatPesMetaGGAStaticMaker]) +def test_matpes_static_maker_default_values(maker_cls: BaseVaspMaker): + maker = maker_cls() + is_meta = "Meta" in maker_cls.__name__ + assert maker.name == f"MatPES {'meta-' if is_meta else ''}GGA static" + assert isinstance( + maker.input_set_generator, + MatPesMetaGGAStaticSetGenerator if is_meta else MatPesGGAStaticSetGenerator, + ) + config = maker.input_set_generator.config_dict + assert {*config} == {"INCAR", "POTCAR", "PARENT", "POTCAR_FUNCTIONAL"} + assert config["INCAR"] == expected_incar + + +def test_matpes_gga_static_maker(mock_vasp, clean_dir, vasp_test_dir): + # map from job name to directory containing reference input/output files + ref_paths = {"MatPES GGA static": "matpes_pbe_r2scan_flow/pbe_static"} + si_struct = Structure.from_file( + f"{vasp_test_dir}/matpes_pbe_r2scan_flow/pbe_static/inputs/POSCAR" + ) + + # settings passed to fake_run_vasp; adjust these to check for certain INCAR settings + fake_run_vasp_kwargs = {key: {"incar_settings": []} for key in ref_paths} + + mock_vasp(ref_paths, fake_run_vasp_kwargs) + + # generate flow + job = MatPesGGAStaticMaker().make(si_struct) + + # ensure flow runs successfully + responses = run_locally(job, create_folders=True, ensure_success=True) + + # validate output + output = responses[job.uuid][1].output + assert isinstance(output, TaskDoc) + assert output.output.energy == pytest.approx(-10.84940729) + + +def test_matpes_meta_gga_static_maker(mock_vasp, clean_dir, vasp_test_dir): + # map from job name to directory containing reference input/output files + ref_paths = {"MatPES meta-GGA static": "matpes_pbe_r2scan_flow/r2scan_static"} + si_struct = Structure.from_file( + f"{vasp_test_dir}/matpes_pbe_r2scan_flow/r2scan_static/inputs/POSCAR" + ) + + # settings passed to fake_run_vasp; adjust these to check for certain INCAR settings + fake_run_vasp_kwargs = { + key: {"incar_settings": ["GGA", "METAGGA", "ALGO"]} for key in ref_paths + } + + mock_vasp(ref_paths, fake_run_vasp_kwargs) + + # generate flow + job = MatPesMetaGGAStaticMaker( + input_set_generator=MatPesMetaGGAStaticSetGenerator( + auto_kspacing=0.6172000000000004 + ) + ).make(si_struct) + + # ensure flow runs successfully + responses = run_locally(job, create_folders=True, ensure_success=True) + + # validate output + output = responses[job.uuid][1].output + assert isinstance(output, TaskDoc) + assert output.output.energy == pytest.approx(-17.53895667)