Cluster vectors

Although the calculation of cluster vectors is usually handled internally in icet, it is sometimes advantageous to explicitly look at the cluster vector for structures of interest. This tutorial demonstrates how this can be carried out in practice.

Import modules

First, one needs to import the class ClusterSpace class, which is used to store information regarding a given cluster space. Additionally, the ASE function bulk() will be needed to generate the structures.

from ase.build import bulk
from icet import ClusterSpace

Generate prototype structure

The next step is to build a prototype structure, here a bulk silicon unit cell. It is furthermore decided that the cluster vectors will be created by populating the sites with either silicon or germanium. Also, the cutoffs for pairs, triplets and quadruplets are all set to 5 Å.

primitive_structure = bulk('Si')
cutoffs = [5.0, 5.0, 5.0]
subelements = ['Si', 'Ge']

Initialize cluster space

The cluster space is created by initiating a ClusterSpace object and providing the prototype structure, cutoffs and list elements defined previously as arguments. Next, we print all relevant information regarding the cluster space in tabular format.

cluster_space = ClusterSpace(primitive_structure, cutoffs, subelements)
print(cluster_space)

Specifically, the final call should produce the following (partial) output:

------------------------- Cluster Space -------------------------
subelements: Si Ge
cutoffs: 5.0 5.0 5.0
number of orbits: 22
-----------------------------------------------------------------
order |  radius  | multiplicity | index | orbit |    MC vector
-----------------------------------------------------------------
  0   |   0.0000 |        1     |    0  |   -1
  1   |   0.0000 |        2     |    1  |    0  |    [0]
  2   |   1.1756 |        4     |    2  |    1  |  [0, 0]
  2   |   1.9198 |       12     |    3  |    2  |  [0, 0]
...
  4   |   2.5525 |        8     |   21  |   20  | [0, 0, 0, 0]
-----------------------------------------------------------------

Cluster vector for monoelemental supercell

After building a new structure in the form of a \(2\times2\times2\) supercell, the cluster vectors are constructed using the get_cluster_vector() method for the instance of the ClusterSpace class that was initiated in the previous section. The cluster vectors are printed, as a sequence of tables, as follows:

structure_1 = bulk('Si').repeat(2)
cluster_vector_1 = cluster_space.get_cluster_vector(structure_1)
print(cluster_vector_1)

These lines ought to yield the following result:

[1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]

Cluster vector for alloy supercell

Finally, the steps described in the previous section are repeated after substituting one of the Si atoms in the supercell with Ge.

structure_2 = bulk('Si').repeat(2)
structure_2[0].symbol = 'Ge'
cluster_vector_2 = cluster_space.get_cluster_vector(structure_2)
print(cluster_vector_2)

In this case the output should be:

[1.0, -0.875, 0.75, 0.75, 0.75, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]

Notice that the first element is always 1.0. This is true for all cluster vectors constructed in icet. This orbit is called a zerolet and it is useful when fitting a cluster expansion among other things.

Source code

The complete source code is available in examples/get_cluster_vectors.py

"""
This example demonstrates how to construct cluster vectors.
"""

# Import modules
from ase.build import bulk
from icet import ClusterSpace

# Create a primitive structure, decide which additional elements to populate
# it with (Si, Ge) and set the cutoffs for pairs (5.0 Å), triplets (5.0 Å)
# and quadruplets (5.0 Å).
primitive_structure = bulk('Si')
cutoffs = [5.0, 5.0, 5.0]
subelements = ['Si', 'Ge']

# Initiate and print the cluster space.
cluster_space = ClusterSpace(primitive_structure, cutoffs, subelements)
print(cluster_space)

# Generate and print the cluster vector for a pure Si 2x2x2 supercell.
structure_1 = bulk('Si').repeat(2)
cluster_vector_1 = cluster_space.get_cluster_vector(structure_1)
print(cluster_vector_1)

# Generate and print the cluster vector for a mixed Si-Ge 2x2x2 supercell
structure_2 = bulk('Si').repeat(2)
structure_2[0].symbol = 'Ge'
cluster_vector_2 = cluster_space.get_cluster_vector(structure_2)
print(cluster_vector_2)