Skip to main content

conspire/geometry/mesh/connectivity/primitive/
mod.rs

1use crate::geometry::mesh::connectivity::base::FlatConnectivity;
2use crate::{geometry::mesh::connectivity::base::ConnectivityImpl, math::Sets};
3use std::{fmt::Debug, num::TryFromIntError, slice::Iter, vec::IntoIter};
4
5pub struct PrimitiveConnectivity<const M: usize, const N: usize>(Sets<Vec<[usize; N]>>);
6
7impl<const M: usize, const N: usize> From<Vec<[usize; N]>> for PrimitiveConnectivity<M, N> {
8    fn from(connectivity: Vec<[usize; N]>) -> Self {
9        PrimitiveConnectivity(Sets::from(connectivity))
10    }
11}
12
13impl<const M: usize, const N: usize> PrimitiveConnectivity<M, N> {
14    pub fn iter(&self) -> Iter<'_, [usize; N]> {
15        self.0.members().iter()
16    }
17}
18
19impl<'a, const M: usize, const N: usize> IntoIterator for &'a PrimitiveConnectivity<M, N> {
20    type Item = &'a [usize; N];
21    type IntoIter = Iter<'a, [usize; N]>;
22    fn into_iter(self) -> Self::IntoIter {
23        self.0.members().iter()
24    }
25}
26
27impl<const M: usize, const N: usize> IntoIterator for PrimitiveConnectivity<M, N> {
28    type Item = [usize; N];
29    type IntoIter = IntoIter<[usize; N]>;
30    fn into_iter(self) -> Self::IntoIter {
31        self.0.into_members().into_iter()
32    }
33}
34
35impl<const M: usize, const N: usize> ConnectivityImpl for PrimitiveConnectivity<M, N> {
36    fn is_empty(&self) -> bool {
37        self.0.members().is_empty()
38    }
39    fn element_numbers(&self) -> Option<&[usize]> {
40        self.0.numbers()
41    }
42    fn node_element_connectivity(&self) -> &[Vec<usize>] {
43        self.0.converse()
44    }
45    fn number_elements(&mut self, numbers: Vec<usize>) {
46        self.0.set_numbers(numbers)
47    }
48    fn number_of_elements(&self) -> usize {
49        self.0.members().len()
50    }
51    fn number_of_faces(&self) -> Option<usize> {
52        None
53    }
54    fn number_of_faces_per_element<I>(&self) -> Option<Vec<I>>
55    where
56        I: Debug + TryFrom<usize, Error = TryFromIntError>,
57    {
58        None
59    }
60    fn number_of_nodes_per_element(&self) -> Option<usize> {
61        Some(N)
62    }
63    fn number_of_nodes_per_face<I>(&self) -> Option<Vec<I>>
64    where
65        I: Debug + TryFrom<usize, Error = TryFromIntError>,
66    {
67        None
68    }
69    fn exodus_element_type(&self) -> &str {
70        match (M, N) {
71            (2, 3) => "tri3",
72            (2, 4) => "quad4",
73            (3, 4) => "tet4",
74            (3, 5) => "pyramid5",
75            (3, 6) => "wedge6",
76            (3, 8) => "hex8",
77            _ => panic!("unknown primitive element type: M={M}, N={N}"),
78        }
79    }
80    fn flat_connectivity<I>(&self) -> FlatConnectivity<I>
81    where
82        I: Debug + TryFrom<usize, Error = TryFromIntError>,
83    {
84        match self
85            .0
86            .members()
87            .iter()
88            .flat_map(|nodes| nodes.iter().map(|&node| (node + 1).try_into()))
89            .collect()
90        {
91            Ok(flat) => FlatConnectivity::Primitive(flat),
92            Err(_) => panic!(),
93        }
94    }
95}
96impl PrimitiveConnectivity<2, 3> {
97    pub fn add_edge_adjacency_triangular(&self, nodes_nodes: &mut [Vec<usize>]) {
98        for &[a, b, c] in self.0.members() {
99            nodes_nodes[a].push(b);
100            nodes_nodes[b].push(a);
101            nodes_nodes[b].push(c);
102            nodes_nodes[c].push(b);
103            nodes_nodes[c].push(a);
104            nodes_nodes[a].push(c);
105        }
106    }
107}
108
109impl PrimitiveConnectivity<2, 4> {
110    pub fn add_edge_adjacency(&self, nodes_nodes: &mut [Vec<usize>]) {
111        for &[a, b, c, d] in self.0.members() {
112            nodes_nodes[a].push(b);
113            nodes_nodes[b].push(a);
114            nodes_nodes[b].push(c);
115            nodes_nodes[c].push(b);
116            nodes_nodes[c].push(d);
117            nodes_nodes[d].push(c);
118            nodes_nodes[d].push(a);
119            nodes_nodes[a].push(d);
120        }
121    }
122}
123
124impl PrimitiveConnectivity<3, 4> {
125    pub fn add_edge_adjacency(&self, nodes_nodes: &mut [Vec<usize>]) {
126        for &[a, b, c, d] in self.0.members() {
127            for (u, v) in [(a, b), (a, c), (a, d), (b, c), (b, d), (c, d)] {
128                nodes_nodes[u].push(v);
129                nodes_nodes[v].push(u);
130            }
131        }
132    }
133}
134
135impl PrimitiveConnectivity<3, 5> {
136    pub fn add_edge_adjacency(&self, nodes_nodes: &mut [Vec<usize>]) {
137        for &[a, b, c, d, e] in self.0.members() {
138            for (u, v) in [
139                (a, b),
140                (b, c),
141                (c, d),
142                (d, a),
143                (a, e),
144                (b, e),
145                (c, e),
146                (d, e),
147            ] {
148                nodes_nodes[u].push(v);
149                nodes_nodes[v].push(u);
150            }
151        }
152    }
153}
154
155impl PrimitiveConnectivity<3, 6> {
156    pub fn add_edge_adjacency(&self, nodes_nodes: &mut [Vec<usize>]) {
157        for &[a, b, c, d, e, f] in self.0.members() {
158            for (u, v) in [
159                (a, b),
160                (b, c),
161                (c, a),
162                (d, e),
163                (e, f),
164                (f, d),
165                (a, d),
166                (b, e),
167                (c, f),
168            ] {
169                nodes_nodes[u].push(v);
170                nodes_nodes[v].push(u);
171            }
172        }
173    }
174}
175
176impl PrimitiveConnectivity<3, 8> {
177    pub fn add_edge_adjacency(&self, nodes_nodes: &mut [Vec<usize>]) {
178        for &[n0, n1, n2, n3, n4, n5, n6, n7] in self.0.members() {
179            for (u, v) in [
180                (n0, n1),
181                (n1, n2),
182                (n2, n3),
183                (n3, n0),
184                (n4, n5),
185                (n5, n6),
186                (n6, n7),
187                (n7, n4),
188                (n0, n4),
189                (n1, n5),
190                (n2, n6),
191                (n3, n7),
192            ] {
193                nodes_nodes[u].push(v);
194                nodes_nodes[v].push(u);
195            }
196        }
197    }
198}