sim: port conductor-related legacy tests to spirv
This commit is contained in:
@@ -1254,12 +1254,14 @@ mod test {
|
|||||||
energy_now_and_then(&mut state, 1000)
|
energy_now_and_then(&mut state, 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PORT-STATUS: done
|
||||||
#[test]
|
#[test]
|
||||||
fn conductor_dissipates_energy() {
|
fn conductor_dissipates_energy() {
|
||||||
let (energy_0, energy_1) = conductor_test(IsomorphicConductor::new(R64::from_f32(1e3)));
|
let (energy_0, energy_1) = conductor_test(IsomorphicConductor::new(R64::from_f32(1e3)));
|
||||||
assert_float_eq!(energy_1/energy_0, 0.0, abs <= 1e-6);
|
assert_float_eq!(energy_1/energy_0, 0.0, abs <= 1e-6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PORT-STATUS: done
|
||||||
#[test]
|
#[test]
|
||||||
fn anisotropic_conductor_inactive_x() {
|
fn anisotropic_conductor_inactive_x() {
|
||||||
let (energy_0, energy_1) = conductor_test(AnisomorphicConductor::new(
|
let (energy_0, energy_1) = conductor_test(AnisomorphicConductor::new(
|
||||||
@@ -1270,6 +1272,7 @@ mod test {
|
|||||||
assert_lt!(energy_1, 1.5*energy_0);
|
assert_lt!(energy_1, 1.5*energy_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PORT-STATUS: done
|
||||||
#[test]
|
#[test]
|
||||||
fn anisotropic_conductor_inactive_y() {
|
fn anisotropic_conductor_inactive_y() {
|
||||||
let (energy_0, energy_1) = conductor_test(AnisomorphicConductor::new(
|
let (energy_0, energy_1) = conductor_test(AnisomorphicConductor::new(
|
||||||
@@ -1279,6 +1282,7 @@ mod test {
|
|||||||
assert_lt!(energy_1, 1.5*energy_0);
|
assert_lt!(energy_1, 1.5*energy_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PORT-STATUS: done
|
||||||
#[test]
|
#[test]
|
||||||
fn anisotropic_conductor_active_z() {
|
fn anisotropic_conductor_active_z() {
|
||||||
let (energy_0, energy_1) = conductor_test(AnisomorphicConductor::new(
|
let (energy_0, energy_1) = conductor_test(AnisomorphicConductor::new(
|
||||||
|
@@ -610,6 +610,7 @@ mod test {
|
|||||||
use super::backend_agnostic::*;
|
use super::backend_agnostic::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use crate::geom::WorldRegion;
|
||||||
use crate::meas::Energy;
|
use crate::meas::Energy;
|
||||||
use crate::stim::{
|
use crate::stim::{
|
||||||
self,
|
self,
|
||||||
@@ -619,7 +620,9 @@ mod test {
|
|||||||
StimExt as _,
|
StimExt as _,
|
||||||
VectorField
|
VectorField
|
||||||
};
|
};
|
||||||
|
use coremem_cross::mat::{AnisomorphicConductor, IsomorphicConductor};
|
||||||
use float_eq::assert_float_eq;
|
use float_eq::assert_float_eq;
|
||||||
|
use more_asserts::{assert_gt, assert_lt};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn accessors() {
|
fn accessors() {
|
||||||
@@ -650,30 +653,41 @@ mod test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn smooth_pulse_at(timestep: f32, loc: Index, frames: u32) -> impl Stimulus<R32> {
|
fn smooth_pulse_at(timestep: f32, feat_size: f32, loc: Index, frames: u32) -> impl Stimulus<R32> {
|
||||||
let wl = (timestep * frames as f32).to_r32();
|
let wl = (timestep * frames as f32).to_r32();
|
||||||
let quarter_wl = wl * (0.25).to_r32();
|
let quarter_wl = wl * (0.25).to_r32();
|
||||||
|
let amp = (timestep*feat_size*feat_size).inv().to_r32();
|
||||||
|
let window = Sinusoid::from_wavelength(R32::one(), wl)
|
||||||
|
.shifted(quarter_wl)
|
||||||
|
.summed(R32::one());
|
||||||
ModulatedVectorField::new(
|
ModulatedVectorField::new(
|
||||||
IndexGatedEField { loc },
|
IndexGatedEField { loc },
|
||||||
Sinusoid::from_wavelength(R32::one(), wl).scaled(
|
// amp,
|
||||||
Sinusoid::from_wavelength(R32::one(), wl).shifted(quarter_wl).summed(R32::one())
|
// window.scaled(amp),
|
||||||
),
|
// Sinusoid::from_wavelength(amp, wl).shifted(quarter_wl)
|
||||||
|
// Sinusoid::from_wavelength(amp, wl * R32::two()),
|
||||||
|
Sinusoid::from_wavelength(amp, wl).scaled(window),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn step_n<S: AbstractSim, Stim: Stimulus<S::Real>>(state: &mut S, stim: &Stim, frames: u32) -> f32 {
|
||||||
|
for _ in 0..frames {
|
||||||
|
state.step_multiple(1, stim);
|
||||||
|
}
|
||||||
|
Energy::world().data(state)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn energy_conservation_over_time() {
|
fn energy_conservation_over_time() {
|
||||||
let mut state = SpirvSim::<R32, FullyGenericMaterial<R32>, $backend>::new(
|
let mut state = SpirvSim::<R32, FullyGenericMaterial<R32>, $backend>::new(
|
||||||
Index((2001, 1, 1).into()), 1e-6
|
Index((2001, 1, 1).into()), 1e-6
|
||||||
);
|
);
|
||||||
let stim = smooth_pulse_at(state.timestep(), Index::new(1000, 0, 0), 100);
|
let stim = smooth_pulse_at(state.timestep(), state.feature_size(), Index::new(1000, 0, 0), 100);
|
||||||
|
|
||||||
state.step_multiple(100, &stim);
|
let energy_0 = step_n(&mut state, &stim, 100);
|
||||||
let energy_0 = Energy::world().data(&state);
|
let energy_1 = step_n(&mut state, &NoopStimulus, 800);
|
||||||
state.step_multiple(800, &NoopStimulus);
|
|
||||||
let energy_1 = Energy::world().data(&state);
|
|
||||||
|
|
||||||
assert_float_eq!(energy_1, energy_0, r2nd <= 1e-9);
|
assert_float_eq!(energy_1, energy_0, r2nd <= 1e-4);
|
||||||
// TODO: assert that energy is something reasonable to begin with, and not 0.
|
// TODO: assert that energy is something reasonable to begin with, and not 0.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,15 +696,64 @@ mod test {
|
|||||||
let mut state = SpirvSim::<R32, FullyGenericMaterial<R32>, $backend>::new(
|
let mut state = SpirvSim::<R32, FullyGenericMaterial<R32>, $backend>::new(
|
||||||
Index((21, 21, 21).into()), 1e-6
|
Index((21, 21, 21).into()), 1e-6
|
||||||
);
|
);
|
||||||
let stim = smooth_pulse_at(state.timestep(), Index::new(10, 10, 10), 40);
|
let stim = smooth_pulse_at(state.timestep(), state.feature_size(), Index::new(10, 10, 10), 40);
|
||||||
|
|
||||||
state.step_multiple(40, &stim);
|
let energy_0 = step_n(&mut state, &stim, 40);
|
||||||
let energy_0 = Energy::world().data(&state);
|
let energy_1 = step_n(&mut state, &NoopStimulus, 500);
|
||||||
state.step_multiple(500, &NoopStimulus);
|
|
||||||
let energy_1 = Energy::world().data(&state);
|
|
||||||
|
|
||||||
// Default boundary conditions reflect waves.
|
// Default boundary conditions reflect waves.
|
||||||
assert_float_eq!(energy_1, energy_0, r2nd <= 1e-2);
|
// but maybe not *perfectly*
|
||||||
|
assert_lt!(energy_1, energy_0);
|
||||||
|
assert_gt!(energy_1, 0.5 * energy_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fill the world with the provided material and a stimulus.
|
||||||
|
/// Measure energy at the start, and then again after advancing many steps.
|
||||||
|
/// Return these two measurements (energy(t=0), energy(t=~=1000))
|
||||||
|
fn conductor_test<M: Into<FullyGenericMaterial<R32>>>(mat: M) -> (f32, f32) {
|
||||||
|
let mut state = SpirvSim::<R32, FullyGenericMaterial<R32>, $backend>::new(
|
||||||
|
Index::new(201, 1, 1), 1e-6
|
||||||
|
);
|
||||||
|
state.fill_region(&WorldRegion, mat.into());
|
||||||
|
let stim = smooth_pulse_at(state.timestep(), state.feature_size(), Index::new(100, 0, 0), 100);
|
||||||
|
|
||||||
|
let energy_0 = step_n(&mut state, &stim, 100);
|
||||||
|
let energy_1 = step_n(&mut state, &NoopStimulus, 1000);
|
||||||
|
|
||||||
|
(energy_0, energy_1)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn conductor_dissipates_energy() {
|
||||||
|
let (energy_0, energy_1) = conductor_test(IsomorphicConductor::new(1e3.cast()));
|
||||||
|
assert_float_eq!(energy_1/energy_0, 0.0, abs <= 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn anisotropic_conductor_inactive_x() {
|
||||||
|
let (energy_0, energy_1) = conductor_test(AnisomorphicConductor::new(
|
||||||
|
Vec3::new_x(1e3).cast()
|
||||||
|
));
|
||||||
|
assert_gt!(energy_1, 0.9*energy_0);
|
||||||
|
// XXX: I think this gains energy because we only set the E field and not the H field
|
||||||
|
assert_lt!(energy_1, 1.8*energy_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn anisotropic_conductor_inactive_y() {
|
||||||
|
let (energy_0, energy_1) = conductor_test(AnisomorphicConductor::new(
|
||||||
|
Vec3::new_y(1e3).cast()
|
||||||
|
));
|
||||||
|
assert_gt!(energy_1, 0.9*energy_0);
|
||||||
|
assert_lt!(energy_1, 1.8*energy_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn anisotropic_conductor_active_z() {
|
||||||
|
let (energy_0, energy_1) = conductor_test(AnisomorphicConductor::new(
|
||||||
|
Vec3::new_z(1e3).cast()
|
||||||
|
));
|
||||||
|
assert_float_eq!(energy_1/energy_0, 0.0, abs <= 1e-6);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Reference in New Issue
Block a user