fdtd-coremem/crates/cross/src/mat/conductor.rs

106 lines
2.8 KiB
Rust

use crate::compound::enumerated::{Discr, DiscriminantCodable};
use crate::compound::peano::Peano;
use crate::mat::Material;
use crate::real::Real;
use crate::vec::Vec3;
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "fmt", derive(Debug))]
#[derive(Copy, Clone, Default, PartialEq)]
pub struct Conductor<T>(T);
pub type AnisomorphicConductor<R> = Conductor<Vec3<R>>;
pub type IsomorphicConductor<R> = Conductor<(R,)>;
impl<R> IsomorphicConductor<R> {
pub fn new(c: R) -> Self {
Self((c,))
}
}
impl<V: Clone> IsomorphicConductor<V> {
pub fn iso_conductivity(&self) -> V {
self.0.0.clone()
}
}
impl<R> AnisomorphicConductor<R> {
pub fn new(c: Vec3<R>) -> Self {
Self(c)
}
}
impl<R: Real> Into<AnisomorphicConductor<R>> for IsomorphicConductor<R> {
fn into(self) -> AnisomorphicConductor<R> {
AnisomorphicConductor::new(Vec3::uniform(self.iso_conductivity()))
}
}
impl<R: Real> Material<R> for AnisomorphicConductor<R> {
fn conductivity(&self) -> Vec3<R> {
self.0
}
}
impl<R: Real> Material<R> for IsomorphicConductor<R> {
fn conductivity(&self) -> Vec3<R> {
Vec3::uniform(self.iso_conductivity())
}
}
impl<R: Real, P: Peano> DiscriminantCodable<P> for AnisomorphicConductor<R> {
fn decode_discr(&self) -> Discr<P> {
let cond = self.conductivity().x();
let d = if cond < R::zero() {
(-cond.to_f32()) as u32
} else {
0
};
Discr::new(d)
}
fn encode_discr(d: Discr<P>) -> Self {
Self::new(Vec3::new_x(
R::from_primitive(-(d.value() as i32))
))
}
}
impl<R: Real, P: Peano> DiscriminantCodable<P> for IsomorphicConductor<R> {
fn decode_discr(&self) -> Discr<P> {
let cond = self.iso_conductivity();
let d = if cond < R::zero() {
(-cond.to_f32()) as u32
} else {
0
};
Discr::new(d)
}
fn encode_discr(d: Discr<P>) -> Self {
Self::new(R::from_primitive(-(d.value() as i32)))
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::compound::peano::P6;
#[test]
fn iso_conductor_discr() {
type T = IsomorphicConductor<f32>;
let c = <T as DiscriminantCodable<P6>>::encode_discr(Discr::new(5));
assert_eq!(DiscriminantCodable::<P6>::decode_discr(&c).value(), 5);
let c = <T as DiscriminantCodable<P6>>::encode_discr(Discr::new(0));
assert_eq!(DiscriminantCodable::<P6>::decode_discr(&c).value(), 0);
let c = T::new(5.0);
assert_eq!(DiscriminantCodable::<P6>::decode_discr(&c).value(), 0);
let c = T::new(0.0);
assert_eq!(DiscriminantCodable::<P6>::decode_discr(&c).value(), 0);
}
}