use allocation_counter::{self, AllocationInfo};
use semiflow::{
scratch::ScratchPool, ChernoffFunction, ChernoffSemigroup, DiffusionChernoff, Grid1D, GridFn1D,
TruncatedExp4thDiffusionChernoff,
};
fn a_half(_: f64) -> f64 {
0.5
}
fn a_zero(_: f64) -> f64 {
0.0
}
#[test]
fn diffusion_zero_alloc_steady() {
let n = 64;
let grid = Grid1D::new(-4.0, 4.0, n).unwrap();
let dx = grid.dx();
let a0 = 0.5;
let tau = 0.35 * dx * dx / a0;
let op = DiffusionChernoff::new(a_half, a_zero, a_zero, a0, grid);
let f0 = GridFn1D::from_fn(grid, |x| (-x * x).exp());
let mut pool = ScratchPool::new();
let mut dst = f0.zeroed_like();
op.apply_into(tau, &f0, &mut dst, &mut pool).unwrap();
let info: AllocationInfo = allocation_counter::measure(|| {
op.apply_into(tau, &f0, &mut dst, &mut pool).unwrap();
});
assert_eq!(
info.count_total, 0,
"DiffusionChernoff::apply_into allocated {} time(s) in steady state (expected 0)",
info.count_total
);
}
#[test]
fn texp4_zero_alloc_steady() {
let n = 64;
let grid = Grid1D::new(-4.0, 4.0, n).unwrap();
let dx = grid.dx();
let a0 = 0.5;
let tau = 0.25 * dx * dx / a0;
let op = TruncatedExp4thDiffusionChernoff::new(a_half, a_zero, a_zero, a0, grid);
let f0 = GridFn1D::from_fn(grid, |x| (-x * x).exp());
let mut pool = ScratchPool::new();
let mut dst = f0.zeroed_like();
op.apply_into(tau, &f0, &mut dst, &mut pool).unwrap();
let info: AllocationInfo = allocation_counter::measure(|| {
op.apply_into(tau, &f0, &mut dst, &mut pool).unwrap();
});
assert_eq!(
info.count_total, 0,
"TruncatedExp4th::apply_into allocated {} time(s) in steady state (expected 0)",
info.count_total
);
}
#[test]
fn chernoff_semigroup_ping_pong_allocs() {
let n = 64;
let grid = Grid1D::new(-4.0, 4.0, n).unwrap();
let a0 = 0.5;
let t = 0.01;
let steps = 4_usize;
#[allow(clippy::cast_precision_loss)]
let tau = t / steps as f64;
let dx = grid.dx();
assert!(tau < 0.4 * dx * dx / a0, "CFL violated in test setup");
let op = DiffusionChernoff::new(a_half, a_zero, a_zero, a0, grid);
let semi = ChernoffSemigroup::new(op, steps).unwrap();
let f0 = GridFn1D::from_fn(grid, |x| (-x * x).exp());
let info: AllocationInfo = allocation_counter::measure(|| {
let _result = semi.evolve(t, &f0).unwrap();
});
assert!(
info.count_total <= 4,
"ChernoffSemigroup::evolve allocated {} time(s) (expected ≤ 4 for buffers + scratch init)",
info.count_total
);
}