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\).
import pyscal.core as pc import pyscal.crystal_structures as pcs import matplotlib.pyplot as plt import numpy as np
The crystal_structures module is used to create different perfect crystal structures. The created atoms and simulation box is then assigned to a pyscal.core.System object. For this example, fcc, bcc, hcp and diamond structures are created.
fcc_atoms, fcc_box = pcs.make_crystal('fcc', lattice_constant=4, repetitions=[4,4,4]) fcc = pc.System() fcc.atoms = fcc_atoms fcc.box = fcc_box
bcc_atoms, bcc_box = pcs.make_crystal('bcc', lattice_constant=4, repetitions=[4,4,4]) bcc = pc.System() bcc.atoms = bcc_atoms bcc.box = bcc_box
hcp_atoms, hcp_box = pcs.make_crystal('hcp', lattice_constant=4, repetitions=[4,4,4]) hcp = pc.System() hcp.atoms = hcp_atoms hcp.box = hcp_box
Before calculating the Voronoi polyhedron, the neighbors for each atom need to be found using Voronoi method.
fcc.find_neighbors(method='voronoi') bcc.find_neighbors(method='voronoi') hcp.find_neighbors(method='voronoi')
Now, Voronoi vector can be calculated
fcc.calculate_vorovector() bcc.calculate_vorovector() hcp.calculate_vorovector()
The calculated parameters for each atom can be accessed using the Atom.vorovector attribute.
fcc_atoms = fcc.atoms bcc_atoms = bcc.atoms hcp_atoms = hcp.atoms
[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.vorovector, width=0.2, label="fcc") ax.bar(np.array(range(4)), bcc_atoms.vorovector, width=0.2, label="bcc") ax.bar(np.array(range(4))+0.2, hcp_atoms.vorovector, 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 0x7f1dc90d52d0>
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.