#[derive(Clone, Copy, Debug, PartialEq)]
pub enum BgnModel {
None,
Slotboom,
Klaassen,
Harmon1994,
}
fn delta_eg_ev_impl(v1_ev: f64, n_ref_cm3: f64, n_total_cm3: f64) -> f64 {
if n_total_cm3 <= 0.0 {
return 0.0;
}
let ln_r = (n_total_cm3 / n_ref_cm3).ln();
v1_ev * (ln_r + (ln_r * ln_r + 0.5_f64).sqrt())
}
pub fn slotboom_delta_eg_ev(n_total_cm3: f64) -> f64 {
delta_eg_ev_impl(9.0e-3, 1.0e17, n_total_cm3)
}
pub fn klaassen_delta_eg_ev(n_total_cm3: f64) -> f64 {
delta_eg_ev_impl(6.92e-3, 1.3e17, n_total_cm3)
}
pub fn harmon1994_gaas_delta_eg_ev(n_total_cm3: f64, is_n_type: bool) -> f64 {
if n_total_cm3 < 1e14 {
return 0.0;
}
let a = if is_n_type { 3.23e-8_f64 } else { 2.55e-8_f64 };
a * n_total_cm3.powf(1.0 / 3.0)
}
pub fn ni_eff_squared_cm6(ni_cm3: f64, delta_eg_ev: f64, vt_v: f64) -> f64 {
ni_cm3 * ni_cm3 * (delta_eg_ev / vt_v).exp()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn slotboom_at_n_ref_is_positive() {
let result = slotboom_delta_eg_ev(1e17);
assert!(result > 0.0, "Expected ΔEg > 0 at N=N_ref, got {result}");
}
#[test]
fn bernoulli_like_continuity() {
let eps = 1e-6_f64;
let d1 = slotboom_delta_eg_ev(1e17 * (1.0 - eps));
let d2 = slotboom_delta_eg_ev(1e17 * (1.0 + eps));
let diff_ev = (d1 - d2).abs();
assert!(
diff_ev < 1e-6,
"Expected ΔEg smooth at N_ref (eps=1e-6): |d1-d2|={diff_ev:.3e} eV"
);
}
}