Skip to main content

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

1#[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}