Skip to content

Expanding a selection

mdapy.neighbor.expand_selection grows a selection of atoms by their neighbors: the atoms within a cutoff of a selected atom, the nearest neighbors of each selected atom, or the atoms bonded to one, as many times as asked, as OVITO's expand selection modifier does.

import numpy as np
from mdapy.build import build_crystal
from mdapy.neighbor import expand_selection

crystal = build_crystal("fcc", 3.615, elements="Cu", repeat=(6, 6, 6))
center = [int(np.argmin(np.linalg.norm(crystal["positions"] - 10.8, axis=1)))]
first = expand_selection(crystal, center, cutoff=3.0)  # the atom and its 12 neighbors
second = expand_selection(crystal, center, cutoff=3.0, iterations=2)  # 55 atoms
nearest = expand_selection(crystal, center, num_neighbors=12)  # the same 13
upper = expand_selection(crystal, crystal["positions"][:, 2] > 15, cutoff=3.0)  # a mask

The two shells about an atom in the middle, cut open:

from mdapy.visualization import render

shell = np.zeros(len(crystal), dtype=np.int32)  # 0: the other atoms
shell[second] = 1
shell[first] = 2
shell[center] = 3
colors = np.array(
    [
        [0.86, 0.86, 0.86],  # others
        [0.55, 0.63, 0.80],  # second shell
        [0.40, 0.76, 0.65],  # first shell
        [0.84, 0.15, 0.16],  # the atom
    ]
)
lower = crystal["positions"][:, 2] < 10.9
render(
    crystal.filter(lower),
    "images/expand-selection.png",
    color=colors[shell[lower]],
    view="top",
    width=900,
    height=600,
    legend=dict(zip(["others", "second shell", "first shell", "the atom"], colors)),
)

Two shells about an atom

The lower half of the crystal seen from above, cut through the atom in the middle.

Parameters

expand_selection(system, atoms, *, cutoff=None, num_neighbors=None, bonds=False, iterations=1)

Name Type Default Unit Meaning
system System the atoms and the box
atoms (N,) bool or indices the atoms selected
cutoff float64 Å add the atoms closer than this to a selected atom
num_neighbors int32 add the num_neighbors nearest neighbors of each selected atom
bonds bool False add the atoms bonded to a selected atom, by the bonds of the topology
iterations int32 1 how many times the selection grows, each time by the neighbors of every atom selected so far; 0 leaves it as it is

Give exactly one of cutoff, num_neighbors and bonds. Neighbors are found through the periodic boundaries, with the neighbor lists of mdapy.

Results

A boolean mask of one value per atom: the atoms selected and those added. With num_neighbors, an atom joins when it is one of the nearest neighbors of a selected atom, not the other way around, as in OVITO. The selection stops growing early once a step adds nothing.

Errors

expand_selection raises InvalidParameter when not exactly one of cutoff, num_neighbors and bonds is given, when iterations is not an integer or is negative, when atoms is not a mask or indices of the system, and as NeighborList.build for the cutoff and the number of neighbors; MissingProperty with bonds when the system has no bonds.

See also