use std::num::NonZeroUsize;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use stem_material::prelude::*;
use crate::magnet::Magnet;
#[doc = ""]
#[cfg_attr(
feature = "doc-images",
doc = "![Example of a magnet assembly with three tangentially repeated magnets][drawing_magnet_assembly]"
)]
#[cfg_attr(
feature = "doc-images",
embed_doc_image::embed_doc_image(
"drawing_magnet_assembly",
"docs/img/drawing_magnet_assembly.svg"
)
)]
#[cfg_attr(
not(feature = "doc-images"),
doc = "**Doc images not enabled**. Compile docs with
`cargo doc --features 'doc-images'` and Rust version >= 1.54."
)]
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
pub struct MagnetAssembly {
magnet: Box<dyn Magnet>,
number_axial: usize,
number_tangential: usize,
}
impl MagnetAssembly {
pub fn new<M: Magnet>(
magnet: M,
number_axial: NonZeroUsize,
number_tangential: NonZeroUsize,
) -> MagnetAssembly {
return MagnetAssembly {
magnet: Box::new(magnet),
number_axial: number_axial.into(),
number_tangential: number_tangential.into(),
};
}
pub fn from_boxed(
magnet: Box<dyn Magnet>,
number_axial: NonZeroUsize,
number_tangential: NonZeroUsize,
) -> MagnetAssembly {
return MagnetAssembly {
magnet,
number_axial: number_axial.into(),
number_tangential: number_tangential.into(),
};
}
pub fn magnet(&self) -> &dyn Magnet {
return &*self.magnet;
}
pub fn number_axial(&self) -> usize {
return self.number_axial;
}
pub fn number_tangential(&self) -> usize {
return self.number_tangential;
}
pub fn number_magnets(&self) -> usize {
return self.number_axial * self.number_tangential;
}
pub fn width(&self) -> Length {
return self.magnet().width() * self.number_tangential as f64;
}
pub fn length(&self) -> Length {
return self.magnet().length() * self.number_axial as f64;
}
pub fn volume(&self) -> Volume {
return self.magnet().volume() * self.number_magnets() as f64;
}
pub fn mass(&self) -> Mass {
return self.magnet().mass() * self.number_magnets() as f64;
}
pub fn magnetomotive_force(&self, conditions: &[DynQuantity<f64>]) -> ElectricCurrent {
return self.magnet().magnetomotive_force(conditions) * self.number_magnets() as f64;
}
}
impl Clone for MagnetAssembly {
fn clone(&self) -> Self {
Self {
magnet: dyn_clone::clone_box(&*self.magnet),
number_axial: self.number_axial.clone(),
number_tangential: self.number_tangential.clone(),
}
}
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for MagnetAssembly {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
struct MagnetAssemblyNonZero {
magnet: Box<dyn Magnet>,
number_axial: NonZeroUsize,
number_tangential: NonZeroUsize,
}
let a = MagnetAssemblyNonZero::deserialize(deserializer)?;
return Ok(MagnetAssembly {
magnet: a.magnet,
number_axial: a.number_axial.into(),
number_tangential: a.number_tangential.into(),
});
}
}