use crate::constants::GAMMA;
use crate::vector3::Vector3;
#[derive(Debug, Clone)]
pub struct HybridSystem {
pub magnetization: Vector3<f64>,
pub cavity_amplitude: f64,
pub cavity_phase: f64,
pub coupling_g: f64,
pub omega_cavity: f64,
pub omega_magnon: f64,
pub kappa: f64,
pub gamma_m: f64,
pub h_bias: Vector3<f64>,
pub gamma: f64,
pub alpha: f64,
}
impl HybridSystem {
pub fn new(
h_bias: Vector3<f64>,
coupling_g: f64,
omega_cavity: f64,
kappa: f64,
alpha: f64,
) -> Self {
let mu0 = 1.256637e-6; let h_bias_magnitude = h_bias.magnitude();
let omega_magnon = GAMMA * mu0 * h_bias_magnitude;
Self {
magnetization: Vector3::new(0.0, 0.0, 1.0), cavity_amplitude: 0.0,
cavity_phase: 0.0,
coupling_g,
omega_cavity,
omega_magnon,
kappa,
gamma_m: alpha * omega_magnon, h_bias,
gamma: GAMMA,
alpha,
}
}
pub fn yig_cavity() -> Self {
let h_bias = Vector3::new(0.0, 0.0, 8.0e4); let omega_cavity = 2.0 * std::f64::consts::PI * 10.0e9; let coupling_g = 2.0 * std::f64::consts::PI * 100.0e6; let kappa = 2.0 * std::f64::consts::PI * 1.0e6; let alpha = 0.0001;
Self::new(h_bias, coupling_g, omega_cavity, kappa, alpha)
}
pub fn evolve(&mut self, h_drive: Vector3<f64>, dt: f64) {
let cavity_drive = h_drive.x;
let m_plus = self.magnetization.x + self.magnetization.y; let magnon_to_cavity = self.coupling_g * m_plus;
let da_dt =
-self.kappa * 0.5 * self.cavity_amplitude + magnon_to_cavity + cavity_drive * 1.0e9;
self.cavity_amplitude += da_dt * dt;
let dphi_dt = self.omega_cavity;
self.cavity_phase += dphi_dt * dt;
let h_cavity_feedback = Vector3::new(
self.cavity_amplitude * (self.cavity_phase).cos() * self.coupling_g / self.gamma,
self.cavity_amplitude * (self.cavity_phase).sin() * self.coupling_g / self.gamma,
0.0,
);
let h_total = self.h_bias + h_cavity_feedback + h_drive;
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) * (-self.gamma / (1.0 + self.alpha * self.alpha));
self.magnetization = (self.magnetization + dm_dt * dt).normalize();
}
pub fn detuning(&self) -> f64 {
self.omega_cavity - self.omega_magnon
}
pub fn cooperativity(&self) -> f64 {
4.0 * self.coupling_g.powi(2) / (self.kappa * self.gamma_m)
}
pub fn rabi_splitting(&self) -> f64 {
2.0 * self.coupling_g
}
pub fn is_strong_coupling(&self) -> bool {
self.cooperativity() > 1.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_hybrid_creation() {
let hybrid = HybridSystem::yig_cavity();
assert!(hybrid.coupling_g > 0.0);
assert!(hybrid.omega_cavity > 0.0);
assert!(hybrid.omega_magnon > 0.0);
}
#[test]
fn test_yig_cavity_strong_coupling() {
let hybrid = HybridSystem::yig_cavity();
assert!(hybrid.is_strong_coupling());
assert!(hybrid.cooperativity() > 10.0); }
#[test]
fn test_detuning_calculation() {
let mut hybrid = HybridSystem::yig_cavity();
hybrid.h_bias = hybrid.h_bias * 1.1; hybrid.omega_magnon = GAMMA * hybrid.h_bias.magnitude();
let detuning = hybrid.detuning();
assert!(detuning.abs() > 0.0);
}
#[test]
fn test_rabi_splitting() {
let hybrid = HybridSystem::yig_cavity();
let splitting = hybrid.rabi_splitting();
assert!((splitting - 2.0 * hybrid.coupling_g).abs() < 1e-6);
}
#[test]
fn test_evolution() {
let mut hybrid = HybridSystem::yig_cavity();
let h_drive = Vector3::new(100.0, 0.0, 0.0);
let m_initial = hybrid.magnetization;
for _ in 0..100 {
hybrid.evolve(h_drive, 1.0e-12); }
assert!((hybrid.magnetization - m_initial).magnitude() > 1e-6);
assert!((hybrid.magnetization.magnitude() - 1.0).abs() < 1e-6);
}
#[test]
fn test_cavity_amplitude_growth() {
let mut hybrid = HybridSystem::yig_cavity();
let h_drive = Vector3::new(1.0e4, 0.0, 0.0);
for _ in 0..1000 {
hybrid.evolve(h_drive, 1.0e-12);
}
assert!(hybrid.cavity_amplitude.abs() > 1e-6);
}
#[test]
fn test_magnon_frequency() {
let h_bias = Vector3::new(0.0, 0.0, 8.0e4); let mu0 = 1.256637e-6;
let omega_expected = GAMMA * mu0 * 8.0e4;
let hybrid = HybridSystem::new(h_bias, 1.0e8, 1.0e10, 1.0e6, 0.0001);
assert!((hybrid.omega_magnon - omega_expected).abs() < 1e6);
}
}