use crate::constants::GAMMA;
use crate::vector3::Vector3;
#[derive(Debug, Clone)]
pub struct SpinMechanicalCoupling {
pub magnetization: Vector3<f64>,
pub omega: Vector3<f64>,
pub moment_of_inertia: f64,
pub alpha: f64,
pub ms: f64,
pub volume: f64,
}
impl SpinMechanicalCoupling {
pub fn new(
magnetization: Vector3<f64>,
moment_of_inertia: f64,
alpha: f64,
ms: f64,
volume: f64,
) -> Self {
Self {
magnetization: magnetization.normalize(),
omega: Vector3::new(0.0, 0.0, 0.0),
moment_of_inertia,
alpha,
ms,
volume,
}
}
pub fn evolve(&mut self, h_ext: Vector3<f64>, dt: f64) {
let h_barnett = self.omega * (-1.0 / GAMMA);
let h_total = h_ext + h_barnett;
let m_cross_h = self.magnetization.cross(&h_total);
let damping = self.magnetization.cross(&m_cross_h) * self.alpha;
let dm_dt = (m_cross_h + damping) * (-GAMMA / (1.0 + self.alpha * self.alpha));
self.magnetization = (self.magnetization + dm_dt * dt).normalize();
let mechanical_torque = dm_dt * (-self.volume * self.ms);
let alpha_mech = mechanical_torque * (1.0 / self.moment_of_inertia);
self.omega = self.omega + alpha_mech * dt;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_coupled_system_creation() {
let system =
SpinMechanicalCoupling::new(Vector3::new(1.0, 0.0, 0.0), 1.0e-15, 0.01, 1.0e6, 1.0e-18);
assert!((system.magnetization.magnitude() - 1.0).abs() < 1e-10);
}
#[test]
fn test_angular_momentum_exchange() {
let mut system =
SpinMechanicalCoupling::new(Vector3::new(1.0, 0.0, 0.0), 1.0e-15, 0.01, 1.0e6, 1.0e-18);
let h_ext = Vector3::new(0.0, 0.0, 1.0e5);
assert!(system.omega.magnitude() < 1e-20);
for _ in 0..100 {
system.evolve(h_ext, 1.0e-13);
}
assert!(system.omega.magnitude() > 0.0);
}
}