cheq/solver/options.rs
1//! This module defines configuration options for the charge equilibration solver.
2//!
3//! It provides the `SolverOptions` struct, which allows users to customize the convergence
4//! criteria, iteration limits, and screening parameters for the QEq algorithm. These options
5//! control the trade-off between computational cost and solution accuracy.
6
7/// Specifies the type of basis functions used for Coulomb integrals.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
9pub enum BasisType {
10 /// Gaussian-Type Orbitals (GTO).
11 ///
12 /// Uses Gaussian approximations for Slater orbitals. This allows for fast analytical
13 /// integration but introduces a small approximation error.
14 Gto,
15
16 /// Slater-Type Orbitals (STO).
17 ///
18 /// Uses exact Slater orbitals. This is more accurate but computationally more expensive
19 /// as it requires evaluating complex analytical expansions.
20 #[default]
21 Sto,
22}
23
24/// Strategy for damping charge updates during SCF iterations.
25#[derive(Debug, Clone, Copy, PartialEq)]
26pub enum DampingStrategy {
27 /// No damping is applied (equivalent to damping = 1.0).
28 ///
29 /// Fastest convergence for simple, well-behaved systems, but prone to oscillation
30 /// or divergence in complex cases (e.g., LiH, large systems).
31 None,
32
33 /// A fixed damping factor (0.0 < d <= 1.0).
34 ///
35 /// A constant mixing rate. Lower values (e.g., 0.1) are more stable but slower.
36 /// Higher values (e.g., 0.8) are faster but risk instability.
37 Fixed(f64),
38
39 /// Automatically adjusts damping based on convergence behavior.
40 ///
41 /// Starts with an initial value. If the error increases (divergence), it reduces damping (brakes).
42 /// If the error decreases significantly (convergence), it increases damping (accelerates).
43 /// This is the recommended strategy for general use.
44 Auto { initial: f64 },
45}
46
47/// Configuration parameters for the charge equilibration solver.
48///
49/// This struct encapsulates the numerical settings that control the iterative solution process
50/// in the QEq algorithm. Users can adjust these parameters to balance convergence speed with
51/// accuracy for different molecular systems and computational requirements.
52#[derive(Debug, Clone, Copy, PartialEq)]
53pub struct SolverOptions {
54 /// The convergence tolerance for charge equilibration.
55 ///
56 /// The solver iterates until the root-mean-square change in atomic charges between
57 /// successive iterations falls below this threshold. Smaller values yield more accurate
58 /// results but require more iterations.
59 pub tolerance: f64,
60
61 /// The maximum number of iterations allowed.
62 ///
63 /// If convergence is not achieved within this limit, the solver will terminate and return
64 /// the current best estimate. This prevents infinite loops in difficult cases.
65 pub max_iterations: u32,
66
67 /// The screening parameter scale factor.
68 ///
69 /// This multiplier adjusts the orbital screening strength in Coulomb integral calculations.
70 /// It corresponds to the `λ` parameter in the Rappe & Goddard paper.
71 /// The original paper suggests a value of ~0.4913, often rounded to 0.5.
72 pub lambda_scale: f64,
73
74 /// Whether to update hydrogen hardness each iteration (nonlinear SCF term).
75 ///
76 /// When disabled, hydrogen uses a fixed hardness (lossy simplification). Enabled by default.
77 pub hydrogen_scf: bool,
78
79 /// The type of basis functions to use for Coulomb integrals.
80 ///
81 /// Defaults to `BasisType::Sto` (Slater-Type Orbitals) for maximum accuracy.
82 pub basis_type: BasisType,
83
84 /// The damping strategy for the SCF iteration.
85 ///
86 /// Controls how charge updates are mixed between iterations to ensure convergence.
87 pub damping: DampingStrategy,
88}
89
90impl Default for SolverOptions {
91 fn default() -> Self {
92 Self {
93 tolerance: 1.0e-6,
94 max_iterations: 2000,
95 lambda_scale: 0.5,
96 hydrogen_scf: true,
97 basis_type: BasisType::default(),
98 damping: DampingStrategy::Auto { initial: 0.4 },
99 }
100 }
101}