A diagnostic viewer for DFT geometry-relaxation output — diff two crystal structures, surface every meaningful change (atomic displacement, bond & coordination shifts, cell strain, symmetry breaking) and read a one-paragraph LLM narrative that explains whether the relaxation looks reasonable.
Live demo · Quick start · Showcase · How it works · MIT License
git clone https://github.com/siyu-hu/relaxdiff && cd relaxdiff
python -m venv .venv && source .venv/bin/activate
pip install -e .
relaxdiff before.cif after.cif -o report.html
open report.html # macOS — use xdg-open on LinuxDon't want to install anything locally? Spin up a preconfigured Codespace in your browser:
The Codespace auto-runs pip install -e . on first boot, so once it's ready you can run the CLI directly in the integrated terminal.
Built for: VASP, Quantum ESPRESSO, ABINIT, CP2K, ASE, pymatgen, MACE / CHGNet relaxations — anything that writes a CIF / POSCAR / extxyz before-and-after pair.
Most crystal structure viewers let you see a relaxation. RelaxDiff tells you whether it looks reasonable.
It diffs two structures along every axis a researcher cares about — per-atom displacement, bond breaking / forming, coordination changes, cell strain, space group changes — and produces a self-contained HTML report with a 3D viewer, severity-tagged findings, and a short natural-language narrative. One command. No server. No toolchain.
relaxdiff before.cif after.cif -o report.htmlSupported input formats: CIF · POSCAR / CONTCAR / .vasp · .xyz / .extxyz · pymatgen JSON · ASE Atoms (when used as a library). Both structures must share composition and atom count.
|
Interactive 3D diff viewer Toggle Before / After / Overlay / Diff heatmap. In Diff heatmap mode every atom is colored by how far it moved — small movement blue, big movement red — so problem atoms jump out at a glance.
|
Severity-tagged diagnosis Eleven rules turn raw geometry into severity-tagged findings: large displacement, runaway atoms, cell collapse, bond breaking, coordination changes, broken or elevated symmetry, large shear. Every report gets an overall OK / INFO / WARN / ALERT chip.
|
|
LLM narrative (optional) Reads the structured diagnosis JSON — never raw coordinates — and produces a three-paragraph plain-English read of the result, citing specific atom indices. Works with any OpenAI-compatible LLM endpoint (see below). Without an API key, a deterministic template covers the same ground. |
Adaptive symmetry detection Runs a tolerance scan with spglib and picks an effective symprec automatically, so a small rattle doesn't get misread as full P1 collapse but a real distortion still trips the rule.
|
Four predefined cases, auto-built and deployed to the gallery:
| Case | Severity | What it shows |
|---|---|---|
| MgO normal relax | Clean baseline — what an unremarkable relaxation looks like | |
| SrTiO₃ octahedral tilting | Cubic → tetragonal-tilted variant; symmetry breaking + coordination shifts | |
| Si cell collapse | Cell pressed to ~78% of original volume; full symmetry loss | |
| TiO₂ strained variant | Large shear + heavy rattle; broken bonds + coordination changes |
Rebuild them locally in seconds (no DFT, no ML potential — just geometric construction):
python examples/build.pypython -m venv .venv && source .venv/bin/activate
pip install -e .relaxdiff before.cif after.cif -o report.htmlOpen report.html in any browser. Self-contained, no server required.
--title TEXT Report title shown in the header
--no-llm Skip the LLM narrative, use the deterministic template
--json PATH Also dump structured diagnosis as JSON
--threshold-displacement Override the default 0.5 Å warn threshold (Å)
RelaxDiff talks to any OpenAI-compatible chat-completions endpoint — OpenAI, DeepSeek, Together, Groq, Fireworks, Ollama, your own vLLM server, etc.
cp .env.example .env
# edit .env with your LLM provider's API key, model, and base URL
export $(grep -v '^#' .env | xargs)
relaxdiff before.cif after.cif -o report.htmlWithout RELAXDIFF_LLM_API_KEY (or with --no-llm), the report falls back to a deterministic three-paragraph template. No internet required.
| Provider | RELAXDIFF_LLM_MODEL |
RELAXDIFF_LLM_BASE_URL |
|---|---|---|
| DeepSeek | deepseek-chat |
https://api.deepseek.com |
| OpenAI | gpt-4o-mini |
https://api.openai.com/v1 |
| Together | e.g. meta-llama/Llama-3-8b-chat-hf |
https://api.together.xyz/v1 |
| Groq | e.g. llama-3.1-70b-versatile |
https://api.groq.com/openai/v1 |
| Ollama (local) | e.g. llama3 |
http://localhost:11434/v1 |
CI auto-rebuilds and deploys the gallery on every push to main. It uses the deterministic narrative by default — no API calls, no token cost.
To regenerate narratives with an LLM from CI:
- Repo → Settings → Secrets and variables → Actions → add a repo secret named
RELAXDIFF_LLM_API_KEY. Optionally addRELAXDIFF_LLM_MODELandRELAXDIFF_LLM_BASE_URLas variables (not secrets). - Repo → Actions → Deploy demo site to GitHub Pages → Run workflow → tick
use_llm.
.env is gitignored. CI only sees the secret on the manual use_llm=true path. Nothing in this repo ever stores a key in plain text.
two structures
↓ pymatgen StructureMatcher (Hungarian fallback) site-by-site mapping
↓ geometry + symmetry analysis deterministic
↓ 11 rules + adaptive symprec severity-tagged findings
↓ OpenAI-compatible LLM (or fallback template) 3-paragraph narrative
↓ Jinja2 + 3Dmol.js self-contained HTML
report.html
The LLM is the last thing in the pipeline and only ever sees structured JSON — atom indices, magnitudes, rule outputs — not raw coordinates. Hallucination surface stays small. See PLAN.md for the full design.
- Not a general structure viewer (use matterviz)
- Not an MD defect analyzer (use OVITO)
- Not a VESTA plugin (VESTA has no plugin API)
- Not a real-time interactive editor
DFT relaxation · ionic relaxation diagnostics · crystal structure diff · before/after relaxation comparison · VASP / Quantum ESPRESSO / ABINIT / CP2K post-processing · pymatgen + ASE · spglib symmetry analysis · materials informatics · interactive 3D structure viewer · LLM for materials science
MIT

