use alloc::format;
use alloc::vec::Vec;
use deep_causality_topology::{LatticeComplex, Manifold};
use crate::solvers::dec::DecNsScalar;
use deep_causality_physics::PhysicsError;
use super::boundary_zone::BoundaryZone;
#[derive(Debug, Clone, Copy)]
pub struct SlipWall<const D: usize> {
wall_axis: usize,
max_side: bool,
}
impl<const D: usize> SlipWall<D> {
pub fn new(wall_axis: usize, max_side: bool) -> Result<Self, PhysicsError> {
if wall_axis >= D {
return Err(PhysicsError::DimensionMismatch(format!(
"SlipWall: wall axis {wall_axis} out of range for D = {D}"
)));
}
Ok(Self {
wall_axis,
max_side,
})
}
}
impl<const D: usize, R: DecNsScalar> BoundaryZone<D, R> for SlipWall<D> {
fn collect_slip_edges(
&self,
manifold: &Manifold<LatticeComplex<D, R>, R>,
out: &mut Vec<usize>,
) {
let complex = manifold.complex();
let pos = if self.max_side {
complex.shape()[self.wall_axis] - 1
} else {
0
};
for (idx, cell) in complex.iter_cells(1).enumerate() {
let axis = cell.orientation().trailing_zeros() as usize;
if axis != self.wall_axis && cell.position()[self.wall_axis] == pos {
out.push(idx);
}
}
}
}