conspire/geometry/mesh/connectivity/polytopal/
mod.rs1use crate::geometry::mesh::connectivity::base::FlatConnectivity;
2use crate::{geometry::mesh::connectivity::base::ConnectivityImpl, math::Set};
3use std::{cell::OnceCell, fmt::Debug, num::TryFromIntError, slice::Iter, vec::IntoIter};
4
5pub struct PolytopalConnectivity<const M: usize>(
6 Set<Vec<Vec<usize>>>,
7 Vec<Vec<usize>>,
8 OnceCell<Vec<Vec<usize>>>,
9);
10
11impl<const M: usize> From<(Vec<Vec<usize>>, Vec<Vec<usize>>)> for PolytopalConnectivity<M> {
12 fn from((elements_faces, faces_nodes): (Vec<Vec<usize>>, Vec<Vec<usize>>)) -> Self {
13 PolytopalConnectivity(Set::from(elements_faces), faces_nodes, OnceCell::new())
14 }
15}
16
17impl<const M: usize> PolytopalConnectivity<M> {
18 pub fn add_edge_adjacency(&self, nodes_nodes: &mut [Vec<usize>]) {
19 for faces in self.0.members() {
20 for &face in faces {
21 let nodes = &self.1[face];
22 for (index, &u) in nodes.iter().enumerate() {
23 let v = nodes[(index + 1) % nodes.len()];
24 if u != v {
25 nodes_nodes[u].push(v);
26 nodes_nodes[v].push(u);
27 }
28 }
29 }
30 }
31 }
32 pub fn elements_faces(&self) -> &[Vec<usize>] {
33 self.0.members()
34 }
35 pub fn faces_nodes(&self) -> &[Vec<usize>] {
36 &self.1
37 }
38 pub fn iter(&self) -> Iter<'_, Vec<usize>> {
39 self.0.members().iter()
40 }
41}
42
43impl<'a, const M: usize> IntoIterator for &'a PolytopalConnectivity<M> {
44 type Item = &'a Vec<usize>;
45 type IntoIter = Iter<'a, Vec<usize>>;
46 fn into_iter(self) -> Self::IntoIter {
47 self.0.members().iter()
48 }
49}
50
51impl<const M: usize> IntoIterator for PolytopalConnectivity<M> {
52 type Item = Vec<usize>;
53 type IntoIter = IntoIter<Vec<usize>>;
54 fn into_iter(self) -> Self::IntoIter {
55 self.0.into_members().into_iter()
56 }
57}
58
59impl<const M: usize> ConnectivityImpl for PolytopalConnectivity<M> {
60 fn is_empty(&self) -> bool {
61 self.0.members().is_empty()
62 }
63 fn element_numbers(&self) -> Option<&[usize]> {
64 self.0.numbers()
65 }
66 fn node_element_connectivity(&self) -> &[Vec<usize>] {
67 self.2.get_or_init(|| {
68 let number_of_nodes = self.1.iter().flatten().max().map_or(0, |&node| node + 1);
69 let mut nodes_elements = vec![Vec::new(); number_of_nodes];
70 for (element, faces) in self.0.members().iter().enumerate() {
71 let mut nodes: Vec<usize> = faces
72 .iter()
73 .flat_map(|&face| self.1[face].iter().copied())
74 .collect();
75 nodes.sort_unstable();
76 nodes.dedup();
77 for node in nodes {
78 nodes_elements[node].push(element)
79 }
80 }
81 nodes_elements
82 })
83 }
84 fn number_elements(&mut self, numbers: Vec<usize>) {
85 self.0.set_numbers(numbers)
86 }
87 fn number_of_elements(&self) -> usize {
88 self.0.members().len()
89 }
90 fn number_of_faces(&self) -> Option<usize> {
91 Some(self.1.len())
92 }
93 fn number_of_faces_per_element<I>(&self) -> Option<Vec<I>>
94 where
95 I: Debug + TryFrom<usize, Error = TryFromIntError>,
96 {
97 if let Ok(num) = self
98 .0
99 .members()
100 .iter()
101 .map(|faces| faces.len().try_into())
102 .collect()
103 {
104 Some(num)
105 } else {
106 panic!()
107 }
108 }
109 fn number_of_nodes_per_element(&self) -> Option<usize> {
110 None
111 }
112 fn number_of_nodes_per_face<I>(&self) -> Option<Vec<I>>
113 where
114 I: Debug + TryFrom<usize, Error = TryFromIntError>,
115 {
116 if let Ok(num) = self.1.iter().map(|nodes| nodes.len().try_into()).collect() {
117 Some(num)
118 } else {
119 panic!()
120 }
121 }
122 fn exodus_element_type(&self) -> &str {
123 match M {
124 2 => "nsided",
125 3 => "nfaced",
126 _ => panic!(),
127 }
128 }
129 fn flat_connectivity<I>(&self) -> FlatConnectivity<I>
130 where
131 I: Debug + TryFrom<usize, Error = TryFromIntError>,
132 {
133 let elements_faces = self
134 .0
135 .members()
136 .iter()
137 .flat_map(|faces| faces.iter().map(|&f| (f + 1).try_into()))
138 .collect();
139 let faces_nodes = self
140 .1
141 .iter()
142 .flat_map(|nodes| nodes.iter().map(|&n| (n + 1).try_into()))
143 .collect();
144 match (elements_faces, faces_nodes) {
145 (Ok(elements_faces), Ok(faces_nodes)) => {
146 FlatConnectivity::Polytopal(elements_faces, faces_nodes)
147 }
148 _ => panic!(),
149 }
150 }
151}