Overview

Each structural descriptors inherits from the base class StructuralDescriptor and is computed for a given Trajectory.

Most descriptors require information about the neighbors of each of the considered particles. Nearest neighbors, i.e. particles inside of the first coordination shell, are computed at the level of the trajectory itself or directly read from the input trajectory file. This information is then propagated to the descriptors that rely on it to perform the computations.

There are several method to identify the neighbors of the central particles, and there are different ways for this information to be processed by the descriptors.

Nearest neighbors

Trajectory instances have several attributes and methods to identify nearest neighbors and determine the cutoffs delimiting the first coordination shell.

Nearest neighbors can be computed using the following method:

Trajectory.compute_nearest_neighbors(method=None, cutoffs=None, dr=0.1)[source]

Compute the nearest neighbors for all the particles in the trajectory using the provided method. Neighbors are stored in the nearest_neighbors particle property. Available methods are:

  • 'auto' : read neighbors from the trajectory file, if explicitly requested with the additional_fields argument in the constructor.

  • 'fixed' : use fixed cutoffs for each pair of species in the trajectory.

  • 'sann' : solid-angle based nearest neighbor algorithm (see https://doi.org/10.1063/1.4729313).

  • 'voronoi' : radical Voronoi tessellation method (uses particles’ radii) (see https://doi.org/10.1016/0022-3093(82)90093-X)

Parameters
  • method (str, default: None) – Method to identify the nearest neighbors. Must be one of 'auto', 'fixed', 'sann', or 'voronoi'. None defaults to 'auto'. If method is 'auto', neighbors are read directly from the trajectory file, if specified with the additional_fields argument in the constructor. If no neighbors are found, falls back to method='fixed' instead.

  • cutoffs (list, default: None) – List containing the cutoffs distances for each pair of species in the trajectory (for method 'fixed' and 'sann'). If None, cutoffs will be computed automatically. For method 'sann', cutoffs are required as a first guess to identify the nearest neighbors.

  • dr (float, default: 0.1) – Radial grid spacing \(\Delta r\) for computing the cutoffs on the basis of the first minimum of each partial radial distribution function in the trajectory, if cutoffs are not provided.

Return type

None

Examples

>>> traj.compute_nearest_neighbors(method='fixed', cutoffs=[1.5, 1.4, 1.4, 1.3])
>>> traj.compute_nearest_neighbors(method='sann', cutoffs=[1.5, 1.4, 1.4, 1.3])
>>> traj.compute_nearest_neighbors(method='voronoi')

Nearest neighbors cutoffs can be automatically computed for each pair of species in the trajectory on the basis of the first minimum of the partial radial distribution functions \(g_{\alpha\beta}(r)\), where \(\alpha\) and \(\beta\) are species indices. This is done using the following method:

Trajectory.compute_nearest_neighbors_cutoffs(dr=0.1)[source]

Compute the nearest neighbors cutoffs on the basis of the first minimum of the partial radial distribution function \(g_{\alpha\beta}(r)\) between each pair of species \((\alpha,\beta)\) in the trajectory. Sets the nearest_neighbors_cutoffs list attribute.

Parameters

dr (float, default: 0.1) – Bin width \(\Delta r\) for the radial grid used to compute the partial radial distribution functions \(g_{\alpha\beta}(r)\).

Return type

None

Alternatively, both the nearest neighbors method and cutoffs can be set as instance attributes of Trajectory:

traj = Trajectory('trajectory.xyz')
traj.nearest_neighbors_method = 'fixed'
traj.nearest_neighbors_cutoffs = [1.5, 1.4, 1.4, 1.3]
traj.compute_nearest_neighbors()

Once computed, the lists of nearest neighbors are stored as Particle attributes. These can be accessed through the Trajectory.get_property() method, or by iterating over the particles:

neighbors = traj.get_property('neighbors')
print(neighbors)
for system in traj:
        for particle in system.particle:
                print(particle.nearest_neighbors)

We now present in more details the various available methods to identify the nearest neighbors.

1. From the trajectory

Nearest neighbors can be directly from the input trajectory file if it contains an additional column such as neighbors or nearest_neighbors. Below is an example of such a file in XYZ format:

100
columns:id,pos,neighbors cell:5.000,5.000,5.000
A -1.100 -2.166 -0.629 9,12,54,74
A -1.754  0.583  1.231 2,27,63
A -0.338  1.957 -1.365 4,45,56,78,81
B  1.030 -0.220 -1.256 14,31,35
B  1.322 -1.556  2.134 41,63,70,92
...

This, however, must be specified when reading the input file through the additional_fields parameter.

Warning

Currently, this only works for trajectory files in XYZ format and for a few formats supported by atooms.

Example:

traj = Trajectory('trajectory.xyz', additional_fields=['neighbors'])

2. Fixed-cutoffs

Set using one of:

  • Trajectory.nearest_neighbors_method = 'fixed'

  • Trajectory.compute_nearest_neighbors(method='fixed')

Nearest neighbors are defined on the basis of a fixed cutoff distance \(r_{\alpha\beta}^c\), where \(\alpha\) and \(\beta\) are species indices. The cutoff distance is equal to the first minimum of the corresponding partial radial distribution function, \(g_{\alpha\beta}(r)\).

Example:

traj = Trajectory('trajectory.xyz')
traj.compute_nearest_neighbors(method='fixed', cutoffs=[1.5, 1.4, 1.4, 1.3])

3. Solid-angle based nearest neighbors

Set using one of:

  • Trajectory.nearest_neighbors_method = 'sann'

  • Trajectory.compute_nearest_neighbors(method='sann')

The solid-angle based nearest neighbors algorithm (SANN) [1] is a parameter-free algorithm for the identification of nearest neighbors. It attributes to each possible neighbor of a particle a solid angle and determines the cutoff radius by the requirement that the sum of the solid angles is \(4 \pi\).

Important

This method requires cutoffs (or computes them automatically if not provided) to use as a first guess to identify the possible nearest neighbors. However, cutoffs do not play a role in the algorithm itself. A good choice for these cutoffs is the first minima of the partial radial distribution functions \(g_{\alpha\beta}(r)\).

Example:

traj = Trajectory('trajectory.xyz')
traj.compute_nearest_neighbors(method='sann', cutoffs=[1.5, 1.4, 1.4, 1.3])

4. Radical Voronoi neighbors

Set using one of:

  • Trajectory.nearest_neighbors_method = 'voronoi'

  • Trajectory.compute_nearest_neighbors(method='voronoi')

Voronoi tessellation can be used in molecular simulations to identify nearest neighbors by construction of Voronoi polyhedra [2], which consists in drawing orthogonal planes at the mid-points between the central particle and each of its neighbors (i.e. its Wigner-Seitz cell). In particular, the radical variant of Voronoi tessellation [3], which accounts for the relative sizes of the particles to determine of the positions of the intersecting planes, provides better results for multi-components systems.

Warning

This method uses the effective particles’ radii. This information must thus be provided either from an additional field in the input trajectory file, or directly at the level of the Trajectory instance using the Trajectory.set_property() method. Otherwise, default values will be used.

Examples:

  1. Particles’ radii are read from the input trajectory file:

traj = Trajectory('trajectory.xyz', additional_fields=['radius'])
traj.compute_nearest_neighbors(method='voronoi')
  1. Particles’ radii are set in the Trajectory:

traj = Trajectory('trajectory.xyz')
traj.set_property('radius', 0.5, subset="species == 'A'")
traj.set_property('radius', 0.4, subset="species == 'B'")
traj.compute_nearest_neighbors(method='voronoi')

Neighbors & structural descriptors

The table below shows the requirements of each structural descriptors in terms of neighbors and cutoffs. Note that these requirements are automatically satisfied when computing the descriptors if not explicitly set by the user.

Required types of neighbors & cutoffs

Nearest 1

Extended 2

Cutoffs 3

Radial descriptor

Tetrahedral descriptor

Bond-angle descriptor

Bond-orientational descriptor

Locally averaged bond-orientational descriptor

Compactness descriptor

Coordination descriptor

Radial bond-orientational descriptor

Smoothed bond-angle descriptor

Smoothed bond-orientational descriptor

1

Nearest neighbors, computed in the Trajectory on the basis of one the nearest neighbors methods presented above.

2

Extended neighbors at fixed distances, i.e. beyond the first coordination shell. These are computed directly in the descriptor.

3

Nearest neighbors cutoffs \(\{ r_{\alpha\beta}^c \}\) for normalization. These are computed automatically if not provided in the Trajectory.

References

1

Jacobus A. van Meel, Laura Filion, Chantal Valeriani, and Daan Frenkel. A parameter-free, solid-angle based, nearest-neighbor algorithm. J. Chem. Phys., 136(23):234107, 2012. arXiv:1202.5281, doi:10.1063/1.4729313.

2

J. D. Bernal. A geometrical approach to the structure of liquids. Nature, 183(4655):141–147, 1959. doi:10.1038/183141a0.

3

B. J. Gellatly and J. L. Finney. Characterisation of models of multicomponent amorphous metals: the radical alternative to the voronoi polyhedron. J. Non-Cryst. Solids, 50(3):313–329, 1982. doi:10.1016/0022-3093(82)90093-X.