conspire/geometry/mesh/connectivity/primitive/
mod.rs1use 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}