cross: step: finish backfilling step_h tests

This commit is contained in:
2022-08-26 02:03:15 -07:00
parent a7a9a9ea84
commit c90a73d395

View File

@@ -189,6 +189,7 @@ impl<'a, R: Real, M: Material<R>> StepHContext<'a, R, M> {
let mu0_inv = R::mu0_inv();
let deltas = self.in_e.delta_e();
// \nabla x E
// TODO: inv_feature_size and time_step could be folded
let nabla_e = deltas.nabla() * self.inv_feature_size;
let delta_b = nabla_e * (-self.time_step);
@@ -216,6 +217,7 @@ mod test {
use crate::compound::Optional;
use crate::mat::Vacuum;
use float_eq::assert_float_eq;
use std::cell::Cell;
fn assert_vec_eq(a: Vec3<f32>, b: Vec3<f32>) {
assert_float_eq!(a.x(), b.x(), r2nd <= 1e-6);
@@ -286,12 +288,112 @@ mod test {
// $ 2.0 - 4.0 ]$
// 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 b = -Vec3::new(-2.0, 4.0, -2.0);
assert_vec_eq(new_h, b * f32::mu0_inv());
assert_vec_eq(new_h, delta_b * f32::mu0_inv());
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
}