use crate::mesh::{FaceKey, MapFaceToCells, Mesh};
use russell_lab::sort4;
use std::collections::HashMap;
pub(crate) fn extract_all_faces(mesh: &Mesh) -> MapFaceToCells {
assert_eq!(mesh.ndim, 3);
let mut faces = HashMap::new();
mesh.cells.iter().for_each(|cell| {
if cell.kind.ndim() == 3 {
for f in 0..cell.kind.nface() {
let mut face_key: FaceKey = if cell.kind.face_nnode() > 3 {
(
cell.points[cell.kind.face_node_id(f, 0)],
cell.points[cell.kind.face_node_id(f, 1)],
cell.points[cell.kind.face_node_id(f, 2)],
cell.points[cell.kind.face_node_id(f, 3)],
)
} else {
(
cell.points[cell.kind.face_node_id(f, 0)],
cell.points[cell.kind.face_node_id(f, 1)],
cell.points[cell.kind.face_node_id(f, 2)],
usize::MAX,
)
};
sort4(&mut face_key);
let data = faces.entry(face_key).or_insert(Vec::new());
data.push((cell.id, f));
}
}
});
faces
}
#[cfg(test)]
mod tests {
use super::extract_all_faces;
use crate::mesh::Samples;
#[test]
fn extract_all_faces_works() {
let mesh = Samples::two_hex8();
let faces = extract_all_faces(&mesh);
let mut keys: Vec<_> = faces.keys().collect();
keys.sort();
assert_eq!(
keys,
[
&(0, 1, 2, 3),
&(0, 1, 4, 5),
&(0, 3, 4, 7),
&(1, 2, 5, 6),
&(2, 3, 6, 7),
&(4, 5, 6, 7),
&(4, 5, 8, 9),
&(4, 7, 8, 11),
&(5, 6, 9, 10),
&(6, 7, 10, 11),
&(8, 9, 10, 11),
]
);
assert_eq!(faces.get(&(0, 1, 2, 3)).unwrap(), &[(0, 4)]);
assert_eq!(faces.get(&(0, 1, 4, 5)).unwrap(), &[(0, 2)]);
assert_eq!(faces.get(&(0, 3, 4, 7)).unwrap(), &[(0, 0)]);
assert_eq!(faces.get(&(1, 2, 5, 6)).unwrap(), &[(0, 1)]);
assert_eq!(faces.get(&(2, 3, 6, 7)).unwrap(), &[(0, 3)]);
assert_eq!(faces.get(&(4, 5, 6, 7)).unwrap(), &[(0, 5), (1, 4)]);
assert_eq!(faces.get(&(4, 5, 8, 9)).unwrap(), &[(1, 2)]);
assert_eq!(faces.get(&(4, 7, 8, 11)).unwrap(), &[(1, 0)]);
assert_eq!(faces.get(&(5, 6, 9, 10)).unwrap(), &[(1, 1)]);
assert_eq!(faces.get(&(6, 7, 10, 11)).unwrap(), &[(1, 3)]);
assert_eq!(faces.get(&(8, 9, 10, 11)).unwrap(), &[(1, 5)]);
}
#[test]
fn extract_all_faces_mixed_works() {
let mesh = Samples::mixed_shapes_3d();
let faces = extract_all_faces(&mesh);
let mut keys: Vec<_> = faces.keys().collect();
keys.sort();
assert_eq!(
keys,
[
&(0, 1, 2, 3),
&(0, 1, 4, 5),
&(0, 3, 4, 7),
&(1, 2, 5, 6),
&(2, 3, 6, 7),
&(2, 3, 6, usize::MAX),
&(2, 3, 8, usize::MAX),
&(2, 6, 8, usize::MAX),
&(3, 6, 8, usize::MAX),
&(4, 5, 6, 7),
]
);
assert_eq!(faces.get(&(0, 1, 2, 3)).unwrap(), &[(0, 4)]);
assert_eq!(faces.get(&(0, 1, 4, 5)).unwrap(), &[(0, 2)]);
assert_eq!(faces.get(&(0, 3, 4, 7)).unwrap(), &[(0, 0)]);
assert_eq!(faces.get(&(1, 2, 5, 6)).unwrap(), &[(0, 1)]);
assert_eq!(faces.get(&(2, 3, 6, 7)).unwrap(), &[(0, 3)]);
assert_eq!(faces.get(&(2, 3, 6, usize::MAX)).unwrap(), &[(1, 0)]);
assert_eq!(faces.get(&(2, 3, 8, usize::MAX)).unwrap(), &[(1, 2)]);
assert_eq!(faces.get(&(2, 6, 8, usize::MAX)).unwrap(), &[(1, 1)]);
assert_eq!(faces.get(&(3, 6, 8, usize::MAX)).unwrap(), &[(1, 3)]);
assert_eq!(faces.get(&(4, 5, 6, 7)).unwrap(), &[(0, 5)]);
}
}