Deep, code-cited reference. See the readable summary for the public version. This page is the full provenance: canonical formula, cleaved↔uncleaved pairing, rollup schema, best-available rule, error taxonomy.

Work of Separation Benchmark — Methodology

Scientific and numerical specification of the cleavage (W_sep) track for the mlip-benchmark-gbsegbench corpus. Covers the canonical W_sep formula, how the cleaved↔uncleaved pair is matched in the DB, the per-(potential, structure_id) best-available rule, the rollup CSV schema, and the error taxonomy used by the leaderboard.

Reference implementation: benchmark/build_wsep_dfs.py (the CLEAVAGE_SQL linkage query plus the per-potential W_sep column build).


1. Quantity computed

For each cleavage row, the work of separation in J/m² is the textbook single-plane normalization

W_sep = (E_cleaved - E_uncleaved) / A_plane · EVA2_TO_JM2     [J/m^2]

with EVA2_TO_JM2 = 16.02176565 (the constant in build_wsep_dfs.py:39) and A_plane = the area of the one cleavage plane in Ų.

Sign convention. Positive ⇒ energy required to separate the two half-cells. W_sep is the adhesion energy of the interface, not the surface energy γ of a free surface (γ = W_sep / 2 for an ideal symmetric cleave).

How A_plane is sourced — important convention note

Historically the cleavage rows were ingested with extra->>'area_A2' set equal to 2 · A_plane — i.e. the total free-surface area created by the cleave (two faces, each of area A_plane). The pre-computed DFT quantity stored as extra->>'W_sep_J_per_m2' followed W_sep_stored = ΔE / (2·A_plane), which is the surface energy γ, not the textbook work of separation.

The current build_wsep_dfs.py restores the textbook convention by multiplying the stored γ values by 2 on read and by NOT applying the extra /2 in the surrogate formula. Operationally:

# DFT side (build_wsep_dfs.py:128)
df["dft_w_sep"] = df["dft_w_sep"] * 2.0     # γ → W_sep

# MLIP side (build_wsep_dfs.py:163-164)
w = 2.0 * (E_cleaved - E_uncleaved) / area_a2 * EVA2_TO_JM2
  ≡ (E_cleaved - E_uncleaved) / A_plane * EVA2_TO_JM2          [A_plane = area_a2 / 2]

Both sides now publish the same convention. Every wsep_* metric on the live leaderboard is the corrected (×2) value; a representative row (GRACE-2L-OAM-L, Fe-host, S5-RA001-S210, n_pairs = 7410) shifted from wsep_rmse_jm2 = 2.4113214.822641 (exactly 2×); Spearman ρ unchanged at 0.828861 (scale-invariant under uniform rescaling).

Symbol Meaning
E_cleaved total energy of the cleaved GB structure (two half-cells, one cleave plane)
E_uncleaved total energy of the uncleaved precursor (same cell, no cleave)
area_a2 (extra->>'area_A2')::float; = 2 · A_plane (the sum of the two free-surface areas, by ingest convention)
A_plane the area of the single cleavage plane in Ų (= area_a2 / 2)
EVA2_TO_JM2 unit-conversion constant 16.02176565 (1 eV/Ų = 16.02176565 J/m²)
cleave_idx enumerated cleave-plane index within the parent GB
cleave_z_frac normalised z-position of the cleave plane

DB key: (structure_id, potential) for the cleaved row; the uncleaved energy is joined in on demand.


2. Cleaved↔uncleaved pairing (the linkage SQL)

The structure.extra jsonb on a cleavage row carries:

The linkage SQL (build_wsep_dfs.py:34-66) joins:

SELECT c.*, bp.base_id, bp.base_atoms_hash, bp.base_dft_energy
FROM cleav c
LEFT JOIN base_pick bp ON bp.cleav_id = c.cleav_id;

Where cleav is state='Cleavage' AND extra->>'W_sep_J_per_m2' IS NOT NULL, and base_pick resolves the uncleaved precursor by:

JOIN structure b ON b.job_name = c.base_name AND b.state != 'Cleavage'
ROW_NUMBER() ... ORDER BY b.id  -- lowest id when multiple variants match

Multiple structures may share the same base_job_name (KP / KS / OMAT sibling generation), but they all map to the same atoms_hash (de-duplicated on ingest), so any one resolves to the same MLIP energy. The ROW_NUMBER() tiebreak just picks the lowest-id sibling deterministically.


3. Why no W_sep_corrected

W_sep is a difference of total energies between two cells of the same composition (the cleaved pair and its uncleaved precursor). The per-(composition, ISPIN) offset corrections used on the ASSYST single-point track cancel by construction in the formula. We do NOT emit a W_sep_corrected column on this track.


4. Best-available algorithm rule

Relaxation initial frame. As on the segregation track, the MLIP relaxation is initialised from the unrelaxed (as-constructed / DFT-input) geometry — the relaxation's initial frame is the unrelaxed structure, not the DFT-relaxed frame.

The cleavage corpus rides the same relaxation campaign as the segregation corpus. For each (potential, structure_id) the rollup picks the best-available result:

algo_used = 'BFGS' if status_BFGS == 'done'
            else 'FIRE' if status_FIRE == 'done'
            else NULL (excluded)

energy_used = E_final from algo_used

A W_sep value is reported only when both the cleaved row AND its uncleaved precursor have a best-available done energy for that potential. Missing either ⇒ NaN ⇒ row excluded from the rollup.

Per-row provenance is preserved via algo_used_cleaved, algo_used_uncleaved, and per-potential counts n_best_from_bfgs, n_best_from_fire (a row counts toward n_best_from_fire if either side came from FIRE).


5. Outlier filter

The build script filters catastrophic MLIP failures (build_wsep_dfs.py:32, 137):

OUTLIER_LIMIT = 1e4   # eV per cell

if energy is None or not np.isfinite(energy) or abs(energy) > OUTLIER_LIMIT:
    drop this (pot, atoms_hash) pair

For a typical 50–200 atom GB cell, |E| > 1e4 eV is unphysical — usually an MLIP exploding on an out-of-distribution element. The energy stays in mlip_calc; it just doesn't propagate into W_sep.


6. Rollup CSV schema (per_potential_wsep.csv)

One row per (potential, host, GB, partition) bucket plus __all__ aggregate rows. Consumed by /cleavage and the cleavage drill-down on /elements/[el].

column type meaning
potential str normalized potential id
display_name str display name from metadata.json / gbseg-metadata.json
host str Fe or Ni
gb str grain-boundary id
partition str gbseg-cleavage (the only partition on this track)
n_pairs int number of (cleavage_row, potential) with W_sep on both sides
n_best_from_bfgs int count of pairs where both sides came from BFGS
n_best_from_fire int count of pairs where either side came from FIRE
wsep_rmse_jm2 float RMSE of (W_sep^MLIP − W_sep^DFT) in J/m²
wsep_mae_jm2 float MAE of the same
wsep_spearman float Spearman ρ of W_sep^MLIP vs W_sep^DFT
snapshot_date date per-potential rollup-build date

The headline number on the leaderboard is wsep_rmse_jm2 from the __all__ row, count-weighted across (host, GB).


7. Aggregation (count-weighted, two-step)

Matches the ASSYST headline pattern:

  1. Per-bucket at (potential, host, gb, partition) level: RMSE = sqrt(mean((W_sep^MLIP - W_sep^DFT)^2)), MAE, Spearman ρ over the cleavage pairs where the MLIP has best-available done on both sides.
  2. Top-line at (potential, partition) level: count-weighted mean of the bucket-level metrics, weights = n_pairs per bucket.

Both wsep_rmse_jm2 and wsep_mae_jm2 are emitted. RMSE is the default leaderboard headline; MAE is shown alongside.


8. Error taxonomy

Same five-class enum as the segregation track (see /methodology/deep/segregation §7). On W_sep, the relevant rule of thumb is:

The errored sides are surfaced on the errors.parquet.py loader, scoped to gbseg-cleavage.


9. Implementing code

Linked into the wiki hub at /u/hmai/llm-wiki/wiki/mlip-benchmark-gbsegbench-relax.md.


10. Partitions

partition corpus comment
gbseg-cleavage FeGB / NiGB cleavage pairs only partition on this track

E_seg lives on its own page — see /methodology/deep/segregation.


11. Parameter summary

Parameter Value
W_sep (E_cleaved - E_uncleaved) / A_plane · 16.02176565 [J/m²], with A_plane = area_a2 / 2
Sign convention positive ⇒ energy required to separate the two half-cells
Energy field smeared VASP energy
area_a2 from extra->>'area_A2'; historically ingested as 2·A_plane — divide by 2 to get the single-plane area used by W_sep
DFT γ→W_sep correction df["dft_w_sep"] *= 2.0 on read (build_wsep_dfs.py:128) so DFT and MLIP sides match the textbook convention
BFGS protocol fmax = 0.01 eV/Å, max_steps = 10000
FIRE handback fmax = 0.01 eV/Å, max_steps = 250, merged 2026-06-13
Best-available rule per-side, both sides required done
Outlier filter |E| > 1e4 eV per cell → drop
Aggregation count-weighted two-step, RMSE default, MAE alongside
Magnetic facet not introduced (corpus is all-magnetic by definition)
Corrected variant not introduced (offsets cancel by construction)
DB key (structure_id, potential) on each side; pair joined by linkage SQL

Implementation: benchmark/build_wsep_dfs.py · rollup builder: benchmark/eval/build_gbseg_rollup.py (Task B) · page consumer: src/cleavage.md + src/elements/[el].md (Task D) · wiki hub: wiki/mlip-benchmark-gbsegbench-relax.md.