Getting started#
A host builds a band, steps until the projected force is under
force_tol, and never lets this crate own the loop.
1. Depend on the published crate#
[dependencies]
rgsaddle = "0.1"
rgmin = "0.2"
ndarray = "0.17"
2. Implement BandSurface#
One eval fills energies and gradients for every image. The double-well test surface is the shortest honest example:
impl BandSurface for DoubleWell {
fn eval(
&self,
positions: ArrayView2<f64>,
energies: &mut Array1<f64>,
gradients: &mut Array2<f64>,
) -> Result<(), SaddleError> {
// V = (x² − 1)² + 2y² + 2z²
Ok(())
}
}
3. Step#
let config = BandConfig {
force_tol: 1e-3,
max_move: 0.1,
..BandConfig::default()
};
let mut session = BandSession::new(config, initial)?;
loop {
let report = session.step(&surface)?;
if report.status == BandStatus::Converged {
break;
}
}
Default stepper is FIRE. The projected band force is not conservative; rgmin’s session L-BFGS currently applies an energy-decrease acceptance that refuses every NEB step. FIRE matches eOn’s velocity NEB stepper.
4. Reset when the surface changes#
BandSession::reset is the model-update boundary. Quasi-Newton
history taken on one surface epoch must not survive onto the next.
See tests/double_well.rs for the numbers the crate actually
converges.