Skip to content

Commit e873ac3

Browse files
move remaining VaspInputGenerator features to PMG
1 parent 590831f commit e873ac3

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

pymatgen/io/vasp/sets.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,54 @@ def next_g_size(cur_g_size):
11221122

11231123
return ng_vec, [ng_ * finer_g_scale for ng_ in ng_vec]
11241124

1125+
@staticmethod
1126+
def from_directory(directory: str | Path, optional_files: dict = None) -> VaspInput:
1127+
"""Load a set of VASP inputs from a directory.
1128+
1129+
Note that only the standard INCAR, POSCAR, POTCAR and KPOINTS files are read
1130+
unless optional_filenames is specified.
1131+
1132+
Parameters
1133+
----------
1134+
directory
1135+
Directory to read VASP inputs from.
1136+
optional_files
1137+
Optional files to read in as well as a dict of {filename: Object class}.
1138+
Object class must have a static/class method from_file.
1139+
"""
1140+
directory = Path(directory)
1141+
objs = {"INCAR": Incar, "KPOINTS": Kpoints, "POSCAR": Poscar, "POTCAR": Potcar}
1142+
1143+
inputs = {}
1144+
for name, obj in objs.items():
1145+
if (directory / name).exists():
1146+
inputs[name.upper()] = obj.from_file(directory / name)
1147+
else:
1148+
# handle the case where there is no KPOINTS file
1149+
inputs[name.upper()] = None
1150+
1151+
optional_inputs = {}
1152+
if optional_files is not None:
1153+
for name, obj in optional_files.items():
1154+
optional_inputs[name] = obj.from_file(directory / name)
1155+
1156+
return VaspInput(
1157+
incar=inputs["INCAR"],
1158+
kpoints=inputs["KPOINTS"],
1159+
poscar=inputs["POSCAR"],
1160+
potcar=inputs["POTCAR"],
1161+
optional_files=optional_inputs,
1162+
)
1163+
1164+
def _get_nedos(self, dedos: float) -> int:
1165+
"""Automatic setting of nedos using the energy range and the energy step."""
1166+
if self.prev_vasprun is None:
1167+
return 2000
1168+
1169+
emax = max(eigs.max() for eigs in self.prev_vasprun.eigenvalues.values())
1170+
emin = min(eigs.min() for eigs in self.prev_vasprun.eigenvalues.values())
1171+
return int((emax - emin) / dedos)
1172+
11251173

11261174
# create VaspInputGenerator alias to follow atomate2 terminology
11271175
VaspInputGenerator = VaspInputSet

tests/io/vasp/test_sets.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,32 @@ def test_valid_magmom_struct(self):
648648
)
649649
vis.incar.items()
650650

651+
def test_write_input_and_from_directory(self):
652+
structure = Structure.from_spacegroup("Fm-3m",Lattice.cubic(4.),["Fe"],[[0.,0.,0.]])
653+
654+
vis = self.set(structure=structure)
655+
input_set = vis.get_input_set()
656+
657+
vis.write_input(output_dir=".")
658+
assert all(
659+
os.path.isfile(file) for file in ("INCAR","KPOINTS","POSCAR","POTCAR")
660+
)
661+
input_set_from_dir = self.set().from_directory(".")
662+
663+
assert all(
664+
input_set_from_dir[k] == input_set[k] for k in ("INCAR","KPOINTS","POTCAR")
665+
)
666+
# for some reason the POSCARs are not identical, but their structures and as_dict()'s are
667+
assert input_set_from_dir["POSCAR"].structure == input_set["POSCAR"].structure
668+
assert input_set_from_dir["POSCAR"].as_dict() == input_set["POSCAR"].as_dict()
669+
670+
def test_get_nedos(self):
671+
vrun = Vasprun(f"{VASP_OUT_DIR}/vasprun.pbesol.xml.gz")
672+
vis = self.set(structure=vrun.structures[-1])
673+
# no `prev_vasprun` --> default value of NEDOS
674+
assert vis._get_nedos(0.1) == 2000
675+
vis.prev_vasprun = vrun
676+
assert vis._get_nedos(0.1) == pytest.approx(741,abs=1)
651677

652678
class TestMPStaticSet(PymatgenTest):
653679
def setUp(self):

0 commit comments

Comments
 (0)