cross: step: finish backfilling step_h tests
This commit is contained in:
@@ -189,6 +189,7 @@ impl<'a, R: Real, M: Material<R>> StepHContext<'a, R, M> {
|
|||||||
let mu0_inv = R::mu0_inv();
|
let mu0_inv = R::mu0_inv();
|
||||||
let deltas = self.in_e.delta_e();
|
let deltas = self.in_e.delta_e();
|
||||||
// \nabla x E
|
// \nabla x E
|
||||||
|
// TODO: inv_feature_size and time_step could be folded
|
||||||
let nabla_e = deltas.nabla() * self.inv_feature_size;
|
let nabla_e = deltas.nabla() * self.inv_feature_size;
|
||||||
let delta_b = nabla_e * (-self.time_step);
|
let delta_b = nabla_e * (-self.time_step);
|
||||||
|
|
||||||
@@ -216,6 +217,7 @@ mod test {
|
|||||||
use crate::compound::Optional;
|
use crate::compound::Optional;
|
||||||
use crate::mat::Vacuum;
|
use crate::mat::Vacuum;
|
||||||
use float_eq::assert_float_eq;
|
use float_eq::assert_float_eq;
|
||||||
|
use std::cell::Cell;
|
||||||
|
|
||||||
fn assert_vec_eq(a: Vec3<f32>, b: Vec3<f32>) {
|
fn assert_vec_eq(a: Vec3<f32>, b: Vec3<f32>) {
|
||||||
assert_float_eq!(a.x(), b.x(), r2nd <= 1e-6);
|
assert_float_eq!(a.x(), b.x(), r2nd <= 1e-6);
|
||||||
@@ -286,12 +288,112 @@ mod test {
|
|||||||
// $ 2.0 - 4.0 ]$
|
// $ 2.0 - 4.0 ]$
|
||||||
// this gets negated, and then scaled by $\mu_0^{-1}$
|
// this gets negated, and then scaled by $\mu_0^{-1}$
|
||||||
//```
|
//```
|
||||||
|
let delta_b = -Vec3::new(-2.0, 4.0, -2.0);
|
||||||
|
|
||||||
let (new_h, new_m) = ctx.step_h();
|
let (new_h, new_m) = ctx.step_h();
|
||||||
let b = -Vec3::new(-2.0, 4.0, -2.0);
|
assert_vec_eq(new_h, delta_b * f32::mu0_inv());
|
||||||
assert_vec_eq(new_h, b * f32::mu0_inv());
|
|
||||||
assert_vec_eq(new_m, Vec3::zero());
|
assert_vec_eq(new_m, Vec3::zero());
|
||||||
}
|
}
|
||||||
// TODO: backfill step_h tests
|
#[test]
|
||||||
|
fn step_h_understands_time_scale_feature_size() {
|
||||||
|
let mid = Vec3::new(4.0, 8.0, 12.0);
|
||||||
|
let ctx = StepHContext {
|
||||||
|
inv_feature_size: 5.0, // $\Delta x = 0.2$
|
||||||
|
time_step: 1e-3,
|
||||||
|
stim_h: Vec3::zero(),
|
||||||
|
mat: &Vacuum,
|
||||||
|
in_e: VolumeSamplePos {
|
||||||
|
mid,
|
||||||
|
xp1: Optional::some(mid + Vec3::new(1.0, 2.0, 3.0)),
|
||||||
|
yp1: Optional::some(mid + Vec3::new(4.0, 5.0, 6.0)),
|
||||||
|
zp1: Optional::some(mid + Vec3::new(7.0, 8.0, 9.0)),
|
||||||
|
},
|
||||||
|
in_h: Vec3::zero(),
|
||||||
|
in_m: Vec3::zero(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// see step_h_understands_nabla_e
|
||||||
|
// the nabla is dE/dx, so divide by \Delta x.
|
||||||
|
// nabla relates to dB/dt, so multiply by \Delta t to get \Delta B
|
||||||
|
let delta_b = -Vec3::new(-2.0, 4.0, -2.0) * 1e-3 / 0.2;
|
||||||
|
|
||||||
|
let (new_h, new_m) = ctx.step_h();
|
||||||
|
assert_vec_eq(new_h, delta_b * f32::mu0_inv());
|
||||||
|
assert_vec_eq(new_m, Vec3::zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MockMaterial {
|
||||||
|
response: Vec3<f32>,
|
||||||
|
called_with: Cell<(Vec3<f32>, Vec3<f32>)>,
|
||||||
|
}
|
||||||
|
impl Material<f32> for MockMaterial {
|
||||||
|
fn move_b_vec(&self, m: Vec3<f32>, target_b: Vec3<f32>) -> Vec3<f32> {
|
||||||
|
self.called_with.set((m, target_b));
|
||||||
|
self.response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn step_h_respects_material() {
|
||||||
|
let mock_mat = MockMaterial {
|
||||||
|
response: Vec3::new(1e-6, 2e-6, 3e-6),
|
||||||
|
called_with: Default::default(),
|
||||||
|
};
|
||||||
|
let ctx = StepHContext {
|
||||||
|
inv_feature_size: 1.0,
|
||||||
|
time_step: 1.0,
|
||||||
|
stim_h: Vec3::zero(),
|
||||||
|
mat: &mock_mat,
|
||||||
|
in_e: VolumeSamplePos {
|
||||||
|
mid: Vec3::zero(),
|
||||||
|
xp1: Optional::some(Vec3::new(1.0, 2.0, 3.0)),
|
||||||
|
yp1: Optional::some(Vec3::new(4.0, 5.0, 6.0)),
|
||||||
|
zp1: Optional::some(Vec3::new(7.0, 8.0, 9.0)),
|
||||||
|
},
|
||||||
|
in_h: Vec3::zero(),
|
||||||
|
in_m: Vec3::zero(),
|
||||||
|
};
|
||||||
|
// see step_h_understands_nabla_e
|
||||||
|
let delta_b = -Vec3::new(-2.0, 4.0, -2.0);
|
||||||
|
|
||||||
|
let (new_h, new_m) = ctx.step_h();
|
||||||
|
assert_vec_eq(mock_mat.called_with.get().0, Vec3::zero()); // not magnetized
|
||||||
|
assert_vec_eq(mock_mat.called_with.get().1, delta_b);
|
||||||
|
assert_vec_eq(new_m, mock_mat.response);
|
||||||
|
assert_vec_eq(new_h, delta_b * f32::mu0_inv() - new_m);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn step_h_understands_previous_m_h() {
|
||||||
|
let mock_mat = MockMaterial {
|
||||||
|
response: Vec3::new(1e-6, 2e-6, 3e-6),
|
||||||
|
called_with: Default::default(),
|
||||||
|
};
|
||||||
|
let in_h = Vec3::new(4e-6, 5e-6, 6e-6);
|
||||||
|
let in_m = Vec3::new(7e-6, 8e-6, 9e-6);
|
||||||
|
let ctx = StepHContext {
|
||||||
|
inv_feature_size: 1.0,
|
||||||
|
time_step: 1.0,
|
||||||
|
stim_h: Vec3::zero(),
|
||||||
|
mat: &mock_mat,
|
||||||
|
in_e: VolumeSamplePos {
|
||||||
|
mid: Vec3::zero(),
|
||||||
|
xp1: Optional::some(Vec3::new(1.0, 2.0, 3.0)),
|
||||||
|
yp1: Optional::some(Vec3::new(4.0, 5.0, 6.0)),
|
||||||
|
zp1: Optional::some(Vec3::new(7.0, 8.0, 9.0)),
|
||||||
|
},
|
||||||
|
in_h,
|
||||||
|
in_m,
|
||||||
|
};
|
||||||
|
// see step_h_understands_nabla_e
|
||||||
|
let delta_b = -Vec3::new(-2.0, 4.0, -2.0);
|
||||||
|
let prev_b = (in_h + in_m) * f32::mu0();
|
||||||
|
let new_b = prev_b + delta_b;
|
||||||
|
|
||||||
|
let (new_h, new_m) = ctx.step_h();
|
||||||
|
assert_vec_eq(mock_mat.called_with.get().0, in_m);
|
||||||
|
assert_vec_eq(mock_mat.called_with.get().1, new_b);
|
||||||
|
assert_vec_eq(new_m, mock_mat.response);
|
||||||
|
assert_vec_eq(new_h, new_b * f32::mu0_inv() - new_m);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: backfill step_e tests
|
// TODO: backfill step_e tests
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user