Skip to content

Fix DiffractionSim coordination polyhedra for Si, SrTiO3 and elemental metals - #249

Merged
cophus merged 1 commit into
electronmicroscopy:mainfrom
cophus:polyhedra
Nov 4, 2026
Merged

cophus merged 1 commit into
electronmicroscopy:mainfrom
cophus:polyhedra

Conversation

@cophus

@cophus cophus commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator

What problem does it solve?

The coordination polyhedra of DiffractionSim (cellGeometry in js/diffractionsim/crystal3d.ts) were wrong for elemental crystals and for compounds with more than one cation species. The rule drew a polyhedron around every species except the most numerous one, bonded each centre to every atom of another species within 1.2 (r_i + r_j) of the covalent radii, and accepted 4 to 14 neighbours. The presets, CIFs loaded in the browser (including the quantem.diffsim page planned for the Materials Project TEM tab) and the Jupyter widget all showed two problems:

  • Every atom of an elemental crystal got a polyhedron. Each Si tetrahedron is correct (4 neighbours at 2.35 Å), but the tetrahedra on both fcc sublattices interpenetrate, their faces merge on shared {111} planes into triangles with twice the edge length, and the tetrahedra on the cell boundary extend a/4 past the cell to atoms that are not drawn. The Al and Au (fcc), Fe (bcc) and Ti (hcp) presets drew cuboctahedra or rhombic dodecahedra around every atom, with 126 to 196 faces per cell.
  • Cations bonded to each other. The Sr–Ti distance in SrTiO3 is 3.38 Å, inside the 4.26 Å cutoff, so Ti got 8 Sr and 6 O neighbours and was drawn as the cube of Sr atoms, while Sr, with 20 neighbours, got no polyhedron.

This PR changes the rule. In a compound, centres bond only to the ligand species (the most numerous species, as before), and a polyhedron is drawn for 4 to 8 ligands. In an elemental crystal, polyhedra are drawn on one set of a two-set (bipartite) neighbour network, choosing the set with fewer sites on the cell boundary so that its polyhedra stay inside the cell. Elemental crystals without such a network, including the fcc, bcc and hcp metals, get no polyhedra. The polyhedron faces of one unit cell on main and on this branch are:

Structure main this PR
Si (preset) 72 triangles, tetrahedra on all 8 atoms 16 triangles, 4 SiSi4 tetrahedra inside the cell
SrTiO3 (preset) 6 faces of the Sr cube around Ti 8 triangles of the TiO6 octahedron
Al, Au, Fe and Ti (presets) 126 to 196 faces none
GaAs, NaCl and Al2O3 (presets) 16, 104 and 192 faces unchanged
Si, SrTiO3 and GaN (pymatgen CIFs) 68, 11 and 8 faces 16, 8 and 8 faces

The quantem.diffsim 0.1.0 release waits for this fix, since its page draws the same polyhedra.

What should reviewer(s) do?

  • Read polyhedronSites and the neighbour loop in cellGeometry (js/diffractionsim/crystal3d.ts). The two-set test colours the neighbour network of the sites over periodic images, so a one-atom simple cubic cell, whose two sets differ only by a lattice translation, also gets no polyhedra.
  • Check whether 8 is a suitable upper limit for compounds. It removes the SrO12 cuboctahedra of perovskites, which would otherwise fill the space between the TiO6 octahedra, and keeps every polyhedron of the compound presets, which have 4 or 6 ligands.
  • js/diffractionsim/crystal3d.test.ts checks Si (16 faces with edges of a/√2 = 3.84 Å and every vertex on a drawn atom), SrTiO3 (8 triangles with edges of 2.76 Å) and fcc Al (no faces).

Verification

  • npx vitest run js/diffractionsim js/diffractionsim-web with Node 22: 14 passed, including the 3 new cases.
  • npx tsc --noEmit: no errors.
  • npm run build:web and npm run build -- diffractionsim (quantem.gpu dc8f0398): both bundles build, and they are the only bundles that import crystal3d.ts.
  • pytest -q tests/diffractionsim tests/diffsim tests/infrastructure/test_public_repository.py: 59 passed and 2 skipped.
  • Full suites: npm run build builds every bundle, npx vitest run gives 392 passed and 2 skipped (5 display and show3dslices test files call Python for NumPy reference values and need a Python whose NumPy loads), and PYTHONPATH=src pytest -q gives 668 passed and 223 skipped, with the same 2 local-environment failures as in Add DiffractionSim and quantem.diffsim, and remove the abTEM dependency #245 (a sibling quantem.gpu checkout at another commit, and an lxml without lxml_html_clean).
  • The table above lists the faces from cellGeometry on main and on this branch for the 9 presets and for Si, SrTiO3 and GaN written by quantem.diffsim.structure_to_cif from pymatgen structures.
  • Chromium, save_html pages with polyhedra on: Si along [112] shows 4 tetrahedra inside the cell with their corners on drawn atoms, SrTiO3 along [112] shows the TiO6 octahedron with Sr drawn as spheres, and GaN along [11-23] shows the same NGa4 tetrahedra as on main, with no console errors.
  • Not checked: the widget inside JupyterLab.

Written by Colin Ophus and Claude (Claude Code).

…ements

In a compound, polyhedron centres now bond only to the most numerous
species and are drawn for 4 to 8 ligands, so Ti in SrTiO3 gets TiO6
instead of the cube of its 8 Sr neighbours. An elemental crystal gets
polyhedra on one set of a two-set neighbour network, the set with fewer
sites on the cell boundary, so Si shows four SiSi4 tetrahedra inside the
cell instead of tetrahedra on all eight atoms, and fcc, bcc and hcp metals
get none. GaAs, NaCl, Al2O3 and GaN are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
  • Delete cophus/quantem.widget:polyhedra from its remote if you own it, it is not long-lived, and no other PR uses it.
  • Remove the dedicated worktree and local polyhedra branch after confirming the worktree is clean.
  • Fetch electronmicroscopy/quantem.widget and update local main before starting new work.

@cophus
cophus merged commit 6ce1ff0 into electronmicroscopy:main Nov 4, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant