Skip to main content

conspire/domain/vem/block/
mod.rs

1pub mod element;
2pub mod solid;
3#[cfg(test)]
4mod test;
5
6use crate::{
7    domain::block::element::Elements,
8    geometry::mesh::PolytopalConnectivity,
9    math::TensorRank1Vec,
10    vem::{NodalReferenceCoordinates, block::element::VirtualElement},
11};
12use std::fmt::{self, Debug, Formatter};
13
14pub struct Block<C, F> {
15    constitutive_model: C,
16    connectivity: PolytopalConnectivity<3>,
17    elements: Vec<F>,
18    elements_nodes: Vec<Vec<usize>>,
19}
20
21impl<C, F> Block<C, F> {
22    fn constitutive_model(&self) -> &C {
23        &self.constitutive_model
24    }
25    fn elements(&self) -> &[F] {
26        &self.elements
27    }
28    fn element_coordinates<I, U>(
29        coordinates: &TensorRank1Vec<3, I, U>,
30        nodes: &[usize],
31    ) -> TensorRank1Vec<3, I, U> {
32        nodes
33            .iter()
34            .map(|&node| coordinates[node].clone())
35            .collect()
36    }
37    pub fn elements_faces(&self) -> &[Vec<usize>] {
38        self.connectivity.elements_faces()
39    }
40    fn elements_nodes(&self) -> &[Vec<usize>] {
41        &self.elements_nodes
42    }
43    pub fn faces_nodes(&self) -> &[Vec<usize>] {
44        self.connectivity.faces_nodes()
45    }
46}
47
48impl<C, F> Debug for Block<C, F> {
49    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
50        write!(
51            f,
52            "Block {{ constitutive model: {}, elements: [Virtual; {}] }}",
53            crate::domain::block::trimmed_type_name::<C>(),
54            self.elements().len()
55        )
56    }
57}
58
59impl<C, F> Elements for Block<C, F> {
60    fn node_neighbors(&self, neighbors: &mut [Vec<usize>]) {
61        crate::domain::block::add_node_neighbors(
62            self.elements_nodes().iter().map(|nodes| nodes.as_slice()),
63            neighbors,
64        )
65    }
66}
67
68impl<C, F> From<(C, PolytopalConnectivity<3>, &NodalReferenceCoordinates)> for Block<C, F>
69where
70    F: VirtualElement,
71{
72    fn from(
73        (constitutive_model, connectivity, coordinates): (
74            C,
75            PolytopalConnectivity<3>,
76            &NodalReferenceCoordinates,
77        ),
78    ) -> Self {
79        let faces_nodes = connectivity.faces_nodes();
80        let (elements, elements_nodes) = connectivity
81            .iter()
82            .map(|element_faces| {
83                let element_coordinates = element_faces
84                    .iter()
85                    .map(|&face| {
86                        faces_nodes[face]
87                            .iter()
88                            .map(|&node| coordinates[node].clone())
89                            .collect()
90                    })
91                    .collect();
92                let mut element_nodes = element_faces
93                    .iter()
94                    .flat_map(|&face| faces_nodes[face].clone())
95                    .collect::<Vec<_>>();
96                element_nodes.sort();
97                element_nodes.dedup();
98                (
99                    <F>::from((
100                        element_coordinates,
101                        element_faces,
102                        &element_nodes,
103                        faces_nodes,
104                    )),
105                    element_nodes,
106                )
107            })
108            .unzip();
109        Self {
110            constitutive_model,
111            connectivity,
112            elements,
113            elements_nodes,
114        }
115    }
116}
117
118impl<C, F>
119    From<(
120        C,
121        Vec<Vec<usize>>,
122        Vec<Vec<usize>>,
123        &NodalReferenceCoordinates,
124    )> for Block<C, F>
125where
126    F: VirtualElement,
127{
128    fn from(
129        (constitutive_model, elements_faces, faces_nodes, coordinates): (
130            C,
131            Vec<Vec<usize>>,
132            Vec<Vec<usize>>,
133            &NodalReferenceCoordinates,
134        ),
135    ) -> Self {
136        Self::from((
137            constitutive_model,
138            PolytopalConnectivity::from((elements_faces, faces_nodes)),
139            coordinates,
140        ))
141    }
142}