conspire 0.7.1

The Rust interface to conspire.
Documentation
#[cfg(test)]
mod test;

use super::Incidence;
use crate::{
    geometry::{Coordinate, mesh::Mesh},
    math::Scalar,
};

impl<const D: usize> Mesh<D> {
    pub fn smart_laplace_smooth(&mut self, iterations: usize, scale: Scalar) {
        let number_of_nodes = self.number_of_nodes();
        let neighbors = self.node_node_connectivity().to_vec();
        let incidence = Incidence::of(self);
        let coordinates = self.coordinates.members_mut();
        for _ in 0..iterations {
            for node in 0..number_of_nodes {
                if neighbors[node].is_empty() {
                    continue;
                }
                let before = incidence.minimum_scaled_jacobian(node, coordinates);
                let original = coordinates[node].clone();
                let centroid = neighbors[node]
                    .iter()
                    .map(|&neighbor| &coordinates[neighbor])
                    .sum::<Coordinate<D>>()
                    / (neighbors[node].len() as Scalar);
                coordinates[node] += (centroid - &original) * scale;
                let after = incidence.minimum_scaled_jacobian(node, coordinates);
                if after < before {
                    coordinates[node] = original;
                }
            }
        }
    }
}