From cdff944a858289ac133685a4c7502c938e0f75fa Mon Sep 17 00:00:00 2001 From: njzjz-bot Date: Mon, 24 Aug 2026 04:24:39 +0800 Subject: [PATCH] fix: handle filtered interstitial tasks Coding-Agent: Codex Codex-Version: codex-cli 0.149.0 Model: gpt-5.6-sol Reasoning-Effort: xhigh --- dpgen/auto_test/Interstitial.py | 12 +++++++++--- tests/auto_test/test_interstitial.py | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/dpgen/auto_test/Interstitial.py b/dpgen/auto_test/Interstitial.py index a4b06ae1c..14c4a8e2f 100644 --- a/dpgen/auto_test/Interstitial.py +++ b/dpgen/auto_test/Interstitial.py @@ -183,6 +183,10 @@ def make_confs(self, path_to_work, path_to_equi, refine=False): insert_element_task = os.path.join(path_to_work, "element.out") if os.path.isfile(insert_element_task): os.remove(insert_element_task) + # Keep the task metadata present even when every generated + # interstitial is rejected by a configuration filter. + with open(insert_element_task, "w"): + pass for ii in self.insert_ele: pre_vds = InterstitialGenerator() @@ -467,8 +471,11 @@ def make_confs(self, path_to_work, path_to_equi, refine=False): return task_list def post_process(self, task_list): - if True: - fin1 = open(os.path.join(task_list[0], "..", "element.out")) + """Adjust generated LAMMPS atom types for interstitial tasks.""" + if not task_list: + return + + with open(os.path.join(task_list[0], "..", "element.out")) as fin1: for ii in task_list: conf = os.path.join(ii, "conf.lmp") inter = os.path.join(ii, "inter.json") @@ -492,7 +499,6 @@ def post_process(self, task_list): with open(conf, "w+") as fout: for jj in conf_line: print(jj, file=fout) - fin1.close() def task_type(self): return self.parameter["type"] diff --git a/tests/auto_test/test_interstitial.py b/tests/auto_test/test_interstitial.py index 876502595..4bd48ce01 100644 --- a/tests/auto_test/test_interstitial.py +++ b/tests/auto_test/test_interstitial.py @@ -105,3 +105,25 @@ def test_make_confs_bcc(self): center = (inter_site1.coords + inter_site2.coords) / 2 self.assertTrue((center[0] - center[1]) < 1e-4) self.assertTrue((center[1] - center[2]) < 1e-4) + + def test_make_confs_when_all_interstitials_are_filtered(self): + """An empty filtered result should remain a valid property setup.""" + shutil.copy( + os.path.join(self.source_path, "CONTCAR_V_bcc"), + os.path.join(self.equi_path, "CONTCAR"), + ) + parameter = { + "type": "interstitial", + "supercell": [1, 1, 1], + "insert_ele": ["V"], + "conf_filters": {"min_dist": 100.0}, + } + interstitial = Interstitial(parameter) + + task_list = interstitial.make_confs(self.target_path, self.equi_path) + + self.assertEqual([], task_list) + element_out = os.path.join(self.target_path, "element.out") + self.assertTrue(os.path.isfile(element_out)) + self.assertEqual(0, os.path.getsize(element_out)) + interstitial.post_process(task_list)