pub fn check_convergence(
e1: f64,
e2: f64,
x_old: &DVector<f64>,
x_new: &DVector<f64>,
grad: &DVector<f64>,
config: &Config,
) -> ConvergenceStatusExpand description
Checks convergence criteria for MECP optimization.
Evaluates all five convergence criteria and returns a ConvergenceStatus
indicating which criteria have been satisfied. The optimization converges
only when all criteria are met simultaneously.
§Units
- Coordinates (
x_old,x_new): Angstrom (A) - Gradient (
grad): Hartree/A (Ha/a₀) - Displacement thresholds: Angstrom (A)
- Gradient thresholds: Hartree/A (Ha/a₀)
This function computes displacements in Angstrom (since coordinates are stored in Angstrom) and compares against Angstrom thresholds. Gradients are in Ha/A (converted from native QM output) and compared against Ha/A thresholds.
§Arguments
e1- Energy of state 1 in Hartreee2- Energy of state 2 in Hartreex_old- Previous geometry coordinates in Angstromx_new- Current geometry coordinates in Angstromgrad- Current MECP gradient in Ha/Aconfig- Configuration with convergence thresholds
§Returns
Returns a ConvergenceStatus struct indicating the status of each criterion.
§Convergence Thresholds
§Default (Standard Precision)
- Energy difference: 0.000050 Hartree (~0.00136 eV)
- RMS gradient: 0.0005 Ha/A
- Max gradient: 0.0007 Ha/A
- RMS displacement: 0.0025 A
- Max displacement: 0.004 A
§Recommended for High-Precision MECP
- Energy difference: 0.000010 Hartree (~0.00027 eV)
- RMS gradient: 0.0001 Ha/A
- Max gradient: 0.0005 Ha/A
- RMS displacement: 0.001 A
- Max displacement: 0.002 A
§Implementation Notes
All five criteria must be satisfied simultaneously (AND logic). Tight convergence is especially important for MECP calculations where small energy differences can significantly impact results.
§Requirements
Validates: Requirements 5.3, 5.4
§Examples
use omecp::optimizer::check_convergence;
use nalgebra::DVector;
let e1 = -100.0;
let e2 = -100.0001;
let x_old = DVector::from_vec(vec![0.0, 0.0, 0.0]); // Angstrom
let x_new = DVector::from_vec(vec![0.001, 0.001, 0.001]); // Angstrom
let grad = DVector::from_vec(vec![0.0001, 0.0001, 0.0001]); // Ha/A
// let status = check_convergence(e1, e2, &x_old, &x_new, &grad, &config);
// assert!(status.is_converged());