Skip to content

Commit

Permalink
Update VASP sets to transition atomate2 to use pymatgen input sets ex…
Browse files Browse the repository at this point in the history
…clusively (#3835)

* updates for consistency with atomate2 updates

* lint

* further patch for atomate2 support, make sure tests are respected or updated

* linting

* merge DictSet into VaspInputSet, deprecate DictSet as an alias of VaspInputSet to avoid breakage

* test_dict_set_alias subclass and deprecation message

* Change deprecation warning to be on init of DictSet

* remove deprecated decorator, only works for functions, error msg less clear when wrapped on init

* move remaining VaspInputGenerator features to PMG

* pre-commit auto-fixes

* added tests

* add incar, kpoints, poscar, potcar attr to io.vasp.inputs.VaspInput + tests

* linted

* Bump rexml from 3.2.5 to 3.2.8 in /docs (#3836)

Bumps [rexml](https://github.com/ruby/rexml) from 3.2.5 to 3.2.8.
- [Release notes](https://github.com/ruby/rexml/releases)
- [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md)
- [Commits](ruby/rexml@v3.2.5...v3.2.8)

---
updated-dependencies:
- dependency-name: rexml
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Shyue Ping Ong <shyuep@users.noreply.github.com>

* Bump nokogiri from 1.16.2 to 1.16.5 in /docs (#3828)

Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.16.2 to 1.16.5.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](sparklemotion/nokogiri@v1.16.2...v1.16.5)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Shyue Ping Ong <shyuep@users.noreply.github.com>

* shift features of VaspInputSet.write_input to VaspInput.write_input

* pre-commit /linting

* move file transfer from write_input method of VaspInputSet to VaspInput

* add missing `output_dir` kwarg to vaspinputset.write_input

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Janosh Riebesell <janosh.riebesell@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Shyue Ping Ong <shyuep@users.noreply.github.com>
  • Loading branch information
5 people authored May 23, 2024
1 parent 14b7357 commit 74e692b
Show file tree
Hide file tree
Showing 5 changed files with 443 additions and 336 deletions.
44 changes: 20 additions & 24 deletions docs/pymatgen.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

70 changes: 65 additions & 5 deletions pymatgen/io/vasp/inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
from enum import Enum, unique
from glob import glob
from hashlib import sha256
from pathlib import Path
from shutil import copyfileobj
from typing import TYPE_CHECKING, NamedTuple, cast
from zipfile import ZipFile

import numpy as np
import scipy.constants as const
Expand All @@ -38,7 +41,6 @@

if TYPE_CHECKING:
from collections.abc import Iterator
from pathlib import Path
from typing import Any, ClassVar, Literal

from numpy.typing import ArrayLike
Expand Down Expand Up @@ -2412,7 +2414,7 @@ def identify_potcar_hash_based(
potcar_functionals (list): List of potcar functionals associated with
the PotcarSingle
"""
# Dict to translate the sets in the .json file to the keys used in DictSet
# Dict to translate the sets in the .json file to the keys used in VaspInputSet
mapping_dict = {
"potUSPP_GGA": {
"pymatgen_key": "PW91_US",
Expand Down Expand Up @@ -2737,7 +2739,8 @@ def __init__(
incar: dict | Incar,
kpoints: Kpoints | None,
poscar: Poscar,
potcar: Potcar | None,
potcar: Potcar | str | None,
potcar_spec: bool = False,
optional_files: dict[PathLike, object] | None = None,
**kwargs,
) -> None:
Expand All @@ -2748,14 +2751,18 @@ def __init__(
incar (Incar): The Incar object.
kpoints (Kpoints): The Kpoints object.
poscar (Poscar): The Poscar object.
potcar (Potcar): The Potcar object.
potcar (Potcar or str): The Potcar object.
potcar_spec (bool = False) : used to share POTCAR info without license issues.
True --> POTCAR is a list of symbols, write POTCAR.spec
False --> POTCAR is a VASP POTCAR, write POTCAR
optional_files (dict): Other input files supplied as a dict of {filename: object}.
The object should follow standard pymatgen conventions in implementing a
as_dict() and from_dict method.
**kwargs: Additional keyword arguments to be stored in the VaspInput object.
"""
super().__init__(**kwargs)
self.update({"INCAR": incar, "KPOINTS": kpoints, "POSCAR": poscar, "POTCAR": potcar})
self._potcar_filename = "POTCAR" + (".spec" if potcar_spec else "")
self.update({"INCAR": incar, "KPOINTS": kpoints, "POSCAR": poscar, self._potcar_filename: potcar})
if optional_files is not None:
self.update(optional_files)

Expand Down Expand Up @@ -2793,6 +2800,9 @@ def write_input(
self,
output_dir: PathLike = ".",
make_dir_if_not_present: bool = True,
cif_name: str | None = None,
zip_name: str | None = None,
files_to_transfer: dict | None = None,
) -> None:
"""
Write VASP inputs to a directory.
Expand All @@ -2802,6 +2812,14 @@ def write_input(
Defaults to current directory (".").
make_dir_if_not_present (bool): Create the directory if not
present. Defaults to True.
cif_name (str or None): If a str, the name of the CIF file
to write the POSCAR to (the POSCAR will also be written).
zip_name (str or None): If a str, the name of the zip to
archive the VASP input set to.
files_to_transfer (dict) : A dictionary of
{ < input filename >: < output filepath >}.
This allows the transfer of < input filename > files from
a previous calculation to < output filepath >.
"""
if not os.path.isdir(output_dir) and make_dir_if_not_present:
os.makedirs(output_dir)
Expand All @@ -2811,6 +2829,28 @@ def write_input(
with zopen(os.path.join(output_dir, key), mode="wt") as file:
file.write(str(value))

if cif_name:
self["POSCAR"].structure.to(filename=cif_name)

if zip_name:
files_to_zip = list(self) + ([cif_name] if cif_name else [])
with ZipFile(os.path.join(output_dir, zip_name), mode="w") as zip_file:
for file in files_to_zip:
try:
zip_file.write(os.path.join(output_dir, file), arcname=file)
except FileNotFoundError:
pass

try:
os.remove(os.path.join(output_dir, file))
except (FileNotFoundError, PermissionError, IsADirectoryError):
pass

files_to_transfer = files_to_transfer or {}
for key, val in files_to_transfer.items():
with zopen(val, "rb") as fin, zopen(str(Path(output_dir) / key), "wb") as fout:
copyfileobj(fin, fout)

@classmethod
def from_directory(
cls,
Expand Down Expand Up @@ -2884,3 +2924,23 @@ def run_vasp(
open(err_file, mode="w", encoding="utf-8", buffering=1) as stderr_file,
):
subprocess.check_call(vasp_cmd, stdout=stdout_file, stderr=stderr_file)

@property
def incar(self) -> Incar:
"""INCAR object."""
return Incar(self["INCAR"]) if isinstance(self["INCAR"], dict) else self["INCAR"]

@property
def kpoints(self) -> Kpoints | None:
"""KPOINTS object."""
return self["KPOINTS"]

@property
def poscar(self) -> Poscar:
"""POSCAR object."""
return self["POSCAR"]

@property
def potcar(self) -> Potcar | str | None:
"""POTCAR or POTCAR.spec object."""
return self[self._potcar_filename]
Loading

0 comments on commit 74e692b

Please sign in to comment.