Voronoi parameters#

Voronoi tessellation can be used to identify local structure by counting the number of faces of the Voronoi polyhedra of an atom. For each atom a vector \(\langle n3~n4~n5~n6\) can be calculated where \(n_3\) is the number of Voronoi faces of the associated Voronoi polyhedron with three vertices, \(n_4\) is with four vertices and so on. Each perfect crystal structure such as a signature vector, for example, bcc can be identified by \(\langle 0~6~0~8 \rangle\) and fcc can be identified using \(\langle 0~12~0~0 \rangle\). It is also a useful tool for identifying icosahedral structure which has the fingerprint \(\langle 0~0~12~0 \rangle\).

from pyscal3 import System
import matplotlib.pyplot as plt
import numpy as np

For this example, fcc, bcc, hcp and diamond structures are created.

bcc = System.create.lattice.bcc(lattice_constant=4, repetitions=[4,4,4])
fcc = System.create.lattice.fcc(lattice_constant=4, repetitions=[4,4,4])
hcp = System.create.lattice.hcp(lattice_constant=4, repetitions=[4,4,4])

Before calculating the Voronoi polyhedron, the neighbors for each atom need to be found using Voronoi method.

bcc.find.neighbors(method='voronoi')
fcc.find.neighbors(method='voronoi')
hcp.find.neighbors(method='voronoi')

Now, Voronoi vector can be calculated

fcc.calculate.voronoi_vector()
bcc.calculate.voronoi_vector()
hcp.calculate.voronoi_vector()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[4], line 2
      1 fcc.calculate.voronoi_vector()
----> 2 bcc.calculate.voronoi_vector()
      3 hcp.calculate.voronoi_vector()

File ~/checkouts/readthedocs.org/user_builds/pyscal3/envs/latest/lib/python3.11/site-packages/pyscal3/operations/voronoi.py:93, in calculate_vorovector(system, edge_cutoff, area_cutoff, edge_length)
     90     complete_edge_lengths.append(edge_lengths)
     91     vorovectors.append(vorovector)
---> 93 system.atoms["edge_lengths"] = np.array(complete_edge_lengths)
     94 system.atoms["vorovector"] = np.array(vorovectors)
     96 mapdict = {}

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 2 dimensions. The detected shape was (1024, 14) + inhomogeneous part.

We can access the values

fcc.atoms.voronoi.vector
array([[ 0, 12,  0,  0],
       [ 0, 12,  0,  0],
       [ 0, 12,  0,  0],
       ...,
       [ 0, 12,  0,  0],
       [ 0, 12,  0,  0],
       [ 0, 12,  0,  0]])

As expected, fcc structure exhibits 12 faces with four vertices each. For a single atom, the difference in the Voronoi fingerprint is shown below

fig, ax = plt.subplots()
ax.bar(np.array(range(4))-0.2, fcc.atoms.voronoi.vector[10], width=0.2, label="fcc")
ax.bar(np.array(range(4)), bcc.atoms.voronoi.vector[10], width=0.2, label="bcc")
ax.bar(np.array(range(4))+0.2, hcp.atoms.voronoi.vector[10], width=0.2, label="hcp")
ax.set_xticks([1,2,3,4])
ax.set_xlim(0.5, 4.25)
ax.set_xticklabels(['$n_3$', '$n_4$', '$n_5$', '$n_6$'])
ax.set_ylabel("Number of faces")
ax.legend()
<matplotlib.legend.Legend at 0x7ff9a1816080>
../_images/1d9f820f590ea1af8f0e09f619fad84510fc51a895e91aacb97814436b45dcbd.png

The difference in Voronoi fingerprint for bcc and the closed packed structures is clearly visible. Voronoi tessellation, however, is incapable of distinction between fcc and hcp structures.

Voronoi volume#

Voronoi volume, which is the volume of the Voronoi polyhedron is calculated when the neighbors are found. The volume can also be accessed.

np.mean(fcc.atoms.voronoi.volume)
16.0