Skip to content

3.3 Crystals and Lattices

A crystal is an arrangement of atoms that repeats periodically in three dimensions. The repetition is what makes crystals tractable. A blob of \(10^{23}\) atoms is incomprehensible; the same \(10^{23}\) atoms organised into a regular pattern can be specified by giving the contents of a single small box and a rule for tiling space. This section sets up that machinery — lattices, unit cells, the 14 Bravais lattices, Miller indices, and common crystal structures — and shows how to build crystals in ASE.

The lattice

A lattice is an infinite set of points generated by translating a single point by all integer combinations of three linearly independent vectors \(\mathbf{a}_1, \mathbf{a}_2, \mathbf{a}_3\):

\[ \mathbf{R} = n_1 \mathbf{a}_1 + n_2 \mathbf{a}_2 + n_3 \mathbf{a}_3, \quad n_i \in \mathbb{Z}. \]

The \(\mathbf{a}_i\) are the lattice vectors; the points \(\mathbf{R}\) are the lattice points. The lattice itself is a mathematical abstraction — a set of points — distinct from any physical material. A crystal is built by associating an atomic basis (one or more atoms with positions relative to the lattice point) with every lattice point.

A unit cell is the parallelepiped spanned by \(\mathbf{a}_1, \mathbf{a}_2, \mathbf{a}_3\). By construction, copies of the unit cell tile space without gaps or overlaps. The unit cell completely specifies the crystal: knowing the cell vectors and the atomic basis, every atom in the infinite crystal is determined.

Primitive versus conventional cells

A primitive cell is the smallest unit cell that can generate the lattice — equivalently, the cell whose volume is \(1 / \rho\) where \(\rho\) is the lattice-point density. A primitive cell contains exactly one lattice point.

A conventional cell is a (possibly larger) unit cell chosen for convenience, typically to make the symmetry of the structure manifest. For face-centred cubic (FCC), the primitive cell is a rhombohedral box containing one atom; the conventional cell is the familiar cubic box containing four atoms. The conventional cell is what crystallographers draw; the primitive cell is what minimises computational cost in DFT.

A simulation usually starts from a conventional cell and is then converted to a primitive cell to reduce expense. ASE has utilities for this conversion.

The 14 Bravais lattices

In three dimensions, there are exactly fourteen distinct lattices, classified by Bravais. They are organised by crystal system (seven of them, distinguished by the symmetries of the cell) and centering (whether atoms occupy only corners, or also face centres or the body centre).

The seven crystal systems and their cell shapes:

System Cell shape Constraints
Cubic Cube \(a = b = c\), \(\alpha = \beta = \gamma = 90°\)
Tetragonal Square prism \(a = b \ne c\), \(\alpha = \beta = \gamma = 90°\)
Orthorhombic Rectangular prism \(a \ne b \ne c\), \(\alpha = \beta = \gamma = 90°\)
Hexagonal Hexagonal prism \(a = b \ne c\), \(\alpha = \beta = 90°\), \(\gamma = 120°\)
Rhombohedral (trigonal) Distorted cube \(a = b = c\), \(\alpha = \beta = \gamma \ne 90°\)
Monoclinic Tilted rectangular \(a \ne b \ne c\), \(\alpha = \gamma = 90°\), \(\beta \ne 90°\)
Triclinic General No constraints

The four centering options:

  • P (primitive) — atoms only at cell corners (1 lattice point per cell).
  • I (body-centred) — primitive corners plus one at the centre (2 per cell).
  • F (face-centred) — primitive corners plus one at each face centre (4 per cell).
  • C (base-centred) — primitive corners plus one on a single pair of opposite faces (2 per cell).

Not every combination of crystal system and centering gives a distinct lattice — some are equivalent to each other under a basis change. The fourteen genuinely distinct Bravais lattices are:

  • Cubic: P, I, F (3)
  • Tetragonal: P, I (2)
  • Orthorhombic: P, I, F, C (4)
  • Hexagonal: P (1)
  • Trigonal: R (1, rhombohedral primitive)
  • Monoclinic: P, C (2)
  • Triclinic: P (1)

Total: 14. Each is a distinct way of tiling 3D space with a translationally periodic pattern.

For materials simulation, the cubic and hexagonal systems together account for the great majority of binary and elemental compounds. Most of this book will live in those systems.

Space groups

Bravais lattices describe only the translational symmetry. The full symmetry of a crystal — including rotations, reflections, glides, and screws — is captured by its space group, of which there are 230 in three dimensions. The International Tables for Crystallography list them; tools like spglib (and pymatgen) determine space groups algorithmically. For most simulation purposes, the space group is informational; for some — generating \(\mathbf{k}\)-point paths, applying symmetry to forces — it matters operationally.

Miller indices

When we want to refer to a plane in a crystal — perhaps the (100) face of a cube, or the cleavage plane of silicon — we use Miller indices. The convention is as follows.

Given a plane that intersects the crystal axes at points \(a/h\), \(b/k\), \(c/\ell\) (where \(a, b, c\) are the conventional lattice parameters along each axis), the Miller indices are \((hk\ell)\) — the reciprocals of the intercepts, scaled by the lattice parameters and reduced to coprime integers. If a plane is parallel to an axis, its intercept is at infinity, and the corresponding Miller index is zero. Negative indices are written with a bar: \((\bar 1 0 0)\).

A few examples in a cubic crystal:

  • \((100)\) — a plane perpendicular to \(\mathbf{a}_1\), intersecting the \(a\) axis at \(x = 1\). The face of the cube.
  • \((110)\) — a plane intersecting both \(\mathbf{a}_1\) and \(\mathbf{a}_2\) but parallel to \(\mathbf{a}_3\). A diagonal plane in the cube.
  • \((111)\) — a plane intersecting all three axes at equal distances. The cleavage plane of diamond.

Miller indices for directions in the crystal use square brackets \([hk\ell]\) and refer to the vector \(h \mathbf{a}_1 + k \mathbf{a}_2 + \ell \mathbf{a}_3\). In a cubic crystal, \([100]\) is the direction along \(\mathbf{a}_1\), and \([111]\) is along the body diagonal.

Families of equivalent directions or planes are denoted with curly braces \(\{hk\ell\}\) for planes and angle brackets \(\langle hk\ell \rangle\) for directions. So \(\{100\}\) in a cubic crystal refers to all six cube faces, \(\langle 100 \rangle\) to the six cube-edge directions.

Why Miller indices matter

Almost any property that depends on direction — elastic moduli, surface energies, electronic-structure paths, growth rates — uses Miller-index notation. The Si(100) surface and the FCC (111) slip plane are sentences that anyone in the field is expected to parse without thought.

The convention extends naturally to non-cubic systems, with the appropriate metric. For hexagonal crystals there is an alternative four-index Miller–Bravais notation \((hki\ell)\) with \(h + k + i = 0\) that makes equivalences manifest; we will mention it only in passing.

Common crystal structures

A handful of crystal structures account for a large fraction of materials. We list six.

Face-centred cubic (FCC)

Bravais lattice: cubic F. Basis: one atom at \((0, 0, 0)\) in the conventional cell. Coordination number: 12. Examples: Cu, Ag, Au, Al, Ni, Pb, \(\gamma\)-Fe.

In the conventional cubic cell of edge \(a\), atoms sit at the eight corners (shared between eight cells, so \(8 \times 1/8 = 1\) atom contribution) plus the six face centres (shared between two cells, so \(6 \times 1/2 = 3\) atom contribution), giving four atoms per conventional cell. The primitive cell has one atom and a rhombohedral shape.

The nearest-neighbour distance is \(a / \sqrt{2}\). FCC is the densest possible packing of equal spheres (along with HCP, with which it shares this property).

Body-centred cubic (BCC)

Bravais lattice: cubic I. Basis: one atom at \((0, 0, 0)\). Coordination: 8 nearest, 6 next-nearest. Examples: \(\alpha\)-Fe, W, Mo, Cr, Na, K.

Atoms at the corners plus one at the body centre. Two atoms per conventional cell. Nearest-neighbour distance \(a \sqrt{3}/2\). BCC is less densely packed than FCC (packing fraction 0.68 vs 0.74).

Hexagonal close packed (HCP)

Bravais lattice: hexagonal P. Basis: two atoms at \((0, 0, 0)\) and \((1/3, 2/3, 1/2)\). Coordination: 12. Examples: Mg, Zn, Cd, Ti, Zr, \(\alpha\)-Co.

HCP is the other densest packing of spheres. It has the same coordination as FCC but a different stacking sequence: HCP is ABABAB along the close-packed direction, FCC is ABCABC. The ideal \(c/a\) ratio is \(\sqrt{8/3} \approx 1.633\); real materials deviate slightly from this.

Diamond

Bravais lattice: cubic F. Basis: two atoms per primitive cell, at \((0, 0, 0)\) and \((1/4, 1/4, 1/4)\). Coordination: 4 (tetrahedral). Examples: C (diamond), Si, Ge, \(\alpha\)-Sn.

The diamond structure is two interpenetrating FCC lattices offset by one-quarter of the body diagonal. Each atom has four tetrahedrally arranged neighbours — the canonical sp\(^3\) geometry. Conventional cell contains eight atoms (4 from each FCC sublattice).

The cohesive energy of diamond (\(\sim 7.4\) eV per atom) makes it the hardest naturally occurring substance. Silicon, with weaker bonds in the same structure, is softer but has the same coordination.

Rock salt (NaCl)

Bravais lattice: cubic F. Basis: Na at \((0, 0, 0)\), Cl at \((1/2, 0, 0)\). Coordination: 6:6. Examples: NaCl, KCl, MgO, FeO, NiO, PbS.

Two interpenetrating FCC lattices, one of cations and one of anions, displaced by half the cube edge. Each cation has six anion nearest neighbours in octahedral coordination and vice versa.

Perovskite (ABO\(_3\))

Bravais lattice: cubic P (ideal case). Basis: A at \((0, 0, 0)\), B at \((1/2, 1/2, 1/2)\), three O at \((1/2, 1/2, 0)\) and equivalents. Coordination: A has 12 oxygen nearest neighbours, B has 6. Examples: SrTiO\(_3\), BaTiO\(_3\), CaTiO\(_3\), the lead-halide perovskites for photovoltaics.

The perovskite structure has been called the most useful crystal structure ever known. Distortions from the ideal cubic structure give rise to ferroelectricity (BaTiO\(_3\)), superconductivity (cuprates, with modified perovskites), high oxygen-ion conductivity (used in solid oxide fuel cells), and a vast array of other functional properties. The flexibility of the structure — A and B can be many different cations, and the oxygen can be replaced by halides for hybrid perovskites — makes it one of the most-studied families in materials science.

Pause and recall

Before reading on, try to answer these from memory:

  1. What is the difference between a lattice, a basis, and a crystal, and why does a primitive cell contain exactly one lattice point?
  2. How are Miller indices \((hk\ell)\) constructed from a plane's axis intercepts, and what does a zero index signify?
  3. The diamond, FCC, and rock-salt structures all share the cubic-F Bravais lattice — what distinguishes them, and what is the coordination number of each?

If any of these is shaky, re-read the preceding section before continuing.

Building crystals in ASE

ASE provides convenient builders for common crystal structures. The single most useful function is ase.build.bulk, which returns an Atoms object representing a primitive (or optionally conventional) unit cell of a named element in a chosen structure.

from ase.build import bulk

si = bulk("Si")  # diamond structure, primitive cell
print("Cell vectors (Å):")
print(si.cell.array)
print(f"Volume: {si.get_volume():.3f} Å^3")
print(f"Atomic positions (Å):")
print(si.positions)
print(f"Chemical symbols: {si.get_chemical_symbols()}")

What bulk("Si") actually does:

  1. Looks up silicon's reference data. The default lattice parameter for silicon's diamond structure is \(a = 5.43\) Å, the experimental value. (You can override with bulk("Si", a=5.40).)
  2. Builds the primitive cell. For diamond structure, the primitive cell is rhombohedral with cell vectors \(\mathbf{a}_1 = (0, a/2, a/2)\), \(\mathbf{a}_2 = (a/2, 0, a/2)\), \(\mathbf{a}_3 = (a/2, a/2, 0)\). The primitive cell volume is \(a^3 / 4\), one quarter of the conventional cubic cell.
  3. Places two atoms in the basis: one at the origin, one at \((a/4, a/4, a/4)\), which in fractional coordinates of the primitive cell is \((1/4, 1/4, 1/4)\).

Running the snippet above prints something like:

Cell vectors (Å):
[[0.    2.715 2.715]
 [2.715 0.    2.715]
 [2.715 2.715 0.   ]]
Volume: 40.038 Å^3
Atomic positions (Å):
[[0.     0.     0.    ]
 [1.3575 1.3575 1.3575]]
Chemical symbols: ['Si', 'Si']

Two silicon atoms, in a primitive cell of volume \(40\) Å\(^3\). Compare to the conventional cubic cell, which has volume \(a^3 = 160\) Å\(^3\) and eight atoms.

To get the conventional cubic cell instead:

si_cubic = bulk("Si", cubic=True)
print(si_cubic.get_chemical_symbols())  # eight Si atoms
print(si_cubic.cell.array)              # cubic cell

You can verify the nearest-neighbour distance:

import numpy as np

distances = si.get_all_distances(mic=True)  # minimum image convention
print(f"Si–Si nearest distance: {distances[0, 1]:.3f} Å")
# expected: a * sqrt(3) / 4 = 5.43 * 1.732 / 4 ≈ 2.351 Å

The output should be 2.351 Å, the textbook Si–Si bond length.

Other structures via bulk

The same function builds other common structures by passing the crystalstructure argument:

from ase.build import bulk

cu = bulk("Cu", crystalstructure="fcc")          # 1 atom, primitive
cu_cubic = bulk("Cu", crystalstructure="fcc", cubic=True)  # 4 atoms, conventional
mg = bulk("Mg", crystalstructure="hcp")          # 2 atoms, hexagonal
w  = bulk("W", crystalstructure="bcc")           # 1 atom, primitive

print(cu.cell.lengths(), cu.cell.angles())
print(mg.cell.lengths(), mg.cell.angles())

For multi-element compounds, ASE has builders such as nacl (from ase.build import nacl) and bcc110/fcc111 for surface slabs, and pymatgen has more comprehensive options for arbitrary structures via the Structure class.

Inspecting the structure

A useful first step on any new structure is to inspect it:

from ase.build import bulk
from ase.io import write

si = bulk("Si", cubic=True)
write("si.cif", si)         # standard crystallographic file
write("si.xyz", si)         # extended XYZ for visualisation
write("si.png", si)         # rendered image
print(si.cell.array)
print(si.get_chemical_symbols())
print(si.get_scaled_positions())  # fractional coordinates

The CIF file is the universal exchange format and can be opened in VESTA. The PNG is a quick sanity check. The fractional coordinates should match the textbook ones; if they don't, something is wrong upstream.

Building a supercell

For larger simulations (defects, surfaces, thermal sampling, MD), you replicate the unit cell. ASE makes this trivial:

si = bulk("Si", cubic=True)
supercell = si.repeat((4, 4, 4))   # 4 x 4 x 4 conventional cells
print(len(supercell))               # 8 * 64 = 512 atoms
print(supercell.cell.array)         # 4 * 5.43 = 21.72 Å edges

A 512-atom silicon cell is large enough for many MD purposes and tractable for DFT on a modest cluster.

Symmetry and the space group

Up to now we have described crystals by listing atoms in a unit cell. The full symmetry of the crystal — the rotations, reflections, and translations that map it to itself — is encoded in its space group. For silicon, the space group is \(Fd\bar 3 m\) (no. 227), which expresses the FCC translational symmetry plus diamond's additional rotational and glide symmetries.

Knowing the space group lets simulation codes apply many practical economies: only the symmetry-irreducible part of the Brillouin zone needs sampling; forces on symmetry-equivalent atoms can be averaged; phonon eigenvectors can be classified by irreducible representations. The library spglib and the pymatgen SpacegroupAnalyzer are the standard tools. For an ASE Atoms object:

from ase.spacegroup import get_spacegroup

si = bulk("Si", cubic=True)
sg = get_spacegroup(si, symprec=1e-3)
print(sg.no, sg.symbol)   # 227 Fd-3m

For most of this book, we will not work with the full space-group machinery — we will trust the codes to do the right thing. But you should know it is there.

Defects and disorder

The discussion above assumed perfect periodicity. Real crystals contain defects — vacancies, interstitials, substitutional impurities, dislocations, grain boundaries — and many materials of interest (alloys, glasses, the high-entropy alloys recently in fashion) are not perfectly ordered to begin with.

Modelling defects in periodic codes requires building a supercell large enough that defects on opposite sides do not interact through the periodic image. Standard practice for a single vacancy in silicon is a \(3 \times 3 \times 3\) or \(4 \times 4 \times 4\) conventional supercell (216 or 512 atoms). For charged defects, additional corrections (Makov–Payne, Freysoldt) are needed because the charge interacts with its periodic images through the long-range Coulomb potential.

Disordered alloys are typically modelled by special quasi-random structures (SQS) — small supercells with atomic occupations chosen to mimic the radial-distribution function of a random alloy — or by cluster expansions in which the alloy energy is parameterised in atomic-arrangement variables. We will not pursue these here.

Computing neighbour distances

A useful exercise is to compute and verify neighbour distances for the canonical structures. For FCC with conventional lattice parameter \(a\):

Shell Distance Number of neighbours
1 \(a / \sqrt{2}\) 12
2 \(a\) 6
3 \(a \sqrt{3/2}\) 24
4 \(a \sqrt{2}\) 12
5 \(a \sqrt{5/2}\) 24

For BCC:

Shell Distance Number of neighbours
1 \(a \sqrt{3}/2\) 8
2 \(a\) 6
3 \(a \sqrt{2}\) 12

These can be computed in ASE via the NeighborList utility, but for small systems a direct distance matrix is enough:

import numpy as np
from ase.build import bulk

cu = bulk("Cu", cubic=True)
positions = cu.get_positions()
cell = cu.cell.array
a = cell[0, 0]

# distances within the cell ignoring periodic images
n = len(positions)
d = np.zeros((n, n))
for i in range(n):
    for j in range(n):
        d[i, j] = np.linalg.norm(positions[i] - positions[j])
print(f"Nearest-neighbour distance: {d[d > 0].min():.3f} Å")
print(f"Theoretical: a/sqrt(2) = {a/np.sqrt(2):.3f} Å")

The output should agree to a fraction of a percent.

Sanity checks

Whenever you build a new structure, three quick sanity checks save hours of grief: (1) check the lattice parameters and angles against a reference; (2) check the number of atoms in the cell; (3) check the nearest-neighbour distance. If any of these is wrong, stop and fix it before running any expensive calculation.

Where this leaves us

We can now describe any periodic crystal as a Bravais lattice plus an atomic basis, build it in ASE, and inspect its geometry. The next section, on reciprocal space, asks how to think about waves (electrons, phonons, light) in the periodic environment we have constructed. The reciprocal lattice is the natural language for that question, and it is where the next chapter of every electronic-structure textbook is written.