Skip to content

Commit 2616f34

Browse files
committed
fix: select SIESTA pseudopotentials per task
Coding-Agent: Codex Codex-Version: codex-cli 0.149.0 Model: gpt-5.6-sol Reasoning-Effort: xhigh
1 parent d5ce577 commit 2616f34

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

dpgen/generator/run.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3710,6 +3710,10 @@ def make_fp_siesta(iter_index, jdata):
37103710
iter_name = make_iter_name(iter_index)
37113711
work_path = os.path.join(iter_name, fp_name)
37123712
fp_pp_files = jdata["fp_pp_files"]
3713+
type_map = jdata["type_map"]
3714+
if len(type_map) != len(fp_pp_files):
3715+
raise RuntimeError("fp_pp_files must correspond one-to-one with type_map")
3716+
pp_by_element = dict(zip(type_map, fp_pp_files))
37133717
if "user_fp_params" in jdata.keys():
37143718
fp_params = jdata["user_fp_params"]
37153719
user_input = True
@@ -3720,7 +3724,10 @@ def make_fp_siesta(iter_index, jdata):
37203724
for ii in fp_tasks:
37213725
os.chdir(ii)
37223726
sys_data = dpdata.System("POSCAR").data
3723-
ret = make_siesta_input(sys_data, fp_pp_files, fp_params)
3727+
# A workflow may share a global type map while an individual system
3728+
# contains only a subset of those elements.
3729+
task_pp_files = [pp_by_element[name] for name in sys_data["atom_names"]]
3730+
ret = make_siesta_input(sys_data, task_pp_files, fp_params)
37243731
with open("input", "w") as fp:
37253732
fp.write(ret)
37263733
os.chdir(cwd)

tests/generator/test_make_fp.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,42 @@ def test_make_fp_siesta(self):
991991
_check_potcar(self, 0, jdata["fp_pp_path"], jdata["fp_pp_files"])
992992
shutil.rmtree("iter.000000")
993993

994+
def test_make_fp_siesta_with_element_subset(self):
995+
"""Each SIESTA input should select PPs for its present elements."""
996+
setUpModule()
997+
if os.path.isdir("iter.000000"):
998+
shutil.rmtree("iter.000000")
999+
with open(param_siesta_file) as fp:
1000+
jdata = json.load(fp)
1001+
md_descript = []
1002+
for _ in range(2):
1003+
system_deviations = []
1004+
for _ in range(3):
1005+
system_deviations.append(np.arange(0, 0.29, 0.29 / 10))
1006+
md_descript.append(system_deviations)
1007+
1008+
try:
1009+
_make_fake_md(0, md_descript, [0] * 6, jdata["type_map"])
1010+
make_fp(0, jdata, {})
1011+
1012+
tasks = glob.glob(os.path.join("iter.000000", "02.fp", "task.*"))
1013+
self.assertGreater(len(tasks), 0)
1014+
for task in tasks:
1015+
with open(os.path.join(task, "input")) as fp:
1016+
input_text = fp.read()
1017+
self.assertIn("NumberOfSpecies 1", input_text)
1018+
species_block = input_text.split(
1019+
"%block Chemical_Species_label\n", maxsplit=1
1020+
)[1].split("%endblock Chemical_Species_label", maxsplit=1)[0]
1021+
species_lines = [
1022+
line for line in species_block.splitlines() if line.strip()
1023+
]
1024+
self.assertEqual(1, len(species_lines))
1025+
self.assertEqual("C", species_lines[0].split()[-1])
1026+
finally:
1027+
if os.path.isdir("iter.000000"):
1028+
shutil.rmtree("iter.000000")
1029+
9941030

9951031
class TestMakeFPVasp(unittest.TestCase):
9961032
def test_make_fp_vasp(self):

0 commit comments

Comments
 (0)