Skip to main content
← OpenMECP Documentation

OptimizationState

Struct OptimizationState 

Source
pub struct OptimizationState {
Show 14 fields pub lambdas: Vec<f64>, pub lambda_de: Option<f64>, pub constraint_violations: DVector<f64>, pub geom_history: VecDeque<DVector<f64>>, pub grad_history: VecDeque<DVector<f64>>, pub f_vec_history: VecDeque<DVector<f64>>, pub hess_history: VecDeque<DMatrix<f64>>, pub energy_history: VecDeque<f64>, pub displacement_history: VecDeque<f64>, pub lambda_history: VecDeque<Vec<f64>>, pub lambda_de_history: VecDeque<Option<f64>>, pub max_history: usize, pub stuck_count: usize, pub step_size_multiplier: f64,
}
Expand description

Tracks optimization state and history for adaptive optimization algorithms.

This struct maintains the history of geometries, gradients, Hessians, and energies required by advanced optimization methods like GDIIS and GEDIIS. It also stores Lagrange multipliers for constraint handling.

§Unit Conventions

  • Geometry history (geom_history): Coordinates in Angstrom (A)
  • Gradient history (grad_history): Gradients in Hartree/Angstrom (Ha/A)
  • Energy history (energy_history): Energy differences in Hartree (Ha)
  • Displacement history (displacement_history): Displacements in Angstrom (A)

These units match the internal storage conventions used throughout OpenMECP:

  • Coordinates are stored in Angstrom for compatibility with QM input files
  • Gradients are converted from native QM output (Ha/Bohr) to Ha/A at the QM interface boundary

§Capacity and History Management

  • Maximum history: configurable via max_history parameter (default: 5)
  • Automatically removes oldest entries when capacity is exceeded
  • Maintains rolling window of recent optimization data

§Requirements

Validates: Requirements 7.1, 7.2

Fields§

§lambdas: Vec<f64>

Lagrange multipliers for geometric constraints

§lambda_de: Option<f64>

Lagrange multiplier for the energy difference constraint (FixDE mode)

§constraint_violations: DVector<f64>

Current constraint violations for extended gradient

§geom_history: VecDeque<DVector<f64>>

History of molecular geometries in Angstrom (A) for DIIS methods.

Each entry is a flattened coordinate vector [x1, y1, z1, x2, y2, z2, …] representing the molecular geometry at a previous optimization step. Units: Angstrom (A) - matching the internal coordinate storage convention.

Validates: Requirement 7.1

§grad_history: VecDeque<DVector<f64>>

History of MECP g-vectors (perpendicular component) in Ha/A for DIIS.

This stores only the pure gradient component (g_vec), NOT the mixed combined gradient. Units: Hartree/Angstrom (Ha/A).

§f_vec_history: VecDeque<DVector<f64>>

History of f-vectors (energy difference drive term) in Hartree (Ha).

Used alongside grad_history in GDIIS to reconstruct the combined step direction. Units: Hartree (Ha).

§hess_history: VecDeque<DMatrix<f64>>

History of approximate inverse Hessian matrices in Ų/Ha for BFGS updates.

Each entry is the inverse Hessian approximation at a previous step. Units: Ų/Ha - produces Angstrom steps when multiplied by Ha/A gradients.

§energy_history: VecDeque<f64>

History of energy differences |E1 - E2| in Hartree (Ha) for GEDIIS.

Used to weight interpolation coefficients toward geometries closer to the crossing seam (smaller energy difference).

§displacement_history: VecDeque<f64>

History of displacement norms in Angstrom (A) for stuck detection.

Tracks the magnitude of geometry changes between consecutive steps.

§lambda_history: VecDeque<Vec<f64>>

History of Lagrange multipliers for GDIIS extrapolation

§lambda_de_history: VecDeque<Option<f64>>

History of energy difference Lagrange multiplier for GDIIS extrapolation

§max_history: usize

Maximum number of history entries to store

§stuck_count: usize

Counter for consecutive stuck iterations (zero displacement)

§step_size_multiplier: f64

Adaptive step size multiplier (starts at 1.0, reduces when stuck)

Implementations§

Source§

impl OptimizationState

Source

pub fn new(max_history: usize) -> Self

Creates a new empty OptimizationState.

Initializes all history containers with capacity for max_history entries and sets the maximum history size to max_history iterations.

§Arguments
  • max_history - Maximum number of history entries to store (default: 5)
§Examples
use omecp::optimizer::OptimizationState;

let opt_state = OptimizationState::new(5);
assert_eq!(opt_state.max_history, 5);
assert!(opt_state.geom_history.is_empty());
Source

pub fn update_stuck_detection(&mut self, displacement_norm: f64)

Updates stuck counter and step size multiplier based on displacement

Source

pub fn add_to_history( &mut self, geom: DVector<f64>, grad: DVector<f64>, f_vec: DVector<f64>, hess: DMatrix<f64>, energy: f64, lambdas: Vec<f64>, lambda_de: Option<f64>, use_smart_history: bool, )

Adds optimization data to the history deques.

Supports two history management strategies:

  1. Traditional FIFO (default, smart_history=false): Removes oldest point
  2. Smart Management (smart_history=true): Removes worst point based on scoring
§Traditional FIFO (Default)

Simple first-in-first-out: removes the oldest entry when history is full.

  • Proven and reliable
  • Works well for most cases
  • Recommended for production use
§Smart History Management (Experimental)

Removes the WORST point based on intelligent scoring:

  • Energy difference from degeneracy (weight: 10.0)
  • Gradient norm (weight: 5.0)
  • Geometric redundancy (weight: 20.0)
  • Age penalty (weight: 0.01)
  • MECP gap penalty (weight: 15.0)

May provide 20-30% faster convergence in some cases, but not universally effective.

§Arguments
  • geom - Current geometry coordinates
  • grad - Current MECP gradient
  • hess - Current Hessian matrix estimate
  • energy - Current energy difference (E1 - E2)
  • smart_history - Enable smart history management (default: false)
§Examples
use nalgebra::DVector;
let mut opt_state = OptimizationState::new(5);

let coords = DVector::from_vec(vec![0.0, 0.0, 0.0]);
let grad = DVector::from_vec(vec![0.1, 0.2, 0.3]);
let energy_diff = 0.001;

// Traditional FIFO (default)
// opt_state.add_to_history(coords, grad, hessian, energy_diff, false);

// Smart history (experimental)
// opt_state.add_to_history(coords, grad, hessian, energy_diff, true);
Source

fn add_to_history_fifo( &mut self, geom: DVector<f64>, grad: DVector<f64>, f_vec: DVector<f64>, hess: DMatrix<f64>, energy: f64, lambdas: Vec<f64>, lambda_de: Option<f64>, )

Source

fn add_to_history_smart( &mut self, geom: DVector<f64>, grad: DVector<f64>, f_vec: DVector<f64>, hess: DMatrix<f64>, energy: f64, lambdas: Vec<f64>, lambda_de: Option<f64>, )

Source

pub fn has_enough_history(&self) -> bool

Checks if there is sufficient history for GDIIS/GEDIIS optimization.

Returns true if at least 3 iterations of history have been accumulated, which is the minimum required for effective DIIS interpolation.

§Returns

Returns true if history has ≥ 3 entries, false otherwise.

§Examples
use omecp::optimizer::OptimizationState;
let opt_state = OptimizationState::new();
assert!(!opt_state.has_enough_history()); // Empty state

Trait Implementations§

Source§

impl Clone for OptimizationState

Source§

fn clone(&self) -> OptimizationState

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for OptimizationState

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for OptimizationState

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl From<&OptimizationState> for SerializableOptimizationState

Source§

fn from(opt_state: &OptimizationState) -> Self

Converts to this type from the input type.
Source§

impl From<SerializableOptimizationState> for OptimizationState

Source§

fn from(ser_opt_state: SerializableOptimizationState) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.