Minimization¶
Local minimization relaxes a structure to the nearest potential energy minimum using one of several optimization algorithms.
To run a minimization, set job to minimization in the [Main] section:
[Main]
job = minimization
[Optimizer]
opt_method = lbfgs
converged_force = 0.01
max_iterations = 1000
Or programmatically via rgpycrumbs:
from rgpycrumbs.eon.helpers import write_eon_config
config = {
"Main": {"job": "minimization"},
"Optimizer": {"opt_method": "lbfgs", "converged_force": 0.01},
}
write_eon_config(config, Path("config.ini"))
The optimizer settings control convergence. See Optimizer for the full list of available optimizers and their parameters.
Tip
Enable [Debug] write_movies = true (and optionally write_deprecated_outs = true) so rgpycrumbs eon plt-min can build energy profiles, 2D landscapes, and
convergence panels. For two endpoints, use separate landscape plots (one
--job-dir / --label each). See LJ cluster minimization (built-in potential) and
Real systems for documentation.
Optimizer selection¶
Optimizer |
Best for |
Key parameter |
|---|---|---|
LBFGS |
Most minimizations, fast convergence near minima |
|
FIRE |
Systems far from equilibrium, tolerant of bad initial guesses |
|
CG (default) |
Large systems where LBFGS memory is a concern |
|
QuickMin (token |
Simple dynamics-based relaxation |
|
SD |
Debugging, guaranteed descent direction |
|
The default opt_method is cg.
The QuickMin token is qm.
quickmin is not a token.
Convergence¶
The minimization converges when converged_force is met. The number is
always in eV/A; convergence_metric chooses which force scalar is
compared. The default is eOn’s historical norm, not OPTIM’s RMS.
norm (default): Euclidean
||F||_2of the free-atom force vector (sqrt(sum_i F_i^2)). This is not an RMS: it grows with system size. Chill / OPTIM||F|| < 1e-2is a different scalar.rms:
||F||_2 / sqrt(3 N_free), matching OPTIM MYLBFGS (SQRT(SUM(VNEW**2)/(3*NATOMS))). Opt-in for an OPTIM-comparable stop; it is not the eOn default.max_atom: maximum
||F||on any single free atommax_component: maximum Cartesian component of any free-atom force
L-BFGS memory updates are controlled by lbfgs_curvature (default
reset, the ASE wipe). skip drops a pair when s·y < 0.2 sᵀB0s.
damped is Powell’s 1978 replacement ŷ = θ y + (1-θ) B0 s with
θ = 0.8 sᵀB0s / (sᵀB0s − sᵀy) when sᵀy < 0.2 sᵀB0s (Nocedal
and Wright, Numerical Optimization, §18.3). cautious is the
Li–Fukushima (2001) rule: keep the pair only if
s·y ≥ ε ||s||² ||g||^α. Isolated clusters can set
lbfgs_project_rigid = true to remove the six rigid-body modes
from the force and the step (those modes are Hessian-null; they
should not enter the limited-memory pairs).
Further L-BFGS knobs, all optional and off by default:
lbfgs_secant = zhangxureplacesyby the Zhang–Deng–Chen / Zhang–Xu modified secant, which folds the two function values into the pair (JOTA 1999 / 2001). No extra potential call. On Lennard-Jones and Morse pair potentials this pair inflates the force-call count; leave it atstandardthere.lbfgs_preconselects the two-loopH0metric.noneisH0 I.exp/c1is the Packwood–Kermode–Csanyi pair Laplacian (J. Chem. Phys. 2016, doi:10.1063/1.4947024). ASE falls back below about 100 atoms;expon LJ38 costs force calls.lindhis the Lindh stretch model Hessian (Chem. Phys. Lett. 1995, doi:10.1016/0009-2614(95)00646-L):k = μ exp(α (r_nn² - r²))along each pair,α = lbfgs_precon_A.pairis the Mones–Ortner–Csanyi positive-definite pair Hessian (Sci. Rep. 2018, doi:10.1038/s41598-018-32105-x) of the running potential: analyticV''andV'/rof LJ (4ε[(σ/r)¹²-(σ/r)⁶],ε=σ=1) or Morse_Pt (D=0.7102,α=1.6047,r0=2.897), with negative pieces dropped. That is the right metric when the energy is itself a pair potential (Morse bulk).pair_absuses|V''|and|V'/r|so attractive LJ neighbours still contribute; on LJ38 it does not beat an unpreconditioned two-loop.lindh_fulladds Lindh bend and torsion blocks (B^T k B).fischeris the Fischer-Almlof 1992 model Hessian (doi:10.1021/j100203a036).schlegelis the Schlegel 1984 estimated Hessian (doi:10.1007/BF00554788).swartis the Swart-Bickelhaupt strong/weak screen of Lindh (doi:10.1002/qua.21049). All four are host Cartesian matrices;[Xtsci] precontakes the same tokens.
Newton and RFO are not L-BFGS. They live in
rgmin (formerly xtsci-optimize) as
Method::Newton. Build eOn against rgmin (-Dwith_rgmin=enabled, see
Optimizer) and select them from the INI:
[Optimizer]
opt_method = xtsci
converged_force = 0.01
[Xtsci]
method = newton
[LBFGS]
lbfgs_precon = pair
[Xtsci] highs = true asks HiGHS for the step (Newton QP on the
host pair matrix, or two-loop plus boxes). Build rgmin
with --features capi,highs.
method = rfo is Banerjee RFO. The pair Hessian is still built in eOn
(lbfgs_precon) and handed to Rust through rgmin_minimize_hess. The
engine also runs the other rgmin methods (lbfgs, bfgs,
sr1, sr2, steepest, adam, pso, quickmin, and the NLCG
conjugacies).
To keep opt_method = lbfgs, fire, cg, sd or qm and only move
the step into rgmin, set [Optimizer] opt_backend = rgmin; the method
map is in Optimizer.
lbfgs_h0 = sy_yy(Nocedal–Wright 7.20),ss_sy(Barzilai–Borwein 2), oradaptive(the smaller of the two when both are positive).lbfgs_accept = none(default) takes the two-loop step, matching ASE and historical eOn.energyrefuses a rise (OPTIM-style shrink; each trial is a potential call).nonmonotoneis the Grippo–Lampariello–Lucidi window of the last five energies (SIAM J. Numer. Anal. 1986).lbfgs_extra_updates = preuses the newest pairpextra times in the two-loop recursion (Al-Baali, 2000/2014).
Refinement¶
For paths far from the minimum, a two-stage optimization can be faster: start
with QuickMin or FIRE and switch to LBFGS after the forces
drop below a threshold.
The client reads [Refine] only when that section is present.
[Refine] is absent from eon/config.yaml, so a file the server loads exits before the client runs.
[Optimizer]
opt_method = fire
[Refine]
opt_method = lbfgs
threshold = 0.5
This runs FIRE until the max force drops below 0.5 eV/A, then switches to LBFGS for final convergence.
Output¶
The minimization writes:
min.con: the minimized structureresults.dat: energy, force calls, convergence status
With write_movies = true (in [Debug]), minimization.con is written as a
concatenated structure movie (one frame per iteration). Each frame stores
structured JSON metadata in the second CON header line via readcon-core, including energy,
frame_index, step_size, and convergence.
Set write_deprecated_outs = true in [Debug] to also emit the legacy
minimization.dat sidecar during the compatibility window.
Configuration¶
The minimization job reads [Optimizer].
Its opt_method defaults to cg.
An optional [Refine] block is client-only: the client reads it when the section is present, and the server exits on the unknown section before the client runs.
- pydantic model eon.schema.OptimizerConfig[source]
- Fields:
opt_method (Literal['box', 'cg', 'qm', 'lbfgs', 'fire', 'sd', 'xtsci'])opt_backend (Literal['eon', 'rgmin'])convergence_metric (Literal['norm', 'rms', 'max_atom', 'max_component'])converged_force (float)max_move (float)time_step (float)max_iterations (int)
- field opt_method: Literal['box', 'cg', 'qm', 'lbfgs', 'fire', 'sd', 'xtsci'] = 'cg'
- Options:
box: Optimizes the atom positions and box using quickmincg: Conjugate gradientqm: Quickminlbfgs: Limited Memory Broyden-Fletcher-Goldfarb-Shanno QuasiNewton optimizerfire: Fast inertial relaxation enginesd: Steepest descentxtsci: rgmin engine (formerly xtsci-optimize). Pick the solver with[Xtsci] method. Needs a build that links rgmin (-Dwith_rgmin).
The optimization method to use.
- field opt_backend: Literal['eon', 'rgmin'] = 'eon'
- Options:
eon: eOn’s own optimizers (default)rgmin: rgmin sessions: lbfgs is rgmin L-BFGS, fire is FIRE, cg is Polak-Ribiere CG, sd is steepest descent, qm is quick-min. Needs a build that links rgmin (-Dwith_rgmin). Applies to every objective whose gradient is the derivative of its energy (relaxations, the per-image IDPP path, BGSD); the nudged elastic band, the collective IDPP band and min-mode translation steps stay on eOn’s optimizers.[LBFGS] lbfgs_memoryand the[Xtsci]session keys still apply.
Who runs the lbfgs, fire, cg, sd and qm optimizers.
- field convergence_metric: Literal['norm', 'rms', 'max_atom', 'max_component'] = 'norm'
- Options:
norm: Euclidean||F||_2of the free-atom force vector (default)rms:||F||_2 / sqrt(3 N_free), OPTIM MYLBFGS RMS. Opt-in.max_atom: The maximum force on any non-frozen atommax_component: The maximum force on any non-frozen degree of freedom
The metric to use to determine when an optimization is complete.
- field converged_force: float = 0.01
When the convergence_metric is smaller than this value (eV/A), the structure is considered minimized.
- field max_move: float = 0.2
Maximum distance that an atom may be moved in a single optimization step (Angstroms).
- field time_step: float = 1.0
The dynamical timestep for the quickmin algorithm (fs).
- field max_iterations: int = 1000
The maximum number of optimization iterations that will be performed.
- pydantic model eon.schema.RefineConfig[source]¶
- Fields:
refine_opt_method (Literal['none', 'cg', 'lbfgs', 'fire', 'box', 'qm'])refine_threshold (float)
- field refine_opt_method: Literal['none', 'cg', 'lbfgs', 'fire', 'box', 'qm'] = 'none'¶
- Options:
none: No refinement optimizationcg: Conjugate gradientlbfgs: Limited Memory Broyden-Fletcher-Goldfarb-Shanno QuasiNewton optimizerfire: Fast inertial relaxation enginebox: Optimizes the atom positions and box using quickminqm: Quickmin
The optimization method to use for refinement.