I am working on project which requires development of a spatial mesh data structure. I need to be able to support meshes of 2- or 3-dimensional elements with corresponding 1- or 2-dimensional interfaces which join neighboring elements. Every element in the mesh is guaranteed to be represented by geometries which share a common spatial dimension.

Using the knowledge that if I have an element of dimension `N`

, the dimension of the interface will be `N - 1`

, and the fact that `N`

will only over be 2 or 3, I am looking for a way to represent the spatial dimensions `N`

and `N - 1`

without have to revert to the nightly compiler and enabling the `generic_const_exprs`

feature.

Currently the mesh structure looks something akin to

```
use nalgebra::Point;
pub struct Mesh<const N: usize> {
points: Vec<Point<f64, N>>,
elements: Vec<ElementData>,
interfaces: Vec<InterfaceData>,
}
```

I have need to sometimes transfer down to the `N - 1`

dimension. For example, I may need to represent interfaces in their true dimension as in the following `as_parametric`

function

```
// `N` is the mesh/element dimension
struct SomeInterfaceType<'a, const N: usize> {
points: &'a [Point<f64, N>],
}
impl<'a, const N: usize> SomeInterfaceType<'a, N> {
/// Transfer a point on the interface to a `N - 1`-dimensional parametric coordinate.
///
/// Returns `None` if `point` is not on the interface.
// requires `feature(generic_const_exprs)`
fn try_to_parametric(&self, point: &Point<f64, N>) -> Option<Point<f64, { N - 1 }>>{
// ...
}
}
```

I am aware of the possibility to represent the spatial dimension with a generic type instead of a const generic by using the `typenum`

and `nalgebra`

crates. However, in this case, every `Point`

object would become an `OPoint`

which would require including a `DefaultAllocator: Allocator<f64, D>`

bound everywhere the dimension type is used which can add unwanted technical debt when applied throughout the code base.

Currently, I am using a combination of const generics and generic types to solve this problem, as in

```
use nalgebra::{Const, DimName, DimNameSub, U1};
trait Dim: DimName + DimNameSub<U1> {}
impl Dim for Const<2> {}
impl Dim for Const<3> {}
// e.g. LessOne<Const<3>> == Const<2>
type LessOne<D> = <D as DimNameSub<U1>>::Output;
```

Can anyone imagine a more succinct way of representing the spatial dimension?

Thanks for your help and for reading my wall of text!