Handover — v0.9.0 composite “3c” methods stack

Status snapshot for the v0.9.0 composite-methods milestone. If another chat picks this up, start here.

Where it stands (2026-05-21 — LANDED on main)

The composite layer is pushed to origin/main — 2 commits: 147443e4 (the 4 cpp/src/xc.cpp composite-parent functional aliases) and c13ed1fd (the Python composite layer + bundled data). Verified green at the pushed tip: 140 tests pass (87 new composite/gCP/data_library/xc_mgga/xc_rsh + 53 test_xc.py regression). A v0.9.0 release-status drop-box for the release chat is at .release-status/v0.9.0/mol-methods.md (gitignored, local-only).

All 7 composite 3c methods are RUNNABLE end-to-end via vq.run_job(method="<name>", ...):

Composite

Status

Notes

HF-3c

RUNNABLE

MINIX basis + gCP + SRB + D3-BJ

PBEh-3c

RUNNABLE

modified-PBE0 alias + def2-mSVP + gCP + D3

B97-3c

RUNNABLE

def2-mTZVP + D3-BJ + gCP (+ SRB, approx.)

B3LYP-3c

RUNNABLE

def2-mSVP + gCP + D3-BJ

r²SCAN-3c

RUNNABLE

def2-mTZVPP + D4 + gCP

ωB97X-3c

RUNNABLE

vDZP + D4 (vDZP gCP per-element data partial)

HSE-3c

RUNNABLE

def2-mSVP + gCP + D3-BJ

The rebase story — READ THIS FIRST

This branch forked at vibe-qc v0.7.5-era and was developed against that base. By the time it came to land (2026-05-19), origin/main had advanced 200+ commits. Critically, upstream independently implemented both F1 (range-separated hybrids) and F3 (meta-GGA τ-density) in its v0.8.x → v0.9.0 functional sweep — the same features this branch had built in parallel.

The rebase therefore dropped this branch’s entire F1 + F3 C++ implementation (it was functionally equivalent to upstream’s, just with different variable names). The branch was reduced via a clean selective replay onto current origin/main to only the genuinely-new, non-redundant layer:

  • vibeqc.composites — the 3c recipe registry (no upstream equivalent)

  • vibeqc.gcp + _gcp_slater.py — geometric counterpoise

  • data_library/ — the TOML parameter-storage standard

  • 5 bundled 3c orbital bases + vDZP ECPs

  • run_job composite dispatch in runner.py

  • 4 functional aliases in cpp/src/xc.cpp (pbeh-3c, b97-3c, hse06, wb97x-v) — the composite parent functionals upstream’s sweep did not register

Upstream is authoritative for F1 + F3. Its accessors are Functional::is_range_separated() / rsh_omega() / cam_alpha() / cam_beta() and JKBuilder::build_K_erf(D, omega). If you touch RSH or mGGA C++, work from upstream’s implementation, not this branch’s git history.

What this branch contributes (the v0.9.0 composite layer)

  • C1-C5 composite frameworkvibeqc.composites recipe registry, run_job(method=...) keyword dispatch, vibeqc.gcp standalone gCP API, ShortRangeCorrection (SRB), docs/user_guide/composites.md.

  • gCP — shell-aware analytic STO overlap (_gcp_slater.py, ported from the Grimme-lab mctc-gcp Fortran reference), per-element data for 6 basis sets under data_library/gcp/*.toml.

  • data_library/ standard — TOML parameter storage with required citation + DOI + license metadata. data_library/README.md is the normative spec; the first concrete consumer is gCP, with dispersion / EEQ / functional-alias / Lebedev migrations as the Phase-2 plan.

  • 3c orbital bases — def2-mSVP, def2-mTZVP, def2-mTZVPP, vDZP, MINIX bundled (+ vDZP ECPs). Per CLAUDE.md § 4 this is an explicit, maintainer-approved override of the basissetdev rule, documented in the per-file .g94 headers.

  • 4 functional aliases in cpp/src/xc.cpppbeh-3c (modified PBE0, 42% HF), b97-3c (XC_GGA_XC_B97_3C), hse06, wb97x-v.

v0.9.x patch follow-ups (NOT v0.9.0 blockers)

  • vDZP gCP per-element data — ωB97X-3c’s gCP step currently logs SKIPPED (the vDZP TOML carries the σ/η/α/β fit constants but not the per-element e_mis / n_virt rows). Müller-Hansen-Grimme 2023 SI transcription needed; follow scripts/extract_gcp_data.py.

  • Canonical SRB for HF-3c + B97-3c — research complete, ready to execute. Full spec in the section below.

  • Direct/DF/COSX long-range-K — large-system RSH SCF. Upstream’s F1 wired the FourIndex path; check origin/main for which JKBuilder concretes have build_K_erf before assuming this is still open.

  • data_library/ Phase 2 — migrate dispersion / EEQ / functional- alias / Lebedev hot-path data to the TOML standard + a codegen script. See data_library/README.md § Phase 2.

v0.9.x — canonical SRB: implementation spec (research done)

The short-range bond correction shipped in v0.9.0 (ShortRangeCorrection in composites.py) is a documented simplification and is non-canonical for both recipes that use it. The exact reference forms were pinned against the authoritative Grimme-lab source (grimme-lab/gcp, src/gcp.f90, LGPL-3.0 — the same project the gCP port already came from) and the ORCA 6.1 manual § 3.6. No physics is left to guess; this is now pure execution.

The two recipes use genuinely different SRB functional forms — the current single evaluate() (-s·Σ(Z_aZ_b)^0.5·exp(-γ·R^{1/3})) matches neither.

  • HF-3c SRBgcp.f90::basegrad, applied for elements Z = 1–18 only:

    E_SRB = -qscal · Σ_{A<B}  (Z_A Z_B)^{3/2} · exp(-rscal · r0ab_AB^{0.75} · R_AB)
    

    qscal = 0.03, rscal = 0.7. (Matches ORCA manual eq. for HF-3c: s = 0.03, γ = 0.7.)

  • B97-3c SRBgcp.f90::srb_egrad2 (“modified form derived from the HF-3c SRB potential”, SG Nov-2016), applied for all elements:

    E_SRB = -qscal · Σ_{A<B}  (Z_A Z_B)^{0.5} · exp(-(rscal / r0ab_AB) · R_AB)
    

    qscal = 0.08, rscal = 10.0.

  • r0ab_AB — the DFT-D3 ab-initio cut-off-radii table (Grimme, Antony, Ehrlich, Krieg, J. Chem. Phys. 132, 154104, 2010). Source: gcp.f90::setr0ab — a 4465-element packed lower triangle of the symmetric 94×94 matrix (94·95/2 = 4465), in (/ /) blocks of 70 reals. Unpack: k=0; for i in 1..94: for j in 1..i: k+=1; r[i][j]=r[j][i]=r0ab[k]. Values are in Å in the file and converted with autoang = 0.5291772083 inside setr0ab.

Sequencing decision (2026-05-21): land all three steps below as one reviewable unit after the v0.9.0 tag is cut — not piecemeal. Steps 1–2 are technically additive/safe-anytime, but landing a tested-but-unused evaluator on release-day main is needless churn, and steps 1–3 review better together.

Implementation steps:

  1. Extract setr0abdata_library/dispersion/r0ab_d3.toml (new data_library category; full citation/DOI/license metadata per the data_library/README.md spec; LGPL-3.0 redistribution via grimme-lab/gcp, underlying data DOI 10.1063/1.3382344).

  2. Add a canonical SRB evaluator (new code — does not change any energy yet): a kind-discriminated ShortRangeCorrection carrying (qscal, rscal, form) where form {hf3c_base, b973c_mod}, plus the r0ab lookup. Unit-test in isolation.

  3. Recipe flip (the only step that changes energies): point the hf-3c and b97-3c recipes at the canonical evaluator with the parameters above.

⚠️ Release coordination — step 3 shifts the HF-3c and B97-3c composite total energies, i.e. it changes the B97-3c -76.391 figure in the CHANGELOG and the test_composite_integration windows for those two composites. Per CLAUDE.md § 11 that is a CHANGELOG-affecting change. Combined with the sequencing decision above: the whole increment waits for the v0.9.0 tag, then lands as one unit and updates the CHANGELOG figure + test windows in the same commit.

Key files

  • python/vibeqc/composites.py — recipe registry + dispatch types

  • python/vibeqc/gcp.py + _gcp_slater.py — gCP

  • python/vibeqc/data_library/ — parameter TOMLs + the standard

  • python/vibeqc/runner.pyrun_job composite dispatch

  • cpp/src/xc.cpp — the 4 composite-parent functional aliases

  • scripts/extract_gcp_data.py, scripts/fetch_3c_orbital_bases.py — maintainer-side data extraction (one-shot; outputs committed)

  • tests/test_{gcp,composites,composite_integration,xc_mgga,xc_rsh,data_library}.py