Skip to content

Surfaces & Slabs ​

Generate surface slabs from bulk crystals using Miller indices, add vacuum layers, and find adsorption sites.

Source: src/lib/structure/miller-slab.ts, src/lib/structure/ferrox-wasm.ts

Overview ​

The slab cutter takes a bulk crystal and creates a surface slab by:

  1. Specifying Miller indices (h, k, l) to define the surface orientation
  2. Setting slab thickness (number of layers)
  3. Adding vacuum for surface separation in periodic calculations

Two code paths are available:

  • Preview (JS) — fast JavaScript preview for real-time visualization
  • Apply (WASM) — full slab generation via Rust/WASM for final output

Key Functions ​

Miller Index Utilities ​

typescript
// Normalize Miller indices by dividing by GCD
normalize_miller(h, k, l): [number, number, number]

// Validate that at least one index is non-zero
validate_miller(h, k, l): boolean

// Convert Miller indices to surface normal in Cartesian coordinates
miller_to_normal(h, k, l, lattice_matrix): number[]

Slab Generation ​

typescript
// JavaScript preview pipeline (fast, approximate)
generate_slab_pipeline(structure, miller, thickness, vacuum): SlabPreview

// Full WASM slab generation (accurate, final output)
wasm_generate_slab(structure, miller, min_thickness, min_vacuum): Structure

// Generate slab from configuration object
generate_slab_from_config(structure, config): Structure

Lattice Handedness ​

typescript
// Ensure slab lattice is right-handed: (a x b) . z > 0
ensure_slab_right_handed(a_vec, b_vec): { a: number[], b: number[] }

Atom Visibility ​

typescript
// Compute per-atom visibility for animated cutting preview
get_atom_visibility(structure, cutting_plane): number[]

Interactive Slab Cutter ​

The MillerSlabCutterPane component provides a UI for:

  • Miller index input — h, k, l fields
  • Thickness control — minimum slab thickness in Angstroms
  • Vacuum control — vacuum layer thickness
  • Live preview — cutting plane visualization overlaid on the structure
  • Apply — generate the final slab and replace the structure

Cutting Plane Visualizer ​

The CuttingPlaneVisualizer renders translucent planes showing where the surface cuts the crystal. Planes are positioned using center + n*(d - c_proj) to center on the crystal.

Adsorption Sites ​

The AdsorptionSitePane uses ray-casting to find surface adsorption sites:

  • Atop — directly above a surface atom
  • Bridge — between two surface atoms
  • Hollow — above the center of 3+ surface atoms

Sites are placed at covalent radius distance from the surface.

Data Flow ​

Structure.svelte
  ├── passes `structure` to MillerSlabCutterPane (editing)
  ├── passes `displayed_structure` to StructureScene (rendering)
  │   └── includes PBC image atoms from get_pbc_image_sites()
  └── cutting_atom_visibility computed from original structure only

Vacuum Layer ​

typescript
// Add vacuum along a lattice direction
add_vacuum_layer(structure, thickness, direction): Structure

// Interactive vacuum box modal
VacuumBoxModal.svelte  // Add vacuum in any direction(s)

Conventions ​

  • Right-handed lattice is always enforced after slab generation
  • The WASM path adjusts fractional b-coordinates (negate + wrap) when fixing handedness
  • Surface normal is computed from the reciprocal lattice vectors

CatGo is licensed under AGPL-3.0-or-later. If CatGo contributes to your work, please include “This work used CatGo (https://app.catgo-ucsd.org).” and the preferred citation in CITATION.cff. This request is not an additional condition of the AGPL license.