diff --git a/pymatgen/io/aims/inputs.py b/pymatgen/io/aims/inputs.py index 209a3a7498a..e7057c09e55 100644 --- a/pymatgen/io/aims/inputs.py +++ b/pymatgen/io/aims/inputs.py @@ -6,6 +6,7 @@ from __future__ import annotations import gzip +import os import time from copy import deepcopy from dataclasses import dataclass, field @@ -20,6 +21,11 @@ if TYPE_CHECKING: from collections.abc import Sequence +__author__ = "Thomas A. R. Purcell" +__version__ = "1.0" +__email__ = "purcellt@arizona.edu" +__date__ = "November 2023" + @dataclass class AimsGeometryIn(MSONable): @@ -566,7 +572,8 @@ def write_file( fd.write(cube.control_block) fd.write(lim + "\n\n") - fd.write(self.get_species_block(structure, self._parameters["species_dir"])) + species_dir = self._parameters.get("species_dir", os.environ.get("AIMS_SPECIES_DIR")) + fd.write(self.get_species_block(structure, species_dir)) def get_species_block(self, structure: Structure | Molecule, species_dir: str | Path) -> str: """Get the basis set information for a structure @@ -592,7 +599,7 @@ def get_species_block(self, structure: Structure | Molecule, species_dir: str | with gzip.open(f"{filename}.gz", "rt") as sf: sb += "".join(sf.readlines()) else: - raise ValueError("Species file for {sp.symbol} not found.") + raise ValueError(f"Species file for {sp.symbol} not found.") return sb diff --git a/pymatgen/io/aims/outputs.py b/pymatgen/io/aims/outputs.py index b07cea8a33c..2861a83186c 100644 --- a/pymatgen/io/aims/outputs.py +++ b/pymatgen/io/aims/outputs.py @@ -21,6 +21,11 @@ from pymatgen.core import Molecule, Structure +__author__ = "Andrey Sobolev and Thomas A. R. Purcell" +__version__ = "1.0" +__email__ = "andrey.n.sobolev@gmail.com and purcellt@arizona.edu" +__date__ = "November 2023" + class AimsOutput(MSONable): """The main output file for FHI-aims.""" diff --git a/pymatgen/io/aims/parsers.py b/pymatgen/io/aims/parsers.py index c35d4874cba..7f577e0aa9b 100644 --- a/pymatgen/io/aims/parsers.py +++ b/pymatgen/io/aims/parsers.py @@ -16,6 +16,11 @@ from emmet.core.math import Matrix3D, Vector3D +__author__ = "Thomas A. R. Purcell and Andrey Sobolev" +__version__ = "1.0" +__email__ = "purcellt@arizona.edu and andrey.n.sobolev@gmail.com" +__date__ = "November 2023" + # TARP: Originally an object, but type hinting needs this to be an int LINE_NOT_FOUND = -1000 EV_PER_A3_TO_KBAR = 1.60217653e-19 * 1e22 @@ -997,7 +1002,7 @@ def get_aims_out_chunks(content: str | TextIOWrapper, header_chunk: AimsOutHeade Yields: The next AimsOutChunk """ - lines = list(filter(lambda x: x not in header_chunk.lines, get_lines(content))) + lines = get_lines(content)[len(header_chunk.lines) :] if len(lines) == 0: return @@ -1122,7 +1127,9 @@ def read_aims_output_from_content( check_convergence(chunks, non_convergence_ok) # Relaxations have an additional footer chunk due to how it is split images = ( - [chunk.structure for chunk in chunks[:-1]] if header_chunk.is_relaxation else [chunk.atoms for chunk in chunks] + [chunk.structure for chunk in chunks[:-1]] + if header_chunk.is_relaxation + else [chunk.structure for chunk in chunks] ) return images[index] diff --git a/tests/io/aims/input_files/control.in.si.gz b/tests/io/aims/input_files/control.in.si.gz index 828dc548be4..a7396a35bb1 100644 Binary files a/tests/io/aims/input_files/control.in.si.gz and b/tests/io/aims/input_files/control.in.si.gz differ diff --git a/tests/io/aims/input_files/control.in.si.no_sd.gz b/tests/io/aims/input_files/control.in.si.no_sd.gz new file mode 100644 index 00000000000..6a7a2052065 Binary files /dev/null and b/tests/io/aims/input_files/control.in.si.no_sd.gz differ diff --git a/tests/io/aims/output_files/si.out.gz b/tests/io/aims/output_files/si.out.gz index 20bfa80681b..dfcfb82deb7 100644 Binary files a/tests/io/aims/output_files/si.out.gz and b/tests/io/aims/output_files/si.out.gz differ diff --git a/tests/io/aims/output_files/si_ref.json.gz b/tests/io/aims/output_files/si_ref.json.gz index edc0f16180a..d7ef89f6c00 100644 Binary files a/tests/io/aims/output_files/si_ref.json.gz and b/tests/io/aims/output_files/si_ref.json.gz differ diff --git a/tests/io/aims/test_aims_inputs.py b/tests/io/aims/test_aims_inputs.py index 9725d870d37..fc0652b3bd2 100644 --- a/tests/io/aims/test_aims_inputs.py +++ b/tests/io/aims/test_aims_inputs.py @@ -2,6 +2,7 @@ import gzip import json +import os from pathlib import Path import numpy as np @@ -29,7 +30,6 @@ def compare_files(ref_file, test_file): for test_line, ref_line in zip(test_lines, ref_lines): if "species_dir" in ref_line: continue - assert test_line.strip() == ref_line.strip() @@ -228,3 +228,38 @@ def test_aims_control_in(tmp_path): aims_control_from_dict.write_file(si, directory=tmp_path, verbose_header=True, overwrite=True) compare_files(infile_dir / "control.in.si", f"{tmp_path}/control.in") + + +def test_aims_control_in_default_species_dir(tmp_path): + original_sd = os.environ.get("AIMS_SPECIES_DIR", None) + os.environ["AIMS_SPECIES_DIR"] = str(infile_dir.parent / "species_directory/light") + + parameters = { + "cubes": [ + AimsCube(type="eigenstate 1", points=[10, 10, 10]), + AimsCube(type="total_density", points=[10, 10, 10]), + ], + "xc": "LDA", + "smearing": ["fermi-dirac", 0.01], + "vdw_correction_hirshfeld": True, + "compute_forces": True, + "relax_geometry": ["trm", "1e-3"], + "batch_size_limit": 200, + "output": ["band 0 0 0 0.5 0 0.5 10 G X", "band 0 0 0 0.5 0.5 0.5 10 G L"], + "k_grid": [1, 1, 1], + } + + aims_control = AimsControlIn(parameters.copy()) + + for key, val in parameters.items(): + assert aims_control[key] == val + + si = AimsGeometryIn.from_file(infile_dir / "geometry.in.si.gz").structure + + aims_control.write_file(si, directory=tmp_path, verbose_header=True, overwrite=True) + compare_files(infile_dir / "control.in.si.no_sd", f"{tmp_path}/control.in") + + if original_sd is not None: + os.environ["AIMS_SPECIES_DIR"] = original_sd + else: + del os.environ["AIMS_SPECIES_DIR"]