types: mat: hack in a way to implement a 3-variant material
This commit is contained in:
@@ -168,6 +168,13 @@ impl<L> Enum<(), L> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D, L> Enum<D, L> {
|
||||
/// use with care. long term, this probably shouldn't stay public.
|
||||
pub fn from_components(discr: D, list: L) -> Self {
|
||||
Self(discr, list)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait EnumRequirements {
|
||||
type NumVariants: Peano;
|
||||
fn decode_discr(&self) -> Discr<Self::NumVariants>;
|
||||
|
@@ -128,6 +128,10 @@ pub trait IntoList {
|
||||
}
|
||||
|
||||
pub type List<Args> = <Args as IntoList>::List;
|
||||
pub type List1<E0> = Node<E0, Null>;
|
||||
pub type List2<E0, E1> = Node<E0, List1<E1>>;
|
||||
pub type List3<E0, E1, E2> = Node<E0, List2<E1, E2>>;
|
||||
pub type List4<E0, E1, E2, E3> = Node<E0, List3<E1, E2, E3>>;
|
||||
|
||||
impl<H> Meta for Node<H, Null> {
|
||||
type Length = P1;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
use crate::compound::enumerated::{Discr, DiscriminantCodable, Enum, EnumRequirements, InternallyDiscriminated, VariantHandler};
|
||||
use crate::compound::list::{IntoList as _, List};
|
||||
use crate::compound::peano::{Peano, P2};
|
||||
use crate::compound::list::{Indexable, IntoList, List, List2, List3};
|
||||
use crate::compound::peano::{Peano, P0, P1, P2, P3};
|
||||
use crate::real::Real;
|
||||
use crate::vec::Vec3;
|
||||
|
||||
@@ -27,40 +27,31 @@ pub trait Material<R: Real>: Sized {
|
||||
}
|
||||
}
|
||||
|
||||
/// a material which can take on 1 of N types.
|
||||
/// it's assumed that the first type in the material list is capable of storing the discriminant
|
||||
/// (i.e. that it implements DiscriminantCodable).
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
#[cfg_attr(feature = "fmt", derive(Debug))]
|
||||
#[derive(Copy, Clone, Default, PartialEq)]
|
||||
pub struct DiscrMat2<M0, M1>(InternallyDiscriminated<(M0, M1)>);
|
||||
#[derive(Clone, Default, PartialEq)]
|
||||
pub struct DiscrMat<Mats>(Enum<(), Mats>);
|
||||
pub type DiscrMat2<M0, M1> = DiscrMat<List2<M0, M1>>;
|
||||
pub type DiscrMat3<M0, M1, M2> = DiscrMat<List3<M0, M1, M2>>;
|
||||
|
||||
struct D0<T>(T);
|
||||
struct D1<T>(T);
|
||||
|
||||
impl<M0, M1> DiscrMat2<M0, M1> {
|
||||
fn new_from_fields(m0: M0, m1: M1) -> Self {
|
||||
Self(Enum::internally_discriminated((m0, m1)))
|
||||
impl<Mats> DiscrMat<Mats> {
|
||||
fn new_from_fields(mats: Mats) -> Self {
|
||||
Self(Enum::from_components((), mats))
|
||||
}
|
||||
}
|
||||
|
||||
impl<M0: DiscriminantCodable<P2>, M1: Default> DiscrMat2<M0, M1> {
|
||||
pub fn new0(m: M0) -> Self {
|
||||
D0(m).into()
|
||||
}
|
||||
pub fn new1(m: M1) -> Self {
|
||||
D1(m).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<M0, M1: Default> From<D0<M0>> for DiscrMat2<M0, M1> {
|
||||
fn from(m0: D0<M0>) -> Self {
|
||||
let m0 = m0.0;
|
||||
Self::new_from_fields(m0, Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<M0: DiscriminantCodable<P2>, M1> From<D1<M1>> for DiscrMat2<M0, M1> {
|
||||
fn from(m1: D1<M1>) -> Self {
|
||||
let m1 = m1.0;
|
||||
Self::new_from_fields(M0::encode_discr(Discr::new(1)), m1)
|
||||
impl<Mats: Default> DiscrMat<Mats> {
|
||||
fn new<P: Peano>(m: Mats::Element) -> Self
|
||||
where
|
||||
Mats: Indexable<P>,
|
||||
Enum<(), Mats>: EnumRequirements,
|
||||
{
|
||||
let mut me = Self::default();
|
||||
me.0.set::<P>(m);
|
||||
me
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +72,24 @@ impl<R: Real, P: Peano, T: Material<R>> VariantHandler<P, T, Vec3<R>> for MoveBV
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Real, M0: DiscriminantCodable<P2> + Material<R> + Copy, M1: Material<R> + Copy> Material<R> for DiscrMat2<M0, M1>
|
||||
impl<R: Real, M0, M1> Material<R> for DiscrMat2<M0, M1>
|
||||
where
|
||||
M0: DiscriminantCodable<P2> + Material<R> + Copy,
|
||||
M1: Material<R> + Copy,
|
||||
{
|
||||
fn conductivity(&self) -> Vec3<R> {
|
||||
self.0.dispatch(ConductivityDispatcher)
|
||||
}
|
||||
fn move_b_vec(&self, m: Vec3<R>, target_b: Vec3<R>) -> Vec3<R> {
|
||||
self.0.dispatch(MoveBVecDispatcher { m, target_b })
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Real, M0, M1, M2> Material<R> for DiscrMat3<M0, M1, M2>
|
||||
where
|
||||
M0: DiscriminantCodable<P3> + Material<R> + Copy,
|
||||
M1: Material<R> + Copy,
|
||||
M2: Material<R> + Copy,
|
||||
{
|
||||
fn conductivity(&self) -> Vec3<R> {
|
||||
self.0.dispatch(ConductivityDispatcher)
|
||||
@@ -97,12 +105,12 @@ pub type IsoConductorOr<R, M1> = DiscrMat2<IsomorphicConductor<R>, M1>;
|
||||
// IsomorphicConductor itself
|
||||
impl<R: Real> From<Ferroxcube3R1MH> for IsoConductorOr<R, Ferroxcube3R1MH> {
|
||||
fn from(mat: Ferroxcube3R1MH) -> Self {
|
||||
IsoConductorOr::new1(mat)
|
||||
IsoConductorOr::new::<P1>(mat)
|
||||
}
|
||||
}
|
||||
impl<R: Real> From<IsomorphicConductor<R>> for IsoConductorOr<R, Ferroxcube3R1MH> {
|
||||
fn from(mat: IsomorphicConductor<R>) -> Self {
|
||||
IsoConductorOr::new0(mat)
|
||||
IsoConductorOr::new::<P0>(mat)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,10 +132,10 @@ mod test {
|
||||
fn iso_conductor_or_aniso() {
|
||||
type I = IsoConductorOr<R32, AnisomorphicConductor<R32>>;
|
||||
|
||||
let c = I::new0(IsomorphicConductor::new(22f32.cast()));
|
||||
let c = I::new::<P0>(IsomorphicConductor::new(22f32.cast()));
|
||||
assert!(c.conductivity() == Vec3::uniform(22.0).cast());
|
||||
|
||||
let c = I::new1(AnisomorphicConductor::new(
|
||||
let c = I::new::<P1>(AnisomorphicConductor::new(
|
||||
Vec3::new(2.0, 3.0, 4.0).cast()
|
||||
));
|
||||
|
||||
|
Reference in New Issue
Block a user