use plot3d::{
verify_translational_periodicity, Block, FaceMatch, FaceRecord, Float, Orientation,
OrientationPlane,
};
const TOL: Float = 1.0e-6;
const PITCH_Y: Float = 0.4; const SPAN_Z: Float = 0.05;
fn make_block(imax: usize, jmax: usize, kmax: usize, y_offset: Float, z_offset: Float) -> Block {
let mut x = Vec::with_capacity(imax * jmax * kmax);
let mut y = Vec::with_capacity(imax * jmax * kmax);
let mut z = Vec::with_capacity(imax * jmax * kmax);
for k in 0..kmax {
for j in 0..jmax {
for i in 0..imax {
x.push(i as Float * 0.1);
y.push(j as Float * 0.05 + y_offset);
z.push(k as Float * 0.02 + z_offset);
}
}
}
Block::new(imax, jmax, kmax, x, y, z)
}
fn periodic_face(
b1: (usize, [usize; 3], [usize; 3]),
b2: (usize, [usize; 3], [usize; 3]),
matrix: [[i8; 2]; 2],
) -> FaceMatch {
let face_record = |block_index, lb: [usize; 3], ub: [usize; 3]| FaceRecord {
block_index,
il: lb[0],
jl: lb[1],
kl: lb[2],
ih: ub[0],
jh: ub[1],
kh: ub[2],
id: None,
u_physical: None,
v_physical: None,
};
FaceMatch {
block1: face_record(b1.0, b1.1, b1.2),
block2: face_record(b2.0, b2.1, b2.2),
points: Vec::new(),
orientation: Some(Orientation {
permutation_index: 0,
plane: OrientationPlane::InPlane,
permutation_matrix: Some(matrix),
}),
}
}
#[test]
fn translational_y_pitch_resolves_to_index_zero() {
let imax = 9;
let jmax = 5;
let kmax = 3;
let a = make_block(imax, jmax, kmax, 0.0, 0.0);
let b = make_block(imax, jmax, kmax, PITCH_Y, 0.0);
let blocks = vec![a, b];
let pf = vec![periodic_face(
(0, [0, jmax - 1, 0], [imax - 1, jmax - 1, kmax - 1]),
(1, [0, 0, 0], [imax - 1, 0, kmax - 1]),
[[1, 0], [0, 1]],
)];
let (verified, mismatched) =
verify_translational_periodicity(&blocks, &pf, None, 'y', TOL);
assert_eq!(mismatched.len(), 0, "exact translational match must verify");
assert_eq!(verified.len(), 1);
let o = verified[0].orientation.as_ref().unwrap();
assert_eq!(o.permutation_index, 0);
assert_eq!(o.permutation_matrix, Some([[1, 0], [0, 1]]));
}
#[test]
fn translational_z_span_resolves_to_index_zero() {
let imax = 9;
let jmax = 5;
let kmax = 3;
let a = make_block(imax, jmax, kmax, 0.0, 0.0);
let blocks = vec![a];
let pf = vec![periodic_face(
(0, [0, 0, 0], [imax - 1, jmax - 1, 0]),
(0, [0, 0, kmax - 1], [imax - 1, jmax - 1, kmax - 1]),
[[1, 0], [0, 1]],
)];
let (verified, mismatched) =
verify_translational_periodicity(&blocks, &pf, None, 'z', TOL);
assert_eq!(mismatched.len(), 0);
assert_eq!(verified.len(), 1);
assert_eq!(
verified[0].orientation.as_ref().unwrap().permutation_index,
0
);
}
#[test]
fn translational_wrong_axis_does_not_match() {
let imax = 9;
let jmax = 5;
let kmax = 3;
let a = make_block(imax, jmax, kmax, 0.0, 0.0);
let b = make_block(imax, jmax, kmax, PITCH_Y, 0.0);
let blocks = vec![a, b];
let pf = vec![periodic_face(
(0, [0, jmax - 1, 0], [imax - 1, jmax - 1, kmax - 1]),
(1, [0, 0, 0], [imax - 1, 0, kmax - 1]),
[[1, 0], [0, 1]],
)];
let (verified, mismatched) =
verify_translational_periodicity(&blocks, &pf, None, 'z', TOL);
assert_eq!(verified.len(), 0, "axis mismatch must not silently pass");
assert_eq!(mismatched.len(), 1);
let _ = SPAN_Z; }