lindhard/ion/stopping/
mix.rs1use super::lindhard_scharff::LindhardScharff;
11use super::oen_robinson::OenRobinson;
12use super::{ElectronicStopping, Ion, StoppingError, ValidityRange};
13
14#[derive(Debug, Clone, Default)]
16pub struct EquipartitionMix {
17 ls: LindhardScharff,
18 or: OenRobinson,
19}
20
21impl EquipartitionMix {
22 pub fn new() -> Self {
24 Self::default()
25 }
26
27 pub fn nonlocal_stopping(
29 &self,
30 ion: &Ion,
31 target_z: u8,
32 energy_ev: f64,
33 ) -> Result<f64, StoppingError> {
34 Ok(0.5 * self.ls.stopping(ion, target_z, energy_ev)?)
35 }
36
37 pub fn nonlocal_sqrt_energy_coefficient(&self, ion: &Ion, target_z: u8) -> Option<f64> {
40 Some(0.5 * self.ls.sqrt_energy_coefficient(ion, target_z)?)
41 }
42
43 pub fn local_loss(
45 &self,
46 ion: &Ion,
47 target_z: u8,
48 energy_ev: f64,
49 r_min_m: f64,
50 ) -> Result<f64, StoppingError> {
51 Ok(0.5 * self.or.local_loss(ion, target_z, energy_ev, r_min_m)?)
52 }
53}
54
55impl ElectronicStopping for EquipartitionMix {
56 fn name(&self) -> &'static str {
57 "equipartition-ls-or"
58 }
59
60 fn stopping(&self, ion: &Ion, target_z: u8, energy_ev: f64) -> Result<f64, StoppingError> {
61 Ok(self.nonlocal_stopping(ion, target_z, energy_ev)?
63 + 0.5 * self.or.stopping(ion, target_z, energy_ev)?)
64 }
65
66 fn validity(&self, ion: &Ion) -> ValidityRange {
67 self.ls.validity(ion)
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn average_equals_ls() {
77 let ion = Ion::new(31).unwrap();
78 let a = EquipartitionMix::new().stopping(&ion, 14, 5e4).unwrap();
79 let b = LindhardScharff::new().stopping(&ion, 14, 5e4).unwrap();
80 assert!((a / b - 1.0).abs() < 1e-14);
81 }
82
83 #[test]
84 fn local_loss_rejects_bad_closest_approach() {
85 let ion = Ion::proton();
86 let m = EquipartitionMix::new();
87 for bad in [-1e-10, f64::NAN, f64::INFINITY] {
88 assert!(matches!(
89 m.local_loss(&ion, 14, 1e4, bad),
90 Err(StoppingError::InvalidParameter { .. })
91 ));
92 }
93 assert!(m.local_loss(&ion, 14, 1e4, 0.0).unwrap() > 0.0);
94 }
95}