castep_param_io/param/electro_min/
elec_eigenvalue_tol.rs

1use castep_param_derive::KeywordDisplayStruct;
2use derive_builder::Builder;
3use serde::{Deserialize, Serialize};
4
5use crate::param::{EnergyUnit, Nbands};
6
7use super::ElecEnergyTol;
8
9#[derive(
10    Debug, Clone, Copy, Deserialize, Serialize, PartialEq, PartialOrd, Builder, KeywordDisplayStruct,
11)]
12#[builder(setter(into), default)]
13#[keyword_display(field = "ELEC_EIGENVALUE_TOL", display_format = "{:20.15e} {}", from=f64, default_value=1e-6)]
14/// This keyword controls the tolerance for accepting convergence of a single
15/// eigenvalue during density mixing minimization.
16/// The difference between maximum and minimum eigenvalues over ELEC_CONVERGENCE_WIN
17/// iterations must be less than this value.
18/// # Default
19/// The default value is the lower of 1x10-6 eV and ELEC_ENERGY_TOL*NATOMS/NBANDS, where NATOMS is the total number of atoms in the unit cell.
20pub struct ElecEigenvalueTol {
21    pub tol: f64,
22    #[keyword_display(is_option = true)]
23    pub unit: Option<EnergyUnit>,
24}
25
26impl ElecEigenvalueTol {
27    fn default_value(elec_energy_tol: ElecEnergyTol, natoms: usize, nbands: Nbands) -> Self {
28        let tol = elec_energy_tol.tol * natoms as f64 / nbands.value() as f64;
29        Self {
30            tol,
31            unit: elec_energy_tol.unit,
32        }
33    }
34}
35
36#[cfg(test)]
37mod test {
38    use crate::param::KeywordDisplay;
39
40    use super::ElecEigenvalueTol;
41
42    #[test]
43    fn elec_eigenvalue_tol() {
44        let p = ElecEigenvalueTol::default();
45        println!("{}", p.output())
46    }
47}