use std::fmt;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::vector3::Vector3;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SpinSeebeck {
pub l_s: f64,
pub g_th: f64,
pub polarization: Vector3<f64>,
}
impl Default for SpinSeebeck {
fn default() -> Self {
Self {
l_s: 1.0e-6,
g_th: 1.0e6,
polarization: Vector3::new(0.0, 0.0, 1.0),
}
}
}
impl SpinSeebeck {
pub fn yig_pt() -> Self {
Self {
l_s: 1.0e-6,
g_th: 5.0e5,
polarization: Vector3::new(0.0, 0.0, 1.0),
}
}
#[inline]
pub fn spin_current(&self, grad_t: Vector3<f64>) -> Vector3<f64> {
let magnitude = self.l_s * grad_t.magnitude();
self.polarization * magnitude
}
pub fn linear_gradient(
&self,
delta_t: f64,
thickness: f64,
direction: Vector3<f64>,
) -> Vector3<f64> {
let grad_t_magnitude = delta_t / thickness;
let grad_t = direction.normalize() * grad_t_magnitude;
self.spin_current(grad_t)
}
#[inline]
pub fn interface_current(&self, delta_t_interface: f64) -> Vector3<f64> {
let magnitude = self.l_s * self.g_th * delta_t_interface;
self.polarization * magnitude
}
pub fn with_l_s(mut self, l_s: f64) -> Self {
self.l_s = l_s;
self
}
pub fn with_g_th(mut self, g_th: f64) -> Self {
self.g_th = g_th;
self
}
pub fn with_polarization(mut self, polarization: Vector3<f64>) -> Self {
self.polarization = polarization.normalize();
self
}
}
impl fmt::Display for SpinSeebeck {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"SpinSeebeck(L_s={:.2e} J/(K·m²), G_th={:.2e} W/(K·m²))",
self.l_s, self.g_th
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sse_zero_gradient() {
let sse = SpinSeebeck::default();
let grad_t = Vector3::new(0.0, 0.0, 0.0);
let js = sse.spin_current(grad_t);
assert!(js.magnitude() < 1e-50);
}
#[test]
fn test_sse_polarization() {
let sse = SpinSeebeck {
polarization: Vector3::new(1.0, 0.0, 0.0),
..Default::default()
};
let grad_t = Vector3::new(0.0, 100.0, 0.0);
let js = sse.spin_current(grad_t);
assert!(js.y.abs() < 1e-50);
assert!(js.z.abs() < 1e-50);
assert!(js.x.abs() > 0.0);
}
#[test]
fn test_linear_gradient() {
let sse = SpinSeebeck::default();
let delta_t = 10.0; let thickness = 1.0e-6; let direction = Vector3::new(0.0, 1.0, 0.0);
let js = sse.linear_gradient(delta_t, thickness, direction);
assert!(js.magnitude() > 0.0);
}
#[test]
fn test_yig_pt_system() {
let sse = SpinSeebeck::yig_pt();
assert!(sse.l_s > 0.0);
assert!(sse.g_th > 0.0);
}
}