use std::sync::Arc;
use compare_variables::compare_variables;
use std::f64::consts::PI;
use stem_material::prelude::*;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "serde")]
use serde_mosaic::serialize_arc_link;
#[cfg(feature = "serde")]
use stem_material::prelude::serialize_quantity;
use super::wire::Wire;
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
pub struct RoundWire {
#[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arc_link"))]
conductor_material: Arc<Material>,
#[cfg_attr(feature = "serde", serde(serialize_with = "serialize_quantity"))]
outer_diameter: Length,
#[cfg_attr(feature = "serde", serde(serialize_with = "serialize_quantity"))]
inner_diameter: Length,
#[cfg_attr(feature = "serde", serde(serialize_with = "serialize_quantity"))]
insulation_thickness: Length,
}
impl RoundWire {
pub fn new(
conductor_material: Arc<Material>,
outer_diameter: Length,
inner_diameter: Length,
insulation_thickness: Length,
) -> Result<Self, crate::error::Error> {
return RoundWire {
conductor_material,
outer_diameter,
inner_diameter,
insulation_thickness,
}
.check();
}
fn check(self) -> Result<Self, crate::error::Error> {
let zero_length = Length::new::<meter>(0.0);
compare_variables!(self.inner_diameter < self.outer_diameter)?;
compare_variables!(zero_length <= self.inner_diameter)?;
compare_variables!(zero_length <= self.insulation_thickness)?;
return Ok(self);
}
pub fn insulation_diameter(&self) -> Length {
return self.outer_diameter + 2.0 * self.insulation_thickness;
}
pub fn outer_diameter(&self) -> Length {
return self.outer_diameter;
}
pub fn inner_diameter(&self) -> Length {
return self.inner_diameter;
}
pub fn insulation_thickness(&self) -> Length {
return self.insulation_thickness;
}
pub fn conductor_area(&self) -> Area {
use stem_material::uom::typenum::P2;
return (self.outer_diameter.powi(P2::new()) - self.inner_diameter.powi(P2::new())) * PI
/ 4.0;
}
pub fn overall_area(&self) -> Area {
use stem_material::uom::typenum::P2;
return (self.outer_diameter + 2.0 * self.insulation_thickness).powi(P2::new()) * PI / 4.0;
}
}
impl Default for RoundWire {
fn default() -> Self {
Self {
conductor_material: Default::default(),
outer_diameter: Length::new::<meter>(1.0),
inner_diameter: Default::default(),
insulation_thickness: Default::default(),
}
}
}
#[cfg_attr(feature = "serde", typetag::serde)]
impl Wire for RoundWire {
fn material(&self) -> &Material {
return &*self.conductor_material;
}
fn material_arc(&self) -> Arc<Material> {
return self.conductor_material.clone();
}
fn effective_conductor_area(&self, _zone_area: Area, _turns: usize) -> Area {
return self.conductor_area();
}
fn effective_overall_area(&self, _zone_area: Area, _turns: usize) -> Area {
return self.overall_area();
}
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for RoundWire {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde_mosaic::deserialize_arc_link;
use stem_material::prelude::deserialize_quantity;
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct RoundWireSerde {
#[serde(deserialize_with = "deserialize_arc_link")]
conductor_material: Arc<Material>,
#[serde(deserialize_with = "deserialize_quantity")]
outer_diameter: Length,
#[serde(deserialize_with = "deserialize_quantity")]
inner_diameter: Length,
#[serde(deserialize_with = "deserialize_quantity")]
insulation_thickness: Length,
}
let wire_serde = RoundWireSerde::deserialize(deserializer)?;
return RoundWire {
conductor_material: wire_serde.conductor_material,
outer_diameter: wire_serde.outer_diameter,
inner_diameter: wire_serde.inner_diameter,
insulation_thickness: wire_serde.insulation_thickness,
}
.check()
.map_err(serde::de::Error::custom);
}
}