diff -r 3dbc04100b09 -r 3b82a9d16307 src/mapping.rs --- a/src/mapping.rs Wed Oct 04 08:02:14 2023 -0500 +++ b/src/mapping.rs Wed Oct 04 08:59:29 2023 -0500 @@ -49,6 +49,13 @@ impl RealMapping for T where T : Mapping, Codomain = F> {} +/// A helper trait alias for referring to [`Mapping`]s from [`Loc`] to [`Loc`]. +pub trait RealVectorField +: Mapping, Codomain = Loc> {} + +impl RealVectorField for T +where T : Mapping, Codomain = Loc> {} + /// Trait for calculation the differential of `Self` as a mathematical function on `X`. pub trait Differentiable : Sized { @@ -144,8 +151,76 @@ } } + +/// Container for flattening [`Loc`]`` codomain of a [`Mapping`] to `F`. +pub struct FlattenedCodomain>> { + g : G, + _phantoms : PhantomData<(X, F)> +} + +impl>> Apply for FlattenedCodomain { + type Output = F; + #[inline] fn apply(&self, x : X) -> Self::Output { - self.g.differential(x) + self.g.apply(x).flatten1d() + } +} + +/// An auto-trait for constructing a [`FlattenCodomain`] structure for +/// flattening the codomain of a [`Mapping`] from [`Loc`]`` to `F`. +pub trait FlattenCodomain : Mapping> + Sized { + /// Flatten the codomain from [`Loc`]`` to `F`. + fn flatten_codomain(self) -> FlattenedCodomain { + FlattenedCodomain{ g : self, _phantoms : PhantomData } } } + +impl>> FlattenCodomain for G {} + + +/// Container for dimensional slicing [`Loc`]`` codomain of a [`Mapping`] to `F`. +pub struct SlicedCodomain>, const N : usize> { + g : G, + slice : usize, + _phantoms : PhantomData<(X, F)> +} + +impl>, const N : usize> Apply +for SlicedCodomain { + type Output = F; + + #[inline] + fn apply(&self, x : X) -> Self::Output { + let tmp : [F; N] = self.g.apply(x).into(); + // Safety: `slice_codomain` below checks the range. + unsafe { *tmp.get_unchecked(self.slice) } + } +} + +impl<'a, X, F : Copy, G : Mapping>, const N : usize> Apply<&'a X> +for SlicedCodomain { + type Output = F; + + #[inline] + fn apply(&self, x : &'a X) -> Self::Output { + let tmp : [F; N] = self.g.apply(x).into(); + // Safety: `slice_codomain` below checks the range. + unsafe { *tmp.get_unchecked(self.slice) } + } +} + +/// An auto-trait for constructing a [`FlattenCodomain`] structure for +/// flattening the codomain of a [`Mapping`] from [`Loc`]`` to `F`. +pub trait SliceCodomain : Mapping> + Sized { + /// Flatten the codomain from [`Loc`]`` to `F`. + fn slice_codomain(self, slice : usize) -> SlicedCodomain { + assert!(slice < N); + SlicedCodomain{ g : self, slice, _phantoms : PhantomData } + } +} + +impl>, const N : usize> +SliceCodomain +for G {} +