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\).

[1]:
import pyscal as pc
import pyscal.crystal_structures as pcs
import matplotlib.pyplot as plt
import numpy as np

The :mod:~pyscal.crystal_structures module is used to create different perfect crystal structures. The created atoms and simulation box is then assigned to a :class:~pyscal.core.System object. For this example, fcc, bcc, hcp and diamond structures are created.

[2]:
fcc_atoms, fcc_box = pcs.make_crystal('fcc', lattice_constant=4, repetitions=[4,4,4])
fcc = pc.System()
fcc.box = fcc_box
fcc.atoms = fcc_atoms
[3]:
bcc_atoms, bcc_box = pcs.make_crystal('bcc', lattice_constant=4, repetitions=[4,4,4])
bcc = pc.System()
bcc.box = bcc_box
bcc.atoms = bcc_atoms
[4]:
hcp_atoms, hcp_box = pcs.make_crystal('hcp', lattice_constant=4, repetitions=[4,4,4])
hcp = pc.System()
hcp.box = hcp_box
hcp.atoms = hcp_atoms

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

[5]:
fcc.find_neighbors(method='voronoi')
bcc.find_neighbors(method='voronoi')
hcp.find_neighbors(method='voronoi')

Now, Voronoi vector can be calculated

[6]:
fcc.calculate_vorovector()
bcc.calculate_vorovector()
hcp.calculate_vorovector()

The calculated parameters for each atom can be accessed using the :attr:~pyscal.catom.Atom.vorovector attribute.

[7]:
fcc_atoms = fcc.atoms
bcc_atoms = bcc.atoms
hcp_atoms = hcp.atoms
[8]:
fcc_atoms[10].vorovector
[8]:
[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

[9]:
fig, ax = plt.subplots()
ax.bar(np.array(range(4))-0.2, fcc_atoms[10].vorovector, width=0.2, label="fcc")
ax.bar(np.array(range(4)), bcc_atoms[10].vorovector, width=0.2, label="bcc")
ax.bar(np.array(range(4))+0.2, hcp_atoms[10].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()
[9]:
<matplotlib.legend.Legend at 0x7f13d02b9760>
../_images/examples_06_voronoi_tessellation_14_1.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 be accessed using the :attr:~pyscal.catom.Atom.volume attribute.

[10]:
fcc_atoms = fcc.atoms
[11]:
fcc_vols = [atom.volume for atom in fcc_atoms]
[12]:
np.mean(fcc_vols)
[12]:
16.0