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 AnomalousNernst {
pub alpha_ane: f64,
pub magnetization: Vector3<f64>,
}
impl Default for AnomalousNernst {
fn default() -> Self {
Self {
alpha_ane: 3.0e-6, magnetization: Vector3::new(0.0, 0.0, 1.0),
}
}
}
impl AnomalousNernst {
pub fn iron() -> Self {
Self {
alpha_ane: 2.0e-6,
magnetization: Vector3::new(0.0, 0.0, 1.0),
}
}
pub fn cofeb() -> Self {
Self {
alpha_ane: 4.0e-6,
magnetization: Vector3::new(0.0, 0.0, 1.0),
}
}
pub fn heusler() -> Self {
Self {
alpha_ane: 6.0e-6,
magnetization: Vector3::new(0.0, 0.0, 1.0),
}
}
#[inline]
pub fn electric_field(&self, grad_t: Vector3<f64>) -> Vector3<f64> {
let cross = grad_t.cross(&self.magnetization);
cross * self.alpha_ane
}
#[inline]
pub fn voltage(&self, grad_t: Vector3<f64>, width: f64) -> f64 {
let e_field = self.electric_field(grad_t);
e_field.magnitude() * width
}
pub fn power_factor(&self, resistivity: f64) -> f64 {
self.alpha_ane.powi(2) / resistivity
}
pub fn with_alpha_ane(mut self, alpha_ane: f64) -> Self {
self.alpha_ane = alpha_ane;
self
}
pub fn with_magnetization(mut self, magnetization: Vector3<f64>) -> Self {
self.magnetization = magnetization.normalize();
self
}
}
impl fmt::Display for AnomalousNernst {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"AnomalousNernst: α_ANE={:.1} μV/K, m=[{:.2},{:.2},{:.2}]",
self.alpha_ane * 1e6,
self.magnetization.x,
self.magnetization.y,
self.magnetization.z
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ane_perpendicularity() {
let ane = AnomalousNernst::default();
let grad_t = Vector3::new(1000.0, 0.0, 0.0);
let e_field = ane.electric_field(grad_t);
assert!(e_field.dot(&grad_t).abs() < 1e-20);
assert!(e_field.dot(&ane.magnetization).abs() < 1e-20);
}
#[test]
fn test_ane_zero_gradient() {
let ane = AnomalousNernst::default();
let grad_t = Vector3::new(0.0, 0.0, 0.0);
let e_field = ane.electric_field(grad_t);
assert!(e_field.magnitude() < 1e-30);
}
#[test]
fn test_ane_parallel_gradient_magnetization() {
let ane = AnomalousNernst::cofeb();
let grad_t = Vector3::new(0.0, 0.0, 1000.0);
let e_field = ane.electric_field(grad_t);
assert!(e_field.magnitude() < 1e-20);
}
#[test]
fn test_material_coefficients() {
let fe = AnomalousNernst::iron();
let cofeb = AnomalousNernst::cofeb();
let heusler = AnomalousNernst::heusler();
assert!(fe.alpha_ane < cofeb.alpha_ane);
assert!(cofeb.alpha_ane < heusler.alpha_ane);
}
}