move spirv_backend/sim.rs -> coremem_types/step.rs

This commit is contained in:
2022-07-25 00:40:27 -07:00
parent 5fec965549
commit 15aaa3e893
4 changed files with 6 additions and 7 deletions

View File

@@ -1,4 +1,4 @@
use crate::sim::{StepEContext, StepHContext, VolumeSampleNeg, VolumeSamplePos};
use coremem_types::step::{StepEContext, StepHContext, VolumeSampleNeg, VolumeSamplePos};
use crate::support::{Array3, Array3Mut, UnsizedArray};
use coremem_types::compound::Optional;
use coremem_types::mat::Material;

View File

@@ -13,7 +13,6 @@ pub use spirv_std::glam;
use spirv_std::macros::spirv;
mod adapt;
pub mod sim;
pub mod support;
pub use adapt::SerializedSimMeta;

View File

@@ -1,203 +0,0 @@
// use spirv_std::RuntimeArray;
use coremem_types::compound::Optional;
use coremem_types::mat::Material;
use coremem_types::real::Real;
use coremem_types::vec::Vec3;
/// Package the field vectors adjacent to some particular location.
/// Particular those at negative offsets from the midpoint.
/// This is used in step_e when looking at the H field deltas.
#[derive(Copy, Clone)]
pub struct VolumeSampleNeg<R> {
pub mid: Vec3<R>,
pub xm1: Optional<Vec3<R>>,
pub ym1: Optional<Vec3<R>>,
pub zm1: Optional<Vec3<R>>,
}
impl<R: Real> VolumeSampleNeg<R> {
/// Calculate the delta in H values amongst this cell and its neighbors (left/up/out)
fn delta_h(self) -> FieldDeltas<R> {
let mid = self.mid;
// let (dfy_dx, dfz_dx) = self.xm1.map(|xm1| {
// (mid.y() - xm1.y(), mid.z() - xm1.z())
// }).unwrap_or_default();
// let (dfx_dy, dfz_dy) = self.ym1.map(|ym1| {
// (mid.x() - ym1.x(), mid.z() - ym1.z())
// }).unwrap_or_default();
// let (dfx_dz, dfy_dz) = self.zm1.map(|zm1| {
// (mid.x() - zm1.x(), mid.y() - zm1.y())
// }).unwrap_or_default();
let (dfy_dx, dfz_dx) = if self.xm1.is_some() {
(mid.y() - self.xm1.unwrap().y(), mid.z() - self.xm1.unwrap().z())
} else {
(R::zero(), R::zero())
};
let (dfx_dy, dfz_dy) = if self.ym1.is_some() {
(mid.x() - self.ym1.unwrap().x(), mid.z() - self.ym1.unwrap().z())
} else {
(R::zero(), R::zero())
};
let (dfx_dz, dfy_dz) = if self.zm1.is_some() {
(mid.x() - self.zm1.unwrap().x(), mid.y() - self.zm1.unwrap().y())
} else {
(R::zero(), R::zero())
};
FieldDeltas {
dfy_dx,
dfz_dx,
dfx_dy,
dfz_dy,
dfx_dz,
dfy_dz,
}
}
}
/// Package the field vectors adjacent to some particular location.
/// Particular those at positive offsets from the midpoint.
/// This is used in step_h when looking at the E field deltas.
#[derive(Copy, Clone)]
pub struct VolumeSamplePos<R> {
pub mid: Vec3<R>,
pub xp1: Optional<Vec3<R>>,
pub yp1: Optional<Vec3<R>>,
pub zp1: Optional<Vec3<R>>
}
impl<R: Real> VolumeSamplePos<R> {
/// Calculate the delta in E values amongst this cell and its neighbors (right/down/in)
fn delta_e(self) -> FieldDeltas<R> {
let mid = self.mid;
// let (dfy_dx, dfz_dx) = self.xp1.map(|xp1| {
// (xp1.y() - mid.y(), xp1.z() - mid.z())
// }).unwrap_or_default();
// let (dfx_dy, dfz_dy) = self.yp1.map(|yp1| {
// (yp1.x() - mid.x(), yp1.z() - mid.z())
// }).unwrap_or_default();
// let (dfx_dz, dfy_dz) = self.zp1.map(|zp1| {
// (zp1.x() - mid.x(), zp1.y() - mid.y())
// }).unwrap_or_default();
let (dfy_dx, dfz_dx) = if self.xp1.is_some() {
(self.xp1.unwrap().y() - mid.y(), self.xp1.unwrap().z() - mid.z())
} else {
(R::zero(), R::zero())
};
let (dfx_dy, dfz_dy) = if self.yp1.is_some() {
(self.yp1.unwrap().x() - mid.x(), self.yp1.unwrap().z() - mid.z())
} else {
(R::zero(), R::zero())
};
let (dfx_dz, dfy_dz) = if self.zp1.is_some() {
(self.zp1.unwrap().x() - mid.x(), self.zp1.unwrap().y() - mid.y())
} else {
(R::zero(), R::zero())
};
FieldDeltas {
dfy_dx,
dfz_dx,
dfx_dy,
dfz_dy,
dfx_dz,
dfy_dz,
}
}
}
struct FieldDeltas<R> {
dfy_dx: R,
dfz_dx: R,
dfx_dy: R,
dfz_dy: R,
dfx_dz: R,
dfy_dz: R,
}
impl<R: Real> FieldDeltas<R> {
fn nabla(self) -> Vec3<R> {
Vec3::new(
self.dfz_dy - self.dfy_dz,
self.dfx_dz - self.dfz_dx,
self.dfy_dx - self.dfx_dy,
)
}
}
pub struct StepEContext<'a, R, M> {
pub inv_feature_size: R,
pub time_step: R,
pub stim_e: Vec3<R>,
pub mat: &'a M,
/// Input field sampled near this location
pub in_h: VolumeSampleNeg<R>,
pub in_e: Vec3<R>,
}
impl<'a, R: Real, M: Material<R>> StepEContext<'a, R, M> {
pub fn step_e(self) -> Vec3<R> {
let twice_eps0 = R::twice_eps0();
let deltas = self.in_h.delta_h();
// \nabla x H
let nabla_h = deltas.nabla() * self.inv_feature_size;
// $\nabla x H = \epsilon_0 dE/dt + \sigma E$
// no-conductivity version:
// let delta_e = nabla_h * (self.time_step * EPS0_INV);
let sigma = self.mat.conductivity();
let e_prev = self.in_e;
let delta_e = (nabla_h - e_prev.elem_mul(sigma)).elem_div(
sigma*self.time_step + Vec3::uniform(twice_eps0)
)*(R::two()*self.time_step);
// println!("spirv-step_e delta_e: {:?}", delta_e);
e_prev + delta_e + self.stim_e
}
}
pub struct StepHContext<'a, R, M> {
pub inv_feature_size: R,
pub time_step: R,
pub stim_h: Vec3<R>,
pub mat: &'a M,
/// Input field sampled near this location
pub in_e: VolumeSamplePos<R>,
pub in_h: Vec3<R>,
pub in_m: Vec3<R>,
}
impl<'a, R: Real, M: Material<R>> StepHContext<'a, R, M> {
pub fn step_h(self) -> (Vec3<R>, Vec3<R>) {
let mu0 = R::mu0();
let mu0_inv = R::mu0_inv();
let deltas = self.in_e.delta_e();
// println!("spirv-step_h delta_e_struct: {:?}", deltas);
// \nabla x E
let nabla_e = deltas.nabla() * self.inv_feature_size;
// println!("spirv-step_h nabla_e: {:?}", nabla_e);
let delta_b = nabla_e * (-self.time_step);
// Relation between these is: B = mu0*(H + M)
let old_h = self.in_h;
let old_m = self.in_m;
let old_b = (old_h + old_m) * mu0;
let new_b = old_b + delta_b + self.stim_h * mu0;
let mat = self.mat;
let new_m = mat.move_b_vec(old_m, new_b);
let new_h = new_b * mu0_inv - new_m;
// println!("spirv-step_h delta_h: {:?}", delta_h);
(new_h, new_m)
}
}