Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion dpgen/auto_test/Interstitial.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@
from dpgen.auto_test.reproduce import make_repro, post_repro


def _smallest_nonzero_distance(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)
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):
def __init__(self, parameter, inter_param=None):
parameter["reproduce"] = parameter.get("reproduce", False)
Expand Down Expand Up @@ -191,7 +205,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"]
Expand Down
32 changes: 32 additions & 0 deletions tests/auto_test/test_interstitial_distance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
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)

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()