Repository navigation
Add opt-in "sapt0-bj" D3(BJ) damping set and a cached pair-term path for fitting - #36
Conversation
…for fitting d3() is split into d3_pair_terms() (CN, C6, C8/C6 quotient, distances; damping-independent) and d3_pair_energies() (applies s6/s8/a1/a2 and keeps autograd for tensor parameters). d3() composes them and returns bit-identical energies; evaluating new damping parameters on cached pair terms is ~80x faster than calling d3(). resolve_d3_damping_parameters() also accepts a name from D3_DAMPING_PARAMETER_SETS: "sapt-pbe0-d3i" (the unchanged default) and the new opt-in "sapt0-bj" (s6 1, s8 1.0896, a1 0.3836, a2 2.4363 bohr), an MAE fit to SAPT0/aug-cc-pVDZ dispersion of a seeded 200k subsample of the 1600K train split. Held out, dispersion MAE vs SAPT0 drops from 0.611 to 0.493 (1600K test), 0.694 to 0.462 (S66x8) and 0.507 to 0.388 (PDB13K). No model or default uses the new set. Already merged into mastiff-classical as #35; this carries the same patch to main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fit error statistics vs SAPT0 dispersionThe target is
Errors are D3 − SAPT0 (negative = over-binding). MSE is in (kcal/mol)²; all other columns are kcal/mol.
† s8 is pinned at its lower bound. With s6 free under MSE, s8 is traded away for a larger s6, which reflects a degenerate s6/s8 direction rather than information in the data. Freeing s6 improves MAE by only 0.0013 and MSE by 0.013, so s6 stays at 1. Refit on the check set from scratch (same 18 starts):
Optimiser:
Where the error is:
Held out, for reference (MAE; default →
Source: qcmlforge-exp |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe D3 API adds an opt-in SAPT0-BJ damping parameter set and accepts registered set names. Pair-term calculation is separated from damped energy calculation. Tests cover parameter resolution, energy equivalence, and gradients. ChangesD3 damping and energy calculation
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant D3 as d3
participant Resolver as resolve_d3_damping_parameters
participant Terms as d3_pair_terms
participant Energies as d3_pair_energies
D3->>Resolver: Resolve damping parameters
D3->>Terms: Compute pair terms
D3->>Energies: Apply damping parameters to pair terms
Merge Risk: ⚪ Minimal · up to The new damping set is opt-in, and no actionable issue is established that would prevent merging after normal checks. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Adds an opt-in D3(BJ) damping set fitted to SAPT0 dispersion, plus a split of
d3()that makes fitting cheap. Defaults are unchanged; no model or pipeline uses the new set.sapt0-bjis an MAE fit to SAPT0/aug-cc-pVDZ dispersion (Disp_aug) over a seeded 200k subsample of the 1600K train split. A disjoint 200k refit agrees to ≤ 0.018 in every parameter. The fit, validation, figures and provenance are on the qcmlforge-exp branchd3-sapt0, underanalysis/d3-sapt0/fit-v1/(results.md).Same patch as #35 (merged into
mastiff-classical), as one commit onmain: 2 files, +170/−19.d3.pyonmainis identical to the base #35 applied to.Evidence
Held-out D3 dispersion error vs SAPT0 (kcal/mol). Nothing below was fitted on. "MAE fit" is
sapt0-bj; "MSE fit" is the same procedure under an MSE loss and is not registered.sapt-pbe0-d3isapt0-bjSizes: the 1600K test split has 150,000 dimers, S66x8 528 points, PDB13K 13,326 dimers.
Figures are on qcmlforge-exp
d3-sapt0, underanalysis/d3-sapt0/fit-v1/figures/:fig_s66x8_disp_curves: the dispersion column of the manuscript S66x8 curves.fig_s66x8_disp_mae_by_scalefig_1600k_test_disp_parityfig_pdb13k_dispPLA15 has no SAPT0 dispersion reference: the
sapt0-d4(i)record's dispersion is D4(I), so it is not a check.Speedup (Hornet, 8 CPU threads, 2,000 1600K-test dimers / 361,001 A–B pairs, two runs each):
d3()@ 06d1475d3()d3_pair_termsonced3_pair_energiesper evaluationd3()itself is neither faster nor slower; the default energy sum is bit-identical (−6377.2534 old and new).d3(), with bit-identical energies (torch.equalasserted on 20 parameter sets).Tests:
tests/test_dftd3_params.py(new, 8 passed):On this branch (based on
main), the new tests and every existing D3 consumer pass unchanged:test_dftd3_params.py+test_ap3_d3_fused.py: 32 passed.test_ap3_fused.py,test_pt_dataset.py,test_model_io.py,test_classical_components.py,test_freeze_unfreeze.pyand 6 more: 170 passed, 28 skipped.Merge Danger
Door: two-way
Additive API plus a pure refactor of
d3(). Nothing selects"sapt0-bj"unless a caller names it, and reverting removes one dict entry and re-inlines two functions.Blast Radius: none-by-default
Every model resolves
Noneto the unchanged default. The one behavioural widening is thatresolve_d3_damping_parametersnow accepts a string, so a string that used to fail withAttributeErrornow resolves a named set, and an unknown name raisesValueError. Adoptingsapt0-bjunder an already-trained -D3 model (AP3D3-FF, E5g-x + D3, CLIFF2 + D3) changes its dispersion baseline and needs a retrain; that decision is deliberately left out of this PR.🤖 Generated with Claude Code
Summary by CodeRabbit