use crate::constants::{GAMMA, HBAR};
use crate::vector3::Vector3;
#[derive(Debug, Clone)]
pub struct BarnettMagnetization {
pub gamma: f64,
pub moment_density: f64,
pub ms: f64,
}
impl BarnettMagnetization {
pub fn new(ms: f64, moment_density: f64) -> Self {
Self {
gamma: GAMMA,
moment_density,
ms,
}
}
pub fn iron() -> Self {
Self::new(
1.7e6, 8.5e28, )
}
pub fn permalloy() -> Self {
Self::new(8.0e5, 5.8e28)
}
pub fn magnetization_from_rotation(&self, omega: Vector3<f64>) -> Vector3<f64> {
omega * (HBAR * self.moment_density / 2.0)
}
pub fn fractional_magnetization(&self, omega: Vector3<f64>) -> f64 {
let m_b = self.magnetization_from_rotation(omega);
m_b.magnitude() / self.ms
}
pub fn saturation_rotation_rate(&self) -> f64 {
(2.0 * self.ms) / (HBAR * self.moment_density)
}
pub fn barnett_field(&self, omega: Vector3<f64>) -> Vector3<f64> {
omega * (-1.0 / self.gamma)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_barnett_creation() {
let barnett = BarnettMagnetization::iron();
assert!(barnett.ms > 0.0);
}
#[test]
fn test_magnetization_from_rotation() {
let barnett = BarnettMagnetization::permalloy();
let omega = Vector3::new(0.0, 0.0, 1000.0);
let m = barnett.magnetization_from_rotation(omega);
assert!(m.magnitude() > 0.0);
assert!(m.z > 0.0); }
#[test]
fn test_zero_rotation() {
let barnett = BarnettMagnetization::iron();
let omega = Vector3::new(0.0, 0.0, 0.0);
let m = barnett.magnetization_from_rotation(omega);
assert!(m.magnitude() < 1e-50);
}
#[test]
fn test_fractional_magnetization_small() {
let barnett = BarnettMagnetization::iron();
let omega = Vector3::new(0.0, 0.0, 100.0);
let frac = barnett.fractional_magnetization(omega);
assert!(frac < 1.0);
assert!(frac > 0.0);
}
}