Follow a minimum mode#
MinModeSession estimates a low-curvature direction by dimer rotation or Lanczos, then advances on the min-mode force. L-BFGS takes Accept::Step and rgmin’s NEB guards: the reflected force is not a potential gradient (Goswami, Gunde, and Jónsson, Front. Chem. (2026), https://doi.org/10.3389/fchem.2026.1807063, Eq. 9), an empty memory scales the step by 0.01, and a two-loop step that reaches the per-atom cap or faces away from the force drops its pairs. Lanczos stops when the relative change in the lowest Ritz value falls under rotation_tol, or when the residual does, and a repeat visit whose Rayleigh quotient still agrees with the retained curvature returns after one product (Olsen, Kroes, Henkelman, Arnaldsson, and Jónsson, J. Chem. Phys. 121, 9776 (2004), https://doi.org/10.1063/1.1809574; eOn quit_early). While the curvature along that mode is not negative the step is one full per-atom max_move along the mode (the perpendicular force is dropped). Once the curvature is negative the perpendicular force stays and the parallel part is reflected, and the L-BFGS pairs and the FIRE velocity survive a mode turn inside 45 degrees. A turn past that cone drops the memory and zeros the FIRE velocity. FIRE’s timestep stays 1. From rest the move is a quarter of the reflected force, because a zero power halves the step before the Euler update. When the per-atom cap shortens that step and the arrival is no longer negative, the move is replaced from the last negative point by 0.01 times the reflected force, the empty-memory scale of the L-BFGS guard. A capped step that stays negative is kept. L-BFGS is unchanged, and no C field was added. Lanczos uses the same translation. At the stock rotation_tol of 1e-4 the dimer also stops after one rotation once the rotational force is under 1; a tighter residual keeps iterating. FiniteDifference selects forward or central Hessian actions. A surface can supply analytic actions and excluded directions through PointSurface.
The reported force norm must satisfy the selected ForceGate, and the estimated curvature must be negative. If a translation reaches a stationary point, the session measures curvature at that accepted position before reporting convergence. This directional test does not certify the full Hessian index.
set_kappa selects the basin constraint. set_highs selects the optional feasible-step control. Call reset at a surface change and use set_force_gate to select the physical stopping norm. Hosts that require exactly one imaginary mode must perform their full index check.
Keep one session across a host search#
A host that climbs with its own optimizer keeps one session for the whole search. At each new centre it calls set_position (rgsaddle_minmode_set_position) with the gradient it already has, so the session does not evaluate the centre, then estimate_mode (rgsaddle_minmode_estimate). The previous mode seeds the next rotation. Dimer rotations also retain their Polak–Ribiere force and direction across a translation; a repeated estimate at exactly one centre restarts that rotational history. A failed surface evaluation leaves the retained rotation history unchanged, so a recoverable callback error does not silently turn the next estimate into a fresh rotation. set_mode (rgsaddle_minmode_set_mode) replaces the seed and clears both rotational history and the carried curvature. reset clears them at a surface-epoch boundary. All three need ABI minor 5. No new C field, so RGSADDLE_ABI_MINOR stays 21.
Lanczos through rgsaddle_minmode_estimate advances one Hessian action and keeps the Krylov basis until set_position, set_mode, or reset. Repeat the call until the host’s own test on the mode passes. The basis grows to the free dimension rather than stopping at krylov_dim. After k actions the returned mode lies in the k + 1 Lanczos vectors: the last is the residual direction the k-th action already produced. In the Lanczos basis an eigenvector’s components are the Lanczos polynomials at its eigenvalue (Parlett, The Symmetric Eigenvalue Problem, SIAM (1998), https://doi.org/10.1137/1.9781611971163, Ch. 7), and only the known k rows of the tridiagonal enter. The session evaluates them at an estimate of the lowest eigenvalue: the next Ritz value predicted with the last Lanczos diagonal, extrapolated with the two previous Ritz values by Aitken’s delta-squared (Aitken, Proc. R. Soc. Edinburgh 46, 289 (1927), https://doi.org/10.1017/S0370164600022070) when those fall with shrinking steps. At the Ritz value the same formula is the plain Ritz vector. No surface call is added, and the reported curvature is still the Ritz value of the k vectors, an upper bound on the lowest eigenvalue. Sella 0.1.1 (Hermes, Sargsyan, Najm, and Zádor, J. Chem. Theory Comput. 15, 6536 (2019), https://doi.org/10.1021/acs.jctc.9b00869) expands by the same residual at this stage, where it has no Hessian yet to precondition with, and tests the Ritz vector of the vectors it has applied the Hessian to. On lowest-eigenvector/lj38 that iteration and the plain Ritz vector both take about 16.8 actions per start. MinModeSession::estimate_mode and step still finish the residual test before a translation (Olsen, Kroes, Henkelman, Arnaldsson, and Jónsson, J. Chem. Phys. 121, 9776 (2004), https://doi.org/10.1063/1.1809574). A dimer estimate is the full rotation.
These MinModeConfig fields set the cost of an estimate and of the translation:
Field |
Effect |
Default |
|---|---|---|
|
|
|
|
The dimer stops rotating when an iteration’s optimal angle falls under this many radians; 0 turns the test off |
five degrees |
|
Rotational-force residual. At 1e-4 and any looser value the dimer also stops after one rotation once that force is under 1. A tighter value keeps iterating. Lanczos uses it as the Ritz residual and, with no host relative tolerance, as the relative change of the lowest Ritz value |
1e-4 |
|
Rotation cap for one dimer estimate |
20 |
|
Largest per-atom translation. A curvature that is not negative takes one step of this length along the mode. The L-BFGS pairs and the FIRE velocity are kept while the mode turns by at most 45 degrees, and dropped past that cone |
0.2 |
From C, difference and rotation_angle_tol sit in rgsaddle_minmode_config_t and are read only when the config’s version.minor is 5 or more. A zeroed C struct leaves rotation_angle_tol at 0, so the angle test stays off. The C++ helper minmode_config does that, and sets rotation_tol to 1e-3, which is loose enough for the torque window. The Python point stencil does not take rotation_angle_tol; it uses the Rust default of five degrees. rotation_tol on that stencil defaults to 1e-4.