conspire/domain/vem/block/
mod.rs1pub 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}