conspire/geometry/mesh/connectivity/polytopal/
mod.rs1#[cfg(feature = "netcdf")]
2use crate::geometry::mesh::connectivity::base::FlatConnectivity;
3use crate::{geometry::mesh::connectivity::base::ConnectivityImpl, math::Set};
4use std::{fmt::Debug, num::TryFromIntError, slice::Iter, vec::IntoIter};
5
6pub struct PolytopalConnectivity<const M: usize>(Set<Vec<Vec<usize>>>, Vec<Vec<usize>>);
7
8impl<const M: usize> From<(Vec<Vec<usize>>, Vec<Vec<usize>>)> for PolytopalConnectivity<M> {
9 fn from((elements_faces, faces_nodes): (Vec<Vec<usize>>, Vec<Vec<usize>>)) -> Self {
10 PolytopalConnectivity(Set::from(elements_faces), faces_nodes)
11 }
12}
13
14impl<const M: usize> PolytopalConnectivity<M> {
15 pub fn elements_faces(&self) -> &[Vec<usize>] {
16 self.0.members()
17 }
18 pub fn faces_nodes(&self) -> &[Vec<usize>] {
19 &self.1
20 }
21 pub fn iter(&self) -> Iter<'_, Vec<usize>> {
22 self.0.members().iter()
23 }
24}
25
26impl<'a, const M: usize> IntoIterator for &'a PolytopalConnectivity<M> {
27 type Item = &'a Vec<usize>;
28 type IntoIter = Iter<'a, Vec<usize>>;
29 fn into_iter(self) -> Self::IntoIter {
30 self.0.members().iter()
31 }
32}
33
34impl<const M: usize> IntoIterator for PolytopalConnectivity<M> {
35 type Item = Vec<usize>;
36 type IntoIter = IntoIter<Vec<usize>>;
37 fn into_iter(self) -> Self::IntoIter {
38 self.0.into_members().into_iter()
39 }
40}
41
42impl<const M: usize> ConnectivityImpl for PolytopalConnectivity<M> {
43 fn is_empty(&self) -> bool {
44 self.0.members().is_empty()
45 }
46 fn element_numbers(&self) -> Option<&[usize]> {
47 self.0.numbers()
48 }
49 fn node_element_connectivity(&self) -> &[Vec<usize>] {
50 unimplemented!()
51 }
52 fn number_elements(&mut self, numbers: Vec<usize>) {
53 self.0.set_numbers(numbers)
54 }
55 fn number_of_elements(&self) -> usize {
56 self.0.members().len()
57 }
58 fn number_of_faces(&self) -> Option<usize> {
59 Some(self.1.len())
60 }
61 fn number_of_faces_per_element<I>(&self) -> Option<Vec<I>>
62 where
63 I: Debug + TryFrom<usize, Error = TryFromIntError>,
64 {
65 if let Ok(num) = self
66 .0
67 .members()
68 .iter()
69 .map(|faces| faces.len().try_into())
70 .collect()
71 {
72 Some(num)
73 } else {
74 panic!()
75 }
76 }
77 fn number_of_nodes_per_element(&self) -> Option<usize> {
78 None
79 }
80 fn number_of_nodes_per_face<I>(&self) -> Option<Vec<I>>
81 where
82 I: Debug + TryFrom<usize, Error = TryFromIntError>,
83 {
84 if let Ok(num) = self.1.iter().map(|nodes| nodes.len().try_into()).collect() {
85 Some(num)
86 } else {
87 panic!()
88 }
89 }
90 #[cfg(feature = "netcdf")]
91 fn exodus_element_type(&self) -> &str {
92 match M {
93 2 => "nsided",
94 3 => "nfaced",
95 _ => panic!(),
96 }
97 }
98 #[cfg(feature = "netcdf")]
99 fn flat_connectivity<I>(&self) -> FlatConnectivity<I>
100 where
101 I: Debug + TryFrom<usize, Error = TryFromIntError>,
102 {
103 let elements_faces = self
104 .0
105 .members()
106 .iter()
107 .flat_map(|faces| faces.iter().map(|&f| (f + 1).try_into()))
108 .collect();
109 let faces_nodes = self
110 .1
111 .iter()
112 .flat_map(|nodes| nodes.iter().map(|&n| (n + 1).try_into()))
113 .collect();
114 match (elements_faces, faces_nodes) {
115 (Ok(elements_faces), Ok(faces_nodes)) => {
116 FlatConnectivity::Polytopal(elements_faces, faces_nodes)
117 }
118 _ => panic!(),
119 }
120 }
121}