feat(optimizer) :: OCINEB restore, LBFGS options, and the xtsci engine - #403
feat(optimizer) :: OCINEB restore, LBFGS options, and the xtsci engine#403HaoZeke wants to merge 35 commits into
Conversation
An alignment reject left the dimer walk in place, so the band force jumped from 1e-3 to O(1) and NEB never recovered.
MYLBFGS converges on RMS = ||F||_2/sqrt(3N) and shrinks a step when the energy rises. The extra finite-difference H0 call is not in Nocedal 7.20. Read 2014 lbfgs_* keys from [Optimizer].
norm is Euclidean ||F||_2 of the free-atom force vector. OPTIM MYLBFGS RMS is ||F||_2/sqrt(3N) and is convergence_metric=rms.
lbfgs_curvature=reset|skip|damped (default reset). damped is Powell 1978 / Nocedal-Wright 18.3. skip is Li-Fukushima cautious. lbfgs_project_rigid removes the six null modes on isolated clusters.
Add optional L-BFGS pieces from the optimization literature that do not change the default ASE two-loop path: - lbfgs_secant=zhangxu: Zhang-Deng-Chen / Zhang-Xu modified secant (JOTA 1999/2001) folds the two function values into y - lbfgs_curvature=cautious: Li-Fukushima 2001 pair test s·y >= ε ||s||^2 ||g||^α - lbfgs_precon=exp|c1: Packwood-Kermode-Csanyi pair Laplacian (J. Chem. Phys. 2016) as the two-loop H0 metric - lbfgs_h0=ss_sy|adaptive: Barzilai-Borwein-2 or min(BB1, BB2) - lbfgs_accept=nonmonotone: Grippo window of the last five values - lbfgs_extra_updates: Al-Baali reuse of the newest pair Defaults stay reset / standard / none / energy / sy_yy.
Zhang-Xu inflates force calls on Lennard-Jones and Morse pair potentials. Packwood Exp is the condensed-phase metric; ASE falls back below about 100 atoms, and Exp on LJ38 costs calls.
lbfgs_precon=lindh is the Lindh 1995 stretch model k = mu exp(alpha (r_nn^2 - r^2)). lbfgs_precon=pair is the Mones 2018 positive-definite pair Hessian of the running potential (analytic LJ or Morse_Pt). Packwood exp/c1 stay available. Default remains none.
Mones pair drops V''<0. The LJ well sits past the inflection, so those neighbours vanish. pair_abs keeps |V''| and |V'/r|.
lbfgs_step=newton|rfo uses the analytic pair Hessian as the search direction, not as L-BFGS H0. rfo is Banerjee 1985 / Baker 1986. pair_full keeps the signed V'' and V'/r blocks.
opt_method=xtsci with xtsci_method=newton|rfo. The pair Hessian stays in eOn; the direction is xts_minimize_hess. Needs -Dwith_xtsci=true.
opt_method=xtsci and xtsci_method now exist on the L0 schema, catalog, YAML, JSON, pydantic, and SSOT defaults, not only on the INI reader.
opt_method=xtsci selects the xtsci-optimize backend. [Xtsci] method picks the solver: L-BFGS, BFGS, SR1/SR2, Newton, RFO, steepest, Adam, PSO, and the NLCG conjugacies. Unknown tokens are rejected.
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Published OCINEB restores the climbing image only on positive curvature. Extra restore after an alignment reject stays behind ci_mmf_restore_unhelpful until the Baker nebmmf_repro set is strictly better with it on.
|
Baker nebmmf_repro is the defaulting gate for extra OCINEB restore. Published MMF vs CI-NEB force calls (
Rematch (same published |
|
The Frontiers OCI-NEB article (Goswami, Gunde, Jónsson, Front. Chem. 14, 1807063, 2026, doi:10.3389/fchem.2026.1807063) restores the climbing image only on positive curvature. The extra restore after an alignment reject is an opt-in deviation from that protocol. |
Goswami, Gunde, Jonsson, Front. Chem. 14, 1807063 (2026) doi:10.3389/fchem.2026.1807063 Algorithm 1 restores the climbing image only on positive curvature. ci_mmf_restore_unhelpful=false is that setting.
Benchmark ResultsTip 4 benchmark(s) improved
Improvements
4 unchanged benchmark(s)
Details
Raw asv-spyglass output |
Energy and Grippo shrink are opt-in. The default two-loop step matches ASE and the SVN process_search Morse budget. PartialPivLU replaces LDLT so manylinux Eigen plus C++20 compiles.
After a downhill dimer step maxEnergyImage can hop. Band convergenceForce is then a neighbor, so restore rewound the saddle. Help and shouldReset use the image the dimer moved.
relaxMatter advances by step(). Mapping that to run(1) cold-starts every first-order xtsci method, so L-BFGS, BFGS, SR1/2, and the NLCG conjugacies all take the same Wolfe line search and the same force-call count. The first step now consumes max_iterations in one solve.
relaxMatter calls Optimizer::step. Mapping that to a full xts_minimize cold-started every first-order method. The adapter now owns a session: create once, step once per outer iteration, free in the destructor. Requires xtsci-optimize ABI minor 2.
The pair matrix stays in eOn. xtsci applies it as H0 or as a Newton/RFO step. Requires xtsci-optimize ABI minor 3.
Expose the xtsci L-BFGS session policy on Optimizer.Xtsci in Cap'n Proto, the generated catalog, INI, JSON, YAML, and Pydantic. Native [LBFGS] lbfgs_step / lbfgs_precon stay as they are.
The session reads Optimizer.Xtsci first. [LBFGS] lbfgs_step and lbfgs_precon remain a fallback so rematch INIs keep working. Native LBFGS::hessianStep is unchanged.
none / energy / nonmonotone through Cap'n Proto, INI, JSON, YAML, and Pydantic. Native [LBFGS] lbfgs_accept stays as the fallback.
Matter bills energy and forces together. The adapter uses xts_solver_step_fg / step_hess_fg and skips setPositions when x is unchanged. [Xtsci] accept drives xts_solver_set_accept so rematch can use nonmonotone instead of a mandatory backtrack.
Drive xts_solver_set_atom_maxmove, set_project_rigid, extra_updates, and cautious from the native [LBFGS] rematch knobs. Drop the Euclidean 3N cap that crushed isolated-cluster Newton steps.
The last accepted x is stored on the optimizer. Recreating the callback context every step() was dirtying Matter and billing a second force() at the same geometry.
The last fused callback already placed Matter at the accepted geometry. A second setPositions dirtied the PES cache.
getPositions after a PBC wrap does not match the accepted tensor, so the session never reused the last (f, g) and billed twice.
The first step was setPositions on the start point and paying a second force() after the host convergence check.
[Xtsci] method maps onto xtsci-optimize abi_minor 6. Dogleg defaults the host pair Hessian when precon is still none. FIRE takes the optimizer time step as the inertial dt.
Host Cartesian P for [Xtsci] precon and native L-BFGS H0. lindh_full is the Lindh 1995 stretch-bend-torsion model. swart screens that model into strong and weak pairs. fischer and schlegel are the standard QM estimated Hessians assembled as B^T k B. Native L-BFGS now calls pairhess::build so the token list cannot drift.
Opt-in HiGHS feasible-set step. Needs xtsci-optimize 0.2.0 built with --features highs. The setter fails cleanly without that feature.
Tokens match xts_manifold_t: euclidean, sphere, so3, stiefel, se3. The session setter is xts_solver_set_manifold (ABI minor 8).
OCINEB left a walked climbing image in place when the dimer Householder cut rejected the mode.
Pair 26 of OptBench LJ38: alignment 0.700 < 0.707, band force jumped to 8.47, and the NEB never recovered.
Restore the CI whenever MMF does not improve the band force.
Default stop stays Euclidean
||F||_2(convergence_metric=norm).OPTIM MYLBFGS RMS (
||F||_2 / sqrt(3 N)) usesconvergence_metric=rms.Do not mix those clocks.
Newton and RFO sit outside L-BFGS.
They live in xtsci-optimize.
opt_method=xtsciselects the engine.[Xtsci] methodpicks the solver:lbfgs,bfgs,sr1,sr2,newton,rfo,steepest,adam,pso, plus the NLCG tokens (polak_ribiere,fletcher_reeves,hestenes_stiefel,dai_yuan,conjugate_descent,hager_zhang,liu_storey,fr_pr).Unknown tokens throw.
Native L-BFGS keeps literature options.
Defaults stay
lbfgs_curvature=reset,lbfgs_secant=standard,lbfgs_precon=none,lbfgs_accept=energy.OptBench
Chill et al., J. Chem. Theory Comput. 10, 2014 (doi:10.1021/ct5008718).
Force-call means.
Default metric is
||F||_2.Minimization, 100 structures,
lbfgs_memory=100, no angle/distance reset (Chill INI).||F||_2 < 0.01lbfgs_step=newton,lbfgs_precon=pair)||F||_2 < 0.001lbfgs_precon=pair)convergence_metric=rmsuses a different stop (LJ38 mean 167, Morse mean 19).That row is not the default clock.
LJ38 double-ended, 5 images, 50 pairs, published OCINEB INI (
ci_mmf_after_rel=0, absoluteci_mmf_after=0.1):NEWNEB 5 500 0.001then BFGSTSPairs 13/32/38 still fail OCINEB (
termination_reason=2at 5007 calls).They also fail CI-NEB.
Chill's published OPTIM DNEB+EF mean of 131 uses their 2-image protocol, not this 5-image rematch.
What
NEBOcinebController: restore the climbing image when MMF does not help, including an alignment reject.lbfgs_step=newton|rfostays as the in-process pair-Hessian path.opt_method=xtsci+[Xtsci] methodthrough Cap'n Proto SSoT, YAML, JSON, pydantic, and SSOT defaults.Needs
-Dwith_xtsci=true.optimizer.md,minimization.md.Test plan
python3 -m pytest tests/test_params_ssot.py tests/test_config_metadata.py packages/eon-schema/tests(42 passed)eonclient --featureson a-Dwith_xtsci=truebuild lists the engine