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 {
|
pub trait EnumRequirements {
|
||||||
type NumVariants: Peano;
|
type NumVariants: Peano;
|
||||||
fn decode_discr(&self) -> Discr<Self::NumVariants>;
|
fn decode_discr(&self) -> Discr<Self::NumVariants>;
|
||||||
|
@@ -128,6 +128,10 @@ pub trait IntoList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub type List<Args> = <Args as IntoList>::List;
|
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> {
|
impl<H> Meta for Node<H, Null> {
|
||||||
type Length = P1;
|
type Length = P1;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
use crate::compound::enumerated::{Discr, DiscriminantCodable, Enum, EnumRequirements, InternallyDiscriminated, VariantHandler};
|
use crate::compound::enumerated::{Discr, DiscriminantCodable, Enum, EnumRequirements, InternallyDiscriminated, VariantHandler};
|
||||||
use crate::compound::list::{IntoList as _, List};
|
use crate::compound::list::{Indexable, IntoList, List, List2, List3};
|
||||||
use crate::compound::peano::{Peano, P2};
|
use crate::compound::peano::{Peano, P0, P1, P2, P3};
|
||||||
use crate::real::Real;
|
use crate::real::Real;
|
||||||
use crate::vec::Vec3;
|
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 = "serde", derive(Deserialize, Serialize))]
|
||||||
#[cfg_attr(feature = "fmt", derive(Debug))]
|
#[cfg_attr(feature = "fmt", derive(Debug))]
|
||||||
#[derive(Copy, Clone, Default, PartialEq)]
|
#[derive(Clone, Default, PartialEq)]
|
||||||
pub struct DiscrMat2<M0, M1>(InternallyDiscriminated<(M0, M1)>);
|
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);
|
impl<Mats> DiscrMat<Mats> {
|
||||||
struct D1<T>(T);
|
fn new_from_fields(mats: Mats) -> Self {
|
||||||
|
Self(Enum::from_components((), mats))
|
||||||
impl<M0, M1> DiscrMat2<M0, M1> {
|
|
||||||
fn new_from_fields(m0: M0, m1: M1) -> Self {
|
|
||||||
Self(Enum::internally_discriminated((m0, m1)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M0: DiscriminantCodable<P2>, M1: Default> DiscrMat2<M0, M1> {
|
impl<Mats: Default> DiscrMat<Mats> {
|
||||||
pub fn new0(m: M0) -> Self {
|
fn new<P: Peano>(m: Mats::Element) -> Self
|
||||||
D0(m).into()
|
where
|
||||||
}
|
Mats: Indexable<P>,
|
||||||
pub fn new1(m: M1) -> Self {
|
Enum<(), Mats>: EnumRequirements,
|
||||||
D1(m).into()
|
{
|
||||||
}
|
let mut me = Self::default();
|
||||||
}
|
me.0.set::<P>(m);
|
||||||
|
me
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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> {
|
fn conductivity(&self) -> Vec3<R> {
|
||||||
self.0.dispatch(ConductivityDispatcher)
|
self.0.dispatch(ConductivityDispatcher)
|
||||||
@@ -97,12 +105,12 @@ pub type IsoConductorOr<R, M1> = DiscrMat2<IsomorphicConductor<R>, M1>;
|
|||||||
// IsomorphicConductor itself
|
// IsomorphicConductor itself
|
||||||
impl<R: Real> From<Ferroxcube3R1MH> for IsoConductorOr<R, Ferroxcube3R1MH> {
|
impl<R: Real> From<Ferroxcube3R1MH> for IsoConductorOr<R, Ferroxcube3R1MH> {
|
||||||
fn from(mat: Ferroxcube3R1MH) -> Self {
|
fn from(mat: Ferroxcube3R1MH) -> Self {
|
||||||
IsoConductorOr::new1(mat)
|
IsoConductorOr::new::<P1>(mat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<R: Real> From<IsomorphicConductor<R>> for IsoConductorOr<R, Ferroxcube3R1MH> {
|
impl<R: Real> From<IsomorphicConductor<R>> for IsoConductorOr<R, Ferroxcube3R1MH> {
|
||||||
fn from(mat: IsomorphicConductor<R>) -> Self {
|
fn from(mat: IsomorphicConductor<R>) -> Self {
|
||||||
IsoConductorOr::new0(mat)
|
IsoConductorOr::new::<P0>(mat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,10 +132,10 @@ mod test {
|
|||||||
fn iso_conductor_or_aniso() {
|
fn iso_conductor_or_aniso() {
|
||||||
type I = IsoConductorOr<R32, AnisomorphicConductor<R32>>;
|
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());
|
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()
|
Vec3::new(2.0, 3.0, 4.0).cast()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user