replace the FullyGenericMaterial in spirv with an analog type from coremem_types
this represents the last spirv-specific material. next steps are to start removing the materials from `coremem` itself (i.e. re-exporting more from `coremem_types::mat`).
This commit is contained in:
parent
4cbcc46d50
commit
847b95f036
|
@ -59,7 +59,7 @@ fn main() {
|
|||
let coupling_region = Torus::new_xz(Meters::new(0.5*(ferro1_center + ferro2_center), ferro_center_y, half_depth), wire_coupling_major, wire_minor);
|
||||
let sense_region = Torus::new_xz(Meters::new(ferro2_center + ferro_major, ferro_center_y, half_depth), wire_major, wire_minor);
|
||||
|
||||
let mut driver: SpirvDriver<spirv::FullyGenericMaterial> = Driver::new_spirv(Meters::new(width, height, depth), feat_size);
|
||||
let mut driver: SpirvDriver<mat::FullyGenericMaterial<f32>> = Driver::new_spirv(Meters::new(width, height, depth), feat_size);
|
||||
|
||||
// mu_r=881.33, starting at H=25 to H=75.
|
||||
driver.fill_region(&ferro1_region, mat::MHPgram::new(25.0, 881.33, 44000.0));
|
||||
|
|
|
@ -36,7 +36,7 @@ pub struct Driver<S=SimState> {
|
|||
}
|
||||
|
||||
pub type CpuDriver<R=real::R32, M=mat::GenericMaterial<R>> = Driver<SimState<R, M>>;
|
||||
pub type SpirvDriver<M=spirv::FullyGenericMaterial> = Driver<SpirvSim<M>>;
|
||||
pub type SpirvDriver<M=mat::FullyGenericMaterial<f32>> = Driver<SpirvSim<M>>;
|
||||
|
||||
impl<R: Real, M: Default> Driver<SimState<R, M>> {
|
||||
pub fn new<C: Coord>(size: C, feature_size: f32) -> Self {
|
||||
|
|
|
@ -13,7 +13,14 @@ mod linear;
|
|||
|
||||
pub use bh_ferromagnet::*;
|
||||
pub use mb_ferromagnet::*;
|
||||
pub use coremem_types::mat::{AnisomorphicConductor, Ferroxcube3R1MH, IsoConductorOr, IsomorphicConductor, MHPgram};
|
||||
pub use coremem_types::mat::{
|
||||
AnisomorphicConductor,
|
||||
Ferroxcube3R1MH,
|
||||
FullyGenericMaterial,
|
||||
IsoConductorOr,
|
||||
IsomorphicConductor,
|
||||
MHPgram
|
||||
};
|
||||
pub use linear::*;
|
||||
|
||||
#[enum_dispatch]
|
||||
|
|
|
@ -2,7 +2,18 @@ use serde::de::Deserializer;
|
|||
use serde::ser::Serializer;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::mat::{AnisomorphicConductor, IsoConductorOr, IsomorphicConductor, Ferroxcube3R1MH, MaterialExt as _, MBFerromagnet, MBPgram, MHPgram, Static};
|
||||
use crate::mat::{
|
||||
AnisomorphicConductor,
|
||||
IsoConductorOr,
|
||||
IsomorphicConductor,
|
||||
Ferroxcube3R1MH,
|
||||
FullyGenericMaterial,
|
||||
MaterialExt as _,
|
||||
MBFerromagnet,
|
||||
MBPgram,
|
||||
MHPgram,
|
||||
Static
|
||||
};
|
||||
use crate::geom::{Index, Vec3, Vec3u};
|
||||
|
||||
/// hide the actual spirv backend structures inside a submodule to make their use/boundary clear.
|
||||
|
@ -10,7 +21,6 @@ mod ffi {
|
|||
pub use spirv_backend::entry_points;
|
||||
pub use spirv_backend::sim::SerializedSimMeta;
|
||||
pub use spirv_backend::support::Optional;
|
||||
pub use spirv_backend::mat::FullyGenericMaterial;
|
||||
pub use coremem_types::mat::MBPgram;
|
||||
}
|
||||
|
||||
|
@ -88,86 +98,19 @@ impl IntoLib for ffi::MBPgram<f32> {
|
|||
|
||||
identity!( => MHPgram<f32>);
|
||||
identity!( => Ferroxcube3R1MH);
|
||||
identity!( => FullyGenericMaterial<f32>);
|
||||
identity!(R, M, => IsoConductorOr<R, M>);
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Serialize, Deserialize)]
|
||||
pub struct FullyGenericMaterial {
|
||||
pub conductivity: Vec3<f32>,
|
||||
pub m_b_curve: Option<MBPgram<f32>>,
|
||||
pub m_h_curve: Option<MHPgram<f32>>,
|
||||
}
|
||||
|
||||
impl IntoFfi for FullyGenericMaterial {
|
||||
type Ffi = ffi::FullyGenericMaterial;
|
||||
fn into_ffi(self) -> Self::Ffi {
|
||||
Self::Ffi {
|
||||
conductivity: self.conductivity.into_ffi(),
|
||||
m_b_curve: self.m_b_curve.into_ffi(),
|
||||
m_h_curve: self.m_h_curve.into_ffi(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLib for ffi::FullyGenericMaterial {
|
||||
type Lib = FullyGenericMaterial;
|
||||
fn into_lib(self) -> Self::Lib {
|
||||
Self::Lib {
|
||||
conductivity: self.conductivity.into_lib(),
|
||||
m_b_curve: self.m_b_curve.into_lib(),
|
||||
m_h_curve: self.m_h_curve.into_lib(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Static<f32>> for FullyGenericMaterial {
|
||||
// N.B.: this isn't fully correct, as Static also encodes the magnetic component
|
||||
impl From<Static<f32>> for FullyGenericMaterial<f32> {
|
||||
fn from(m: Static<f32>) -> Self {
|
||||
FullyGenericMaterial {
|
||||
conductivity: m.conductivity(),
|
||||
.. Default::default()
|
||||
}
|
||||
AnisomorphicConductor::new(m.conductivity).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AnisomorphicConductor<f32>> for FullyGenericMaterial {
|
||||
fn from(m: AnisomorphicConductor<f32>) -> Self {
|
||||
FullyGenericMaterial {
|
||||
conductivity: m.conductivity(),
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IsomorphicConductor<f32>> for FullyGenericMaterial {
|
||||
fn from(m: IsomorphicConductor<f32>) -> Self {
|
||||
FullyGenericMaterial {
|
||||
conductivity: m.conductivity(),
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MBFerromagnet<f32>> for FullyGenericMaterial {
|
||||
impl From<MBFerromagnet<f32>> for FullyGenericMaterial<f32> {
|
||||
fn from(m: MBFerromagnet<f32>) -> Self {
|
||||
FullyGenericMaterial {
|
||||
m_b_curve: Some(m.curve()),
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MHPgram<f32>> for FullyGenericMaterial {
|
||||
fn from(m: MHPgram<f32>) -> Self {
|
||||
FullyGenericMaterial {
|
||||
m_h_curve: Some(m),
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Ferroxcube3R1MH> for FullyGenericMaterial {
|
||||
fn from(m: Ferroxcube3R1MH) -> Self {
|
||||
let curve: MHPgram<f32> = m.into();
|
||||
curve.into()
|
||||
m.curve().into_ffi().into()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,16 +12,16 @@ use crate::geom::{Coord, Index, Meters, Vec3};
|
|||
use crate::real::Real as _;
|
||||
use crate::sim::{CellStateWithM, GenericSim, MaterialSim, Sample, SampleableSim};
|
||||
use crate::stim::AbstractStimulus;
|
||||
use coremem_types::mat::Material;
|
||||
use coremem_types::mat::{FullyGenericMaterial, Material};
|
||||
|
||||
mod bindings;
|
||||
pub use bindings::{entry_points, IntoFfi, IntoLib, FullyGenericMaterial, Remote, SimMeta};
|
||||
pub use bindings::{entry_points, IntoFfi, IntoLib, Remote, SimMeta};
|
||||
|
||||
/// Wrapper around an inner state object which offloads stepping onto a spirv backend (e.g. GPU).
|
||||
#[derive(Clone, Default, Serialize, Deserialize)]
|
||||
#[serde(bound(serialize = "M: Serialize + IntoFfi, M::Ffi: Clone + IntoLib<Lib=M>"))]
|
||||
#[serde(bound(deserialize = "M: Deserialize<'de> + IntoFfi, M::Ffi: IntoLib<Lib=M>"))]
|
||||
pub struct SpirvSim<M=FullyGenericMaterial>
|
||||
pub struct SpirvSim<M=FullyGenericMaterial<f32>>
|
||||
where M: IntoFfi,
|
||||
{
|
||||
meta: SimMeta,
|
||||
|
@ -70,7 +70,7 @@ impl WgpuData {
|
|||
|
||||
impl Default for WgpuData {
|
||||
fn default() -> Self {
|
||||
Self::new::<FullyGenericMaterial>(0)
|
||||
Self::new::<FullyGenericMaterial<f32>>(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +1,4 @@
|
|||
use crate::support::Optional;
|
||||
use coremem_types::mat::{Material, MBPgram, MHPgram};
|
||||
use coremem_types::vec::Vec3;
|
||||
|
||||
|
||||
#[derive(Copy, Clone, Default, PartialEq)]
|
||||
pub struct FullyGenericMaterial {
|
||||
pub conductivity: Vec3<f32>,
|
||||
pub m_b_curve: Optional<MBPgram<f32>>,
|
||||
pub m_h_curve: Optional<MHPgram<f32>>,
|
||||
}
|
||||
|
||||
impl Material<f32> for FullyGenericMaterial {
|
||||
fn conductivity(&self) -> Vec3<f32> {
|
||||
self.conductivity
|
||||
}
|
||||
fn move_b_vec(&self, m: Vec3<f32>, target_b: Vec3<f32>) -> Vec3<f32> {
|
||||
if self.m_b_curve.is_some() {
|
||||
self.m_b_curve.unwrap().move_b_vec(m, target_b)
|
||||
} else if self.m_h_curve.is_some() {
|
||||
self.m_h_curve.unwrap().move_b_vec(m, target_b)
|
||||
} else {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: plumb the R parameter through and remove this.
|
||||
pub type FullyGenericMaterial = coremem_types::mat::FullyGenericMaterial<f32>;
|
||||
pub type IsoConductorOr<M> = coremem_types::mat::IsoConductorOr<f32, M>;
|
||||
|
||||
|
|
|
@ -3,7 +3,15 @@ use crate::compound::list::{Indexable, List2, List3};
|
|||
use crate::compound::peano::{Peano, P0, P1, P2, P3};
|
||||
use crate::real::Real;
|
||||
use crate::vec::Vec3;
|
||||
use crate::mat::{Ferroxcube3R1MH, IsomorphicConductor, Material};
|
||||
use crate::mat::{
|
||||
AnisomorphicConductor,
|
||||
Ferroxcube3R1MH,
|
||||
IsomorphicConductor,
|
||||
Material,
|
||||
MBPgram,
|
||||
MHPgram,
|
||||
Vacuum,
|
||||
};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
@ -13,7 +21,7 @@ use serde::{Serialize, Deserialize};
|
|||
/// (i.e. that it implements DiscriminantCodable).
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
#[cfg_attr(feature = "fmt", derive(Debug))]
|
||||
#[derive(Clone, Default, PartialEq)]
|
||||
#[derive(Copy, 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>>;
|
||||
|
@ -36,6 +44,7 @@ impl<Mats: Default> DiscrMat<Mats> {
|
|||
}
|
||||
}
|
||||
|
||||
/// invokes Material::conductivity on any Material
|
||||
struct ConductivityDispatcher;
|
||||
impl<P: Peano, R: Real, T: Material<R>> VariantHandler<P, T, Vec3<R>> for ConductivityDispatcher {
|
||||
fn call(self, v: T) -> Vec3<R> {
|
||||
|
@ -43,6 +52,7 @@ impl<P: Peano, R: Real, T: Material<R>> VariantHandler<P, T, Vec3<R>> for Conduc
|
|||
}
|
||||
}
|
||||
|
||||
/// invokes Material::move_b_vec on any Material
|
||||
struct MoveBVecDispatcher<R> {
|
||||
m: Vec3<R>,
|
||||
target_b: Vec3<R>,
|
||||
|
@ -80,6 +90,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// represents a Material which is either an isomorphic conductor, or some other Material `M1`
|
||||
pub type IsoConductorOr<R, M1> = DiscrMat2<IsomorphicConductor<R>, M1>;
|
||||
|
||||
// XXX: can't do this for generic M, because that creates duplicate `From` impls for the
|
||||
|
@ -95,6 +106,105 @@ impl<R: Real> From<IsomorphicConductor<R>> for IsoConductorOr<R, Ferroxcube3R1MH
|
|||
}
|
||||
}
|
||||
|
||||
/// muxes operations to either the conductor or the magnetic material
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
#[cfg_attr(feature = "fmt", derive(Debug))]
|
||||
#[derive(Copy, Clone, Default, PartialEq)]
|
||||
pub struct DualMaterial<C, M> {
|
||||
conductor: C,
|
||||
magnetic: M,
|
||||
}
|
||||
|
||||
impl<C, M> DualMaterial<C, M> {
|
||||
pub fn new(conductor: C, magnetic: M) -> Self {
|
||||
Self { conductor, magnetic }
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Real, C: Material<R>, M: Material<R>> Material<R> for DualMaterial<C, M> {
|
||||
fn conductivity(&self) -> Vec3<R> {
|
||||
self.conductor.conductivity()
|
||||
}
|
||||
fn move_b_vec(&self, m: Vec3<R>, target_b: Vec3<R>) -> Vec3<R> {
|
||||
self.magnetic.move_b_vec(m, target_b)
|
||||
}
|
||||
}
|
||||
|
||||
/// Material which can encode any of the well-known magnetic materials (or Vacuum)
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
#[cfg_attr(feature = "fmt", derive(Debug))]
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub struct GenericMagnetic<R>(DiscrMat3<MBPgram<R>, MHPgram<R>, Vacuum>);
|
||||
|
||||
impl<R: Real> Default for GenericMagnetic<R> {
|
||||
fn default() -> Self {
|
||||
// N.B.: the default is not the first variant.
|
||||
// we order the variants specifically so that the first one can store the descriminant, but
|
||||
// we NEED Vacuum to be the default.
|
||||
Vacuum.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Real> Material<R> for GenericMagnetic<R> {
|
||||
fn conductivity(&self) -> Vec3<R> {
|
||||
self.0.conductivity()
|
||||
}
|
||||
fn move_b_vec(&self, m: Vec3<R>, target_b: Vec3<R>) -> Vec3<R> {
|
||||
self.0.move_b_vec(m, target_b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Real> From<MBPgram<R>> for GenericMagnetic<R> {
|
||||
fn from(mat: MBPgram<R>) -> Self {
|
||||
GenericMagnetic(DiscrMat3::new::<P0>(mat))
|
||||
}
|
||||
}
|
||||
impl<R: Real> From<MHPgram<R>> for GenericMagnetic<R> {
|
||||
fn from(mat: MHPgram<R>) -> Self {
|
||||
GenericMagnetic(DiscrMat3::new::<P1>(mat))
|
||||
}
|
||||
}
|
||||
impl<R: Real> From<Vacuum> for GenericMagnetic<R> {
|
||||
fn from(mat: Vacuum) -> Self {
|
||||
GenericMagnetic(DiscrMat3::new::<P2>(mat))
|
||||
}
|
||||
}
|
||||
|
||||
/// "Fully Generic" in that one can set both the conductivity,
|
||||
/// and set any of the well-known magnetic materials, simultaneously.
|
||||
pub type FullyGenericMaterial<R> = DualMaterial<
|
||||
AnisomorphicConductor<R>,
|
||||
GenericMagnetic<R>,
|
||||
>;
|
||||
|
||||
impl<R: Real> From<AnisomorphicConductor<R>> for FullyGenericMaterial<R> {
|
||||
fn from(mat: AnisomorphicConductor<R>) -> Self {
|
||||
Self::new(mat, Default::default())
|
||||
}
|
||||
}
|
||||
impl<R: Real> From<MBPgram<R>> for FullyGenericMaterial<R> {
|
||||
fn from(mat: MBPgram<R>) -> Self {
|
||||
Self::new(Default::default(), mat.into())
|
||||
}
|
||||
}
|
||||
impl<R: Real> From<MHPgram<R>> for FullyGenericMaterial<R> {
|
||||
fn from(mat: MHPgram<R>) -> Self {
|
||||
Self::new(Default::default(), mat.into())
|
||||
}
|
||||
}
|
||||
impl<R: Real> From<IsomorphicConductor<R>> for FullyGenericMaterial<R> {
|
||||
fn from(mat: IsomorphicConductor<R>) -> Self {
|
||||
let mat: AnisomorphicConductor<R> = mat.into();
|
||||
mat.into()
|
||||
}
|
||||
}
|
||||
impl<R: Real> From<Ferroxcube3R1MH> for FullyGenericMaterial<R> {
|
||||
fn from(mat: Ferroxcube3R1MH) -> Self {
|
||||
let mat: MHPgram<R> = mat.into();
|
||||
mat.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
|
|
@ -50,6 +50,23 @@ impl<R: Real> Material<R> for IsomorphicConductor<R> {
|
|||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use crate::compound::enumerated::{Discr, DiscriminantCodable};
|
||||
use crate::compound::peano::Peano;
|
||||
use crate::mat::Material;
|
||||
use crate::real::Real;
|
||||
use crate::vec::Vec3;
|
||||
|
@ -67,6 +69,24 @@ impl<R: Real> Material<R> for MBPgram<R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<R: Real, P: Peano> DiscriminantCodable<P> for MBPgram<R> {
|
||||
fn decode_discr(&self) -> Discr<P> {
|
||||
let max_m = self.max_m;
|
||||
let d = if max_m < R::zero() {
|
||||
(-max_m.to_f32()) as u32
|
||||
} else {
|
||||
0
|
||||
};
|
||||
Discr::new(d)
|
||||
}
|
||||
fn encode_discr(d: Discr<P>) -> Self {
|
||||
Self {
|
||||
max_m: R::from_primitive(-(d.value() as i32)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
|
|
@ -5,11 +5,15 @@ mod compound;
|
|||
mod conductor;
|
||||
mod mb_pgram;
|
||||
mod mh_pgram;
|
||||
pub use compound::IsoConductorOr;
|
||||
pub use compound::{FullyGenericMaterial, IsoConductorOr};
|
||||
pub use conductor::{AnisomorphicConductor, IsomorphicConductor};
|
||||
pub use mb_pgram::MBPgram;
|
||||
pub use mh_pgram::{Ferroxcube3R1MH, MHPgram};
|
||||
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
pub trait Material<R: Real>: Sized {
|
||||
fn conductivity(&self) -> Vec3<R> {
|
||||
Default::default()
|
||||
|
@ -21,3 +25,11 @@ pub trait Material<R: Real>: Sized {
|
|||
m
|
||||
}
|
||||
}
|
||||
|
||||
/// Default, non-interesting Material.
|
||||
/// has 0 conductivity (electrical and magnetic)
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
#[cfg_attr(feature = "fmt", derive(Debug))]
|
||||
#[derive(Copy, Clone, Default, PartialEq)]
|
||||
pub struct Vacuum;
|
||||
impl<R: Real> Material<R> for Vacuum {}
|
||||
|
|
Loading…
Reference in New Issue