Explanation#

Band and minimum-mode#

The band and the minimum-mode search assemble a force and ask rgmin::Solver for one step. Hosts interleave trust regions, drift budgets, acquisition, or a hybrid MMF between steps. run is a loop over step. The shared reflection, the point presets, and the chain are in one stencil.

Index-1 Newton#

Index1Session searches an index-1 saddle on a Cartesian energy Hessian. The displacement is Baker’s restricted-step partitioned RFO: a 2 by 2 rational-function problem maximizes the lowest mode, a second rational-function problem minimizes the complement, and the Besalu-Bofill scaling is solved so the Cartesian step lies inside the trust sphere. Powell or Bofill updates the Hessian from the gradient difference. The trust radius shrinks when that model predicts the energy change poorly and grows when a step on the sphere agrees with it.

nichols_step is the separate i-PI level shift. A host that already holds a spectrum can call it. rgsaddle_prfo_step is the restricted-step partition. rgsaddle_hessian_powell and rgsaddle_hessian_bofill update the Hessian.

eOn branch structure#

Tangents, springs, projections, and the climbing-image force follow eOn’s NEBTangent / NEBSpringForce / NEBForceProjection with the same branches. The climbing image arms when the convergence force falls under factor * baseline or under an absolute trigger.

Periodicity#

Positions stay unwrapped Cartesian. Cell wraps per-atom differences for the band mechanics through fractional coordinates (rows are lattice vectors; a zero row is a non-periodic axis). Neighbor lists, when a surface wants them, are vesin’s job.

The solid-state reference cell#

The solid-state band is checked against an answer computed without a band. The case is the Bain path from bcc to fcc of LJ (epsilon 1 eV, sigma 1 A), switched to zero over [2.0, 2.2] A. Both atoms of the body-centred tetragonal cell diag(a, a, c) sit on inversion centres, so the atomic force is zero at any cell. The relaxed energy at fixed c/a is then a one-dimensional minimum over the volume. validation/bain_lj_reference.py scans it on a 2.5e-4 grid. bcc and fcc are minima, and the saddle sits at c/a 1.09331985, 0.0590356373 eV/atom above bcc. Over the six cell strains that saddle has one negative eigenvalue.

The saddle is not stable against atomic motion. The phonon at k = (1/2, 0, 1/2) of the conventional cell has the eigenvalue -51.5 eV/A2there, and it shuffles alternate planes. The two-atom cell carries no wave vector but k = 0, so in that cell the scan’s saddle is the band’s saddle. A supercell does carry the shuffle. A 5x5x4 supercell (200 atoms) has k = (2/5, 0, 1/2), with eigenvalue -38.4 eV/A2. Its band, run with the settings of the two-atom test and a tolerance of 1e-3, shows the instability:

iteration

largest force component

climbing image

150

4.6e-3

c/a 1.0933, the scan saddle

200

3.19

cells shear, a and b part

947

8.9e-4 (converged)

c/a 1.0523, 0.0266 eV/atom above bcc

At convergence the cells carry a shear of 0.233 A, a and b differ by 0.065 A, and the atoms sit up to 0.031 (fractional) off their sites. Rounding seeds the shuffle. The band then follows it to a lower path, as an NEB should, and the scan is no reference for that cell. tests/c/solid_bain_lj.c therefore checks the two-atom cell. There the climbing image reaches c/a 1.09331984 and 0.0590356373 eV/atom. Run with arguments 5 5 4 7 1e-3 5000 0.1 0.5, it reproduces the supercell run and fails its tetragonal-path check by design.

Evaluations per step#

A warm band step costs n_images - 2 image evaluations. The endpoint energies are evaluated once. The session keeps its last evaluation, keyed on the interior positions, so a step that starts where the previous one ended is assembled from it: a host resync through set_positions (rows equal up to the minimum image keep the session’s own copy), an optimizer restart, or a solver that dropped its own cache costs nothing. BandReport.surface_rows counts what the surface evaluated. The climbing image is chosen on the energies of the evaluation it climbs on, so the step that arms it already climbs.

Steppers#

FIRE is the default, as in eOn’s velocity NEB stepper. The projected NEB force is not the gradient of the summed image energy the oracle reports, so L-BFGS runs under rgmin’s Accept::Step: the two-loop direction, capped per atom, with one evaluation and no energy test.

Minimum mode#

The dimer rotation is the modified Newton step of Heyden, Bell, and Keil (2005) and Kastner and Sherwood (2008): one trial gradient fixes the Fourier model of the curvature in the rotation plane, the optimal angle is closed form, and the gradient at the rotated dimer is the exact (on a quadratic) combination of the two measured ones, so each rotation costs one evaluation. Rotation planes are Polak-Ribiere conjugate, and the force and direction of a finished rotation are kept for the next centre. A repeated estimate at the same centre, set_mode, and reset start that sequence again. A failed surface callback leaves the retained pair unchanged. Lanczos stops when the Ritz residual beta_j |s_j| meets rotation_tol. Both use the forward difference against the centre gradient by default; validation/fd_curvature.py gives its error, dr |T| / 2 + 2 eps / dr, and the dr that minimizes it for a given gradient noise. FiniteDifference::Central trades one more gradient per action for an O(dr^2) error.

The translation steps on the inverted force, whose value (the true energy) is not its potential, as the band’s pseudo-energy is not the potential of the projected force. Both sessions accept only methods that step on the force alone (FIRE, L-BFGS under Accept::Step, Barzilai-Borwein) and refuse line-searched ones. Between steps the solver’s cached force, inverted along the previous mode, is dropped (rgmin forget_evaluation) and the centre answers the re-read without a surface call. A turn inside MODE_RESET_ANGLE (45 degrees, the Householder cone of Goswami, Gunde, and Jónsson, Front. Chem. (2026), https://doi.org/10.3389/fchem.2026.1807063; validation/mode_reset.py) keeps the L-BFGS pairs and the FIRE velocity. Past that cone the memory is dropped and the FIRE velocity returns to zero. FIRE keeps timestep 1 (Bitzek, Koskinen, Gähler, Moseler, and Gumbsch, Phys. Rev. Lett. 97, 170201 (2006), https://doi.org/10.1103/PhysRevLett.97.170201). From rest a zero power halves the step, so the move is F / 4. 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 F. A capped step that stays negative is kept. A non-negative curvature takes one full per-atom max_move along the mode. At the stock rotational residual the dimer stops on eOn’s torque window after one rotation; rotation_angle_tol defaults to five degrees and zero disables that angle test.