salva3d/kernel/
kernel.rs

1use crate::math::{Point, Real, Vector};
2use approx::AbsDiffEq;
3use na::Unit;
4
5/// Kernel functions for performing approximations within the PBF/SPH methods.
6pub trait Kernel: Send + Sync {
7    /// Evaluates the kernel for the given scalar `r` and the reference support length `h`.
8    fn scalar_apply(r: Real, h: Real) -> Real;
9    /// Evaluates the kernel derivative for the given scalar `r` and the reference support length `h`.
10    fn scalar_apply_diff(r: Real, h: Real) -> Real;
11
12    /// Evaluate the kernel for the given vector.
13    fn apply(v: Vector<Real>, h: Real) -> Real {
14        Self::scalar_apply(v.norm(), h)
15    }
16
17    /// Differential wrt. the coordinates of `v`.
18    fn apply_diff(v: Vector<Real>, h: Real) -> Vector<Real> {
19        if let Some((dir, norm)) = Unit::try_new_and_get(v, Real::default_epsilon()) {
20            *dir * Self::scalar_apply_diff(norm, h)
21        } else {
22            Vector::zeros()
23        }
24    }
25
26    /// Evaluate the kernel for the vector equal to `p1 - p2`.
27    fn points_apply(p1: &Point<Real>, p2: &Point<Real>, h: Real) -> Real {
28        Self::apply(p1 - p2, h)
29    }
30
31    /// Differential wrt. the coordinates of `p1`.
32    fn points_apply_diff1(p1: &Point<Real>, p2: &Point<Real>, h: Real) -> Vector<Real> {
33        Self::apply_diff(p1 - p2, h)
34    }
35
36    /// Differential wrt. the coordinates of `p2`.
37    fn points_apply_diff2(p1: &Point<Real>, p2: &Point<Real>, h: Real) -> Vector<Real> {
38        -Self::apply_diff(p1 - p2, h)
39    }
40}