conspire 0.7.1

The Rust interface to conspire.
Documentation
use crate::{
    geometry::mesh::{Connectivity, Mesh, Verdict},
    math::Tensor,
};

fn grid() -> (Vec<[usize; 8]>, Vec<[f64; 3]>) {
    let id = |i: usize, j: usize, k: usize| i + 3 * j + 9 * k;
    let mut coordinates = Vec::new();
    for k in 0..3 {
        for j in 0..3 {
            for i in 0..3 {
                coordinates.push([i as f64, j as f64, k as f64]);
            }
        }
    }
    let mut connectivity = Vec::new();
    for k in 0..2 {
        for j in 0..2 {
            for i in 0..2 {
                connectivity.push([
                    id(i, j, k),
                    id(i + 1, j, k),
                    id(i + 1, j + 1, k),
                    id(i, j + 1, k),
                    id(i, j, k + 1),
                    id(i + 1, j, k + 1),
                    id(i + 1, j + 1, k + 1),
                    id(i, j + 1, k + 1),
                ]);
            }
        }
    }
    (connectivity, coordinates)
}

fn mesh(connectivity: Vec<[usize; 8]>, coordinates: Vec<[f64; 3]>) -> Mesh<3> {
    Mesh::from((
        vec![Connectivity::Hexahedral(connectivity.into())],
        coordinates.into(),
    ))
}

fn minimum_scaled(mesh: &Mesh<3>) -> f64 {
    mesh.minimum_scaled_jacobians()
        .into_iter()
        .flatten()
        .fold(f64::INFINITY, f64::min)
}

#[test]
fn untangles_an_inverted_interior_node() {
    let (connectivity, mut coordinates) = grid();
    coordinates[13] = [1.0, 1.0, 2.5];
    let mut mesh = mesh(connectivity, coordinates);
    assert!(minimum_scaled(&mesh) < 0.0);
    mesh.untangle(50, 0.1, None);
    assert!(minimum_scaled(&mesh) > 0.0);
}

#[test]
fn leaves_a_valid_mesh_alone() {
    let (connectivity, coordinates) = grid();
    let mut mesh = mesh(connectivity, coordinates);
    let before: Vec<_> = mesh.coordinates().iter().cloned().collect();
    mesh.untangle(10, 0.1, None);
    mesh.coordinates()
        .iter()
        .zip(before)
        .for_each(|(now, was)| {
            assert_eq!(now, &was);
        });
}