Skip to main content
← OpenMECP Documentation

check_convergence

Function check_convergence 

Source
pub fn check_convergence(
    e1: f64,
    e2: f64,
    x_old: &DVector<f64>,
    x_new: &DVector<f64>,
    grad: &DVector<f64>,
    config: &Config,
) -> ConvergenceStatus
Expand 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 Hartree
  • e2 - Energy of state 2 in Hartree
  • x_old - Previous geometry coordinates in Angstrom
  • x_new - Current geometry coordinates in Angstrom
  • grad - Current MECP gradient in Ha/A
  • config - 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
  • 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());