Skip to main content

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

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