I am testing an example of the 'cut' function in ASE cut. In this example, the surface Al(111) is created using vectors (1, -1, 0) and (0, 1, -1) included in the "cut" function. But I am not clear how to define those vectors (1, -1, 0) and (0, 1, -1). Can you help me to explain? If I have to create the surface Al(112), which vectors should I include in the 'cut' function?

import ase
from ase.spacegroup import crystal
a = 4.0
aluminium = crystal('Al', [(0,0,0)], spacegroup=225,cellpar=[a, a, a, 90, 90, 90])
al111 = cut(aluminium, (1,-1,0), (0,1,-1), nlayers=3) #vectors input here

1 Answer 1


As described in the documentation, the a, b, and c vectors passed into ase.build.cut define lines that make up your cell. To see that the vectors you passed in give a (111) surface, consider the third vector c, which when it is not explicitly passed in, is formed using $\vec{c}=\vec{a} \times \vec{b}$. $\vec{c}$ is then the normal vector to plane formed by $\vec{a}$ and $\vec{b}$, which is exactly the Miller index for the plane.

$$(1,-1,0)\times(0,1,-1)=(1,1,1)\to (111)$$ So we can see that this will give a (111) surface. But how would we select these vectors to begin with? We can use another way that Miller indices are defined in terms of intersections with lattice vectors. For example, a (111) surface should have its intercept one unit along each axis, i.e. at the points (1,0,0),(0,1,0), and (0,0,1). These 3 noncollinear points determine a plane, but we can also express this plane using two intersecting lines, which we can generate by forming vectors between pairs of these points. $$(1,0,0)-(0,1,0)=(1,-1,0)=\vec{a}\\ (0,1,0)-(0,0,1)=(0,1,-1)=\vec{b}$$ The particular choice of pairs is arbitrary and you could just as well have used e.g (1,0,-1) for $\vec{b}$ and still produced the same plane.

So how would you make a (112) surface? We want to change the surface normal to be (1,1,2), or equivalently to intersect with the first two lattice vectors as 1 and the third at 1/2. So we can substitute $\vec{b}=(0,1,-1/2)$, which will give a surface normal of $\vec{c}=(1/2,1/2,1)$, which after multiplying by the least common denominator we can see leads to a (112) surface.

When generating a surface of a single compound, any scaling factor applied to each vector is irrelevant, as it will still result in a surface from the same family. However, if you are considering multiple types of surfaces forming an interface or multiple layers, you will need to consider these factors, as these will affect the relative positioning of the surfaces. An example of this given in the documentation for ase.build.stack:

import ase
from ase.spacegroup import crystal

# Create an Ag(110)-Si(110) interface with three atomic layers
# on each side.
a_ag = 4.09
ag = crystal(['Ag'], basis=[(0,0,0)], spacegroup=225,
             cellpar=[a_ag, a_ag, a_ag, 90., 90., 90.])
ag110 = cut(ag, (0, 0, 3), (-1.5, 1.5, 0), nlayers=3)

a_si = 5.43
si = crystal(['Si'], basis=[(0,0,0)], spacegroup=227,
             cellpar=[a_si, a_si, a_si, 90., 90., 90.])
si110 = cut(si, (0, 0, 2), (-1, 1, 0), nlayers=3)

Here, you can work out that these should be (110) surface, but you can also see that the vectors passed for each are different to avoid placing them right on top of each other.

  • $\begingroup$ Hi, since there are many arbitrary vectors a×b combinations, how can we find vectors which give the smallest structures to save computational cost? $\endgroup$
    – Binh Thien
    Aug 4, 2021 at 3:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .