From 1d2077665157e364739814c29e99ade3b2f6bfcc Mon Sep 17 00:00:00 2001 From: njzjz-bot Date: Mon, 24 Aug 2026 03:31:24 +0800 Subject: [PATCH 1/2] fix: select the minimum interstitial distance Fixes #1902 Coding-Agent: Codex Codex-Version: codex-cli 0.149.0 Model: gpt-5.6-sol Reasoning-Effort: xhigh --- dpgen/auto_test/Interstitial.py | 13 +++++++++++- tests/auto_test/test_interstitial_distance.py | 21 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/auto_test/test_interstitial_distance.py diff --git a/dpgen/auto_test/Interstitial.py b/dpgen/auto_test/Interstitial.py index a4b06ae1c..eef74166a 100644 --- a/dpgen/auto_test/Interstitial.py +++ b/dpgen/auto_test/Interstitial.py @@ -13,6 +13,15 @@ from dpgen.auto_test.reproduce import make_repro, post_repro +def _smallest_nonzero_distance(distance_matrix): + """Return the minimum positive distance from a structure distance matrix.""" + distances = np.asarray(distance_matrix) + positive_distances = distances[distances > 0] + if positive_distances.size == 0: + raise ValueError("distance matrix does not contain a positive distance") + return float(np.min(positive_distances)) + + class Interstitial(Property): def __init__(self, parameter, inter_param=None): parameter["reproduce"] = parameter.get("reproduce", False) @@ -191,7 +200,9 @@ def make_confs(self, path_to_work, path_to_equi, refine=False): temp = jj.get_supercell_structure( sc_mat=np.diag(self.supercell, k=0) ) - smallest_distance = list(set(temp.distance_matrix.ravel()))[1] + smallest_distance = _smallest_nonzero_distance( + temp.distance_matrix + ) if ( "conf_filters" in self.parameter and "min_dist" in self.parameter["conf_filters"] diff --git a/tests/auto_test/test_interstitial_distance.py b/tests/auto_test/test_interstitial_distance.py new file mode 100644 index 000000000..19c9def8f --- /dev/null +++ b/tests/auto_test/test_interstitial_distance.py @@ -0,0 +1,21 @@ +import unittest + +import numpy as np + +from dpgen.auto_test.Interstitial import _smallest_nonzero_distance + + +class TestInterstitialDistance(unittest.TestCase): + def test_smallest_nonzero_distance(self): + distance_matrix = np.array( + [ + [0.0, 2.5, 1.25], + [2.5, 0.0, 3.0], + [1.25, 3.0, 0.0], + ] + ) + self.assertEqual(_smallest_nonzero_distance(distance_matrix), 1.25) + + +if __name__ == "__main__": + unittest.main() From 3411c647d2a87d20accd42cabbbb51187da75f58 Mon Sep 17 00:00:00 2001 From: njzjz-bot Date: Sun, 30 Aug 2026 00:03:22 +0800 Subject: [PATCH 2/2] fix: detect exact interstitial overlaps Coding-Agent: Codex Codex-Version: codex-cli 0.151.0 Model: gpt-5.6-sol Reasoning-Effort: xhigh --- dpgen/auto_test/Interstitial.py | 15 ++++++++++----- tests/auto_test/test_interstitial_distance.py | 11 +++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/dpgen/auto_test/Interstitial.py b/dpgen/auto_test/Interstitial.py index eef74166a..b3b6db911 100644 --- a/dpgen/auto_test/Interstitial.py +++ b/dpgen/auto_test/Interstitial.py @@ -14,12 +14,17 @@ def _smallest_nonzero_distance(distance_matrix): - """Return the minimum positive distance from a structure distance matrix.""" + """Return the minimum distance between two distinct atoms. + + Selecting by matrix index, instead of by value, keeps a real zero distance + caused by coincident atoms while excluding the zero-valued diagonal. + """ distances = np.asarray(distance_matrix) - positive_distances = distances[distances > 0] - if positive_distances.size == 0: - raise ValueError("distance matrix does not contain a positive distance") - return float(np.min(positive_distances)) + atom_pairs = np.triu_indices_from(distances, k=1) + pair_distances = distances[atom_pairs] + if pair_distances.size == 0: + raise ValueError("distance matrix does not contain a pair of atoms") + return float(np.min(pair_distances)) class Interstitial(Property): diff --git a/tests/auto_test/test_interstitial_distance.py b/tests/auto_test/test_interstitial_distance.py index 19c9def8f..ef661c618 100644 --- a/tests/auto_test/test_interstitial_distance.py +++ b/tests/auto_test/test_interstitial_distance.py @@ -16,6 +16,17 @@ def test_smallest_nonzero_distance(self): ) self.assertEqual(_smallest_nonzero_distance(distance_matrix), 1.25) + def test_exact_overlap_is_retained(self): + """An off-diagonal zero represents an invalid atomic overlap.""" + distance_matrix = np.array( + [ + [0.0, 0.0, 1.25], + [0.0, 0.0, 2.5], + [1.25, 2.5, 0.0], + ] + ) + self.assertEqual(_smallest_nonzero_distance(distance_matrix), 0.0) + if __name__ == "__main__": unittest.main()