Skip to main content

neco_mesh/
types.rs

1/// 1D edge mesh.
2#[derive(Debug, Clone)]
3pub struct EdgeMesh {
4    pub nodes: Vec<[f64; 2]>,
5    pub edges: Vec<[usize; 2]>,
6    pub lengths: Vec<f64>,
7    pub arc_params: Vec<f64>,
8}
9
10/// 2D triangle mesh.
11#[derive(Debug, Clone)]
12pub struct TriMesh2D {
13    pub nodes: Vec<[f64; 2]>,
14    pub triangles: Vec<[usize; 3]>,
15}
16
17/// 3D tetrahedral mesh.
18#[derive(Debug, Clone)]
19pub struct TetMesh3D {
20    pub nodes: Vec<[f64; 3]>,
21    pub tetrahedra: Vec<[usize; 4]>,
22}
23
24impl TetMesh3D {
25    pub fn n_nodes(&self) -> usize {
26        self.nodes.len()
27    }
28
29    pub fn n_tetrahedra(&self) -> usize {
30        self.tetrahedra.len()
31    }
32
33    pub fn tet_volume(&self, tet_idx: usize) -> f64 {
34        let [i0, i1, i2, i3] = self.tetrahedra[tet_idx];
35        tet_volume_from_nodes(&self.nodes, &[i0, i1, i2, i3])
36    }
37
38    pub fn total_volume(&self) -> f64 {
39        (0..self.n_tetrahedra()).map(|i| self.tet_volume(i)).sum()
40    }
41}
42
43/// Immersed boundary mesh with per-tetrahedron fill fractions.
44#[derive(Debug, Clone)]
45pub struct ImmersedMesh {
46    pub mesh: TetMesh3D,
47    pub fill_fractions: Vec<f64>,
48}
49
50fn tet_volume_from_nodes(nodes: &[[f64; 3]], tet: &[usize; 4]) -> f64 {
51    let p0 = nodes[tet[0]];
52    let p1 = nodes[tet[1]];
53    let p2 = nodes[tet[2]];
54    let p3 = nodes[tet[3]];
55
56    let a = [p1[0] - p0[0], p1[1] - p0[1], p1[2] - p0[2]];
57    let b = [p2[0] - p0[0], p2[1] - p0[1], p2[2] - p0[2]];
58    let c = [p3[0] - p0[0], p3[1] - p0[1], p3[2] - p0[2]];
59
60    let det = a[0] * (b[1] * c[2] - b[2] * c[1]) - a[1] * (b[0] * c[2] - b[2] * c[0])
61        + a[2] * (b[0] * c[1] - b[1] * c[0]);
62    det.abs() / 6.0
63}