Coverage for ase / build / connected.py: 100.00%
45 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-30 08:22 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-30 08:22 +0000
1from ase.atoms import Atoms
2from ase.data import covalent_radii
3from ase.neighborlist import NeighborList
6def connected_atoms(atoms, index, dmax=None, scale=1.5):
7 """Find all atoms connected to atoms[index] and return them."""
8 return atoms[connected_indices(atoms, index, dmax, scale)]
11def connected_indices(atoms, index, dmax=None, scale=1.5):
12 """Find atoms connected to atoms[index] and return their indices.
14 If dmax is not None:
15 Atoms are defined to be connected if they are nearer than dmax
16 to each other.
18 If dmax is None:
19 Atoms are defined to be connected if they are nearer than the
20 sum of their covalent radii * scale to each other.
22 """
23 if index < 0:
24 index = len(atoms) + index
26 # set neighbor lists
27 if dmax is None:
28 # define neighbors according to covalent radii
29 radii = scale * covalent_radii[atoms.get_atomic_numbers()]
30 else:
31 # define neighbors according to distance
32 radii = [0.5 * dmax] * len(atoms)
33 nl = NeighborList(radii, skin=0, self_interaction=False, bothways=True)
34 nl.update(atoms)
36 connected = [index] + list(nl.get_neighbors(index)[0])
37 isolated = False
38 while not isolated:
39 isolated = True
40 for i in connected:
41 for j in nl.get_neighbors(i)[0]:
42 if j not in connected:
43 connected.append(j)
44 isolated = False
46 return connected
49def separate(atoms, **kwargs):
50 """Split atoms into separated entities
52 Returns
53 -------
54 List of Atoms object that connected_indices calls connected.
55 """
56 indices = list(range(len(atoms)))
58 separated = []
59 while indices:
60 my_indcs = connected_indices(atoms, indices[0], **kwargs)
61 separated.append(Atoms(cell=atoms.cell, pbc=atoms.pbc))
62 for i in my_indcs:
63 separated[-1].append(atoms[i])
64 del indices[indices.index(i)]
66 return separated
69def split_bond(atoms, index1, index2, **kwargs):
70 """Split atoms by a bond specified by indices
72 index1: index of first atom
73 index2: index of second atom
74 kwargs: kwargs transferred to connected_atoms
76 Returns two Atoms objects
77 """
78 assert index1 != index2
79 if index2 > index1:
80 shift = 0, 1
81 else:
82 shift = 1, 0
84 atoms_copy = atoms.copy()
85 del atoms_copy[index2]
86 atoms1 = connected_atoms(atoms_copy, index1 - shift[0], **kwargs)
88 atoms_copy = atoms.copy()
89 del atoms_copy[index1]
90 atoms2 = connected_atoms(atoms_copy, index2 - shift[1], **kwargs)
92 return atoms1, atoms2