Skip to content

Tutorial 4 · Crystals & Defects

What you'll learn: how to build bulk crystals with arbitrary structures and lattice constants, create supercells, and introduce point defects (vacancies, substitutions, interstitials).

Prerequisites: Tutorial 1. No extra dependencies.


Building a bulk crystal

examples/12_bulk_vacancy_md.toml
[run]
name = "bulk_vacancy_md"
seed = 7

[geometry.builder]
type             = "crystal"
name             = "Cu"            # (1)
crystalstructure = "fcc"           # (2)
a                = 3.61            # (3)
cubic            = true            # (4)
supercell        = [2, 2, 2]       # (5)

[[geometry.builder.defects]]       # (6)
kind  = "vacancy"
index = 0

[calculator]
type = "emt"

[sampling]
type        = "md"
temperature = 600.0
steps       = 200
interval    = 20

[selection]
steps  = ["physicality", "dedup", "diversity"]
budget = 8

[dataset]
path = "dataset"
pixi run example-12

Crystal builder parameters

  1. name — the element symbol (or compound formula for multi-element crystals, e.g. "NaCl", "GaAs", "TiO2").

  2. crystalstructure — the crystal structure type. Common values: fcc, bcc, hcp, diamond, rocksalt, wurtzite, zincblende. Leave null to let ASE infer it from the element.

  3. a — the primary lattice constant in Å. Leave null to use ASE's built-in experimental value.

  4. cubic — whether to use the cubic conventional cell (larger but orthogonal). Recommended for most MD runs.

  5. supercell — repeat the primitive/conventional cell before adding defects. [2,2,2] → 8× the unit cell.

  6. [[geometry.builder.defects]] — a list of point defects to introduce (see below).


Point defects

Vacancy

Remove one atom from the supercell:

[[geometry.builder.defects]]
kind  = "vacancy"
index = 0     # (1)
  1. index — the atom index in the pre-defect supercell (0-based). Index 0 is the first atom.

Substitution

Replace an atom with a different element:

[[geometry.builder.defects]]
kind    = "substitution"
index   = 0
element = "Ni"    # replace Cu with Ni

Interstitial

Insert an extra atom at a specific position:

[[geometry.builder.defects]]
kind       = "interstitial"
element    = "H"
position   = [0.5, 0.5, 0.5]    # (1)
cartesian  = false               # (2)
  1. position — where to insert the atom.

  2. cartesianfalse means the position is in fractional coordinates (relative to the supercell vectors). Set to true for Cartesian coordinates in Å.


Combining multiple defects

Defects are applied in a stable order: substitutions first, then vacancies, then interstitials. The index fields always refer to the supercell before any atoms are added or removed.

[geometry.builder]
type             = "crystal"
name             = "Cu"
crystalstructure = "fcc"
a                = 3.61
cubic            = true
supercell        = [3, 3, 3]

[[geometry.builder.defects]]
kind    = "substitution"
index   = 0
element = "Ni"          # swap atom 0 for Ni

[[geometry.builder.defects]]
kind  = "vacancy"
index = 1               # remove atom 1 from the original supercell

[[geometry.builder.defects]]
kind      = "interstitial"
element   = "H"
position  = [0.25, 0.25, 0.25]
cartesian = false

Common crystal systems

[geometry.builder]
type             = "crystal"
name             = "Au"
crystalstructure = "fcc"
a                = 4.07
cubic            = true
supercell        = [2, 2, 2]
[geometry.builder]
type             = "crystal"
name             = "W"
crystalstructure = "bcc"
a                = 3.16
cubic            = true
supercell        = [2, 2, 2]
[geometry.builder]
type             = "crystal"
name             = "Si"
crystalstructure = "diamond"
a                = 5.43
cubic            = true
supercell        = [2, 2, 2]
[geometry.builder]
type             = "crystal"
name             = "NaCl"
crystalstructure = "rocksalt"
a                = 5.64
cubic            = true
supercell        = [2, 2, 2]
[geometry.builder]
type             = "crystal"
name             = "Ti"
crystalstructure = "hcp"
a                = 2.95
c                = 4.68
supercell        = [3, 3, 2]

Inspecting defect provenance

Defect information is stored in provenance.extra:

from traincraft.geometry import build_geometry
from traincraft.config.models import CrystalBuilder, DefectSpec, GeometryConfig

s = build_geometry(GeometryConfig(
    builder=CrystalBuilder(
        name="Cu", crystalstructure="fcc", a=3.6, cubic=True,
        supercell=(2, 2, 2),
        defects=[DefectSpec(kind="vacancy", index=0)],
    )
))
print(s.provenance.extra)
# {'defects': [{'kind': 'vacancy', 'index': 0, 'element': None}]}

Summary

Defect type TOML kind Required fields
Remove an atom "vacancy" index
Swap an element "substitution" index, element
Add an atom "interstitial" element, position

Next: Tutorial 5 — standalone surface slabs and mechanical deformation.