cmtool_core/model/
data.rs1use crate::{
4 coordinates::CartesianCoordinates,
5 ensight_gold::{
6 Part,
7 types::{ElementsType, VolumeElementTypes},
8 },
9};
10const C_MAX_NUMBER_VERTEX_PER_VOLUME_ELEM: usize = 20;
11
12#[derive(Default, Debug)]
13pub struct VolumeElementData {
14 global_id: Vec<Vec<usize>>,
15 vtype: Vec<VolumeElementTypes>, ids: Vec<usize>, vertices: Vec<usize>, pub xyz: Vec<CartesianCoordinates>, vertices_cell_id: Vec<usize>, nc_id: Vec<usize>, compartment_ids: Vec<usize>, }
27
28impl VolumeElementData {
29 pub fn get_vertex_per_element(&self, global_id: usize) -> usize {
30 ElementsType::VolumeElementType(self.vtype[global_id])
31 .node_count()
32 .try_into()
33 .unwrap()
34 }
35
36 pub fn get_element_and_nvertex(&self, global_id: usize) -> (VolumeElementTypes, usize) {
37 let element = self.vtype[global_id];
38 (
39 element,
40 ElementsType::VolumeElementType(element)
41 .node_count()
42 .try_into()
43 .unwrap(),
44 )
45 }
46
47 pub fn set_number_cid(&mut self, global_id: usize, n_cid: usize) {
48 self.nc_id[global_id] = n_cid;
49 }
50 pub fn get_number_cid(&self, global_id: usize) -> usize {
51 self.nc_id[global_id]
52 }
53
54 pub fn enumerate_number_id(&self) -> std::iter::Enumerate<std::slice::Iter<'_, usize>> {
55 self.nc_id.iter().enumerate()
56 }
57
58 pub fn resize(&mut self, n_part: usize, n_velement: usize, velement_detail: &[usize]) {
59 self.global_id
60 .resize(n_part * VolumeElementTypes::NUMBER_OF_TYPES, Vec::new());
61
62 for (vec, &new_len) in self.global_id.iter_mut().zip(velement_detail.iter()) {
63 vec.resize(new_len, 0);
64 }
65 self.vtype = Vec::with_capacity(n_velement);
68 self.ids.resize(n_velement, 0);
69 self.nc_id.resize(n_velement, 0);
70 self.vertices
71 .resize(n_velement * C_MAX_NUMBER_VERTEX_PER_VOLUME_ELEM, 0);
72 self.compartment_ids
73 .resize(n_velement * C_MAX_NUMBER_VERTEX_PER_VOLUME_ELEM, 0);
74 self.xyz.resize(n_velement, Default::default());
75 self.vertices_cell_id
77 .resize(n_velement * C_MAX_NUMBER_VERTEX_PER_VOLUME_ELEM, 0);
78 }
79
80 pub fn n_element(&self) -> usize {
81 self.ids.len()
82 }
83
84 pub fn set_list_compartment_id(&mut self, global_id: usize, k_vertex: usize, val: usize) {
85 self.compartment_ids[global_id * C_MAX_NUMBER_VERTEX_PER_VOLUME_ELEM + k_vertex] = val;
86 }
87
88 pub fn get_list_compartment_id(&self, global_id: usize, k_vertex: usize) -> usize {
89 self.compartment_ids[global_id * C_MAX_NUMBER_VERTEX_PER_VOLUME_ELEM + k_vertex]
90 }
91
92 pub fn set_global_id(
93 &mut self,
94 i_part: usize,
95 element_index: usize,
96 volume_element_id: usize,
97 val: usize,
98 ) {
99 self.global_id[VolumeElementTypes::NUMBER_OF_TYPES * i_part + element_index]
100 [volume_element_id] = val;
101 }
102
103 pub fn get_global_id(
104 &self,
105 i_part: usize,
106 element_index: usize,
107 volume_element_id: usize,
108 ) -> usize {
109 self.global_id[VolumeElementTypes::NUMBER_OF_TYPES * i_part + element_index]
110 [volume_element_id]
111 }
112
113 pub fn get_vertex_from_vol_global_id(
114 &self,
115 vol_element_global_id: usize,
116 k_vertex: usize,
117 ) -> usize {
118 self.vertices[vol_element_global_id * C_MAX_NUMBER_VERTEX_PER_VOLUME_ELEM + k_vertex]
119 }
120
121 fn set_vertex_from_vol_global_id(
122 &mut self,
123 vol_element_global_id: usize,
124 k_vertex: usize,
125 val: usize,
126 ) {
127 self.vertices[vol_element_global_id * C_MAX_NUMBER_VERTEX_PER_VOLUME_ELEM + k_vertex] = val;
128 }
129
130 pub fn fill_from_part(
131 &mut self,
132 global_volume_element_counter: usize,
133 part_it: (usize, &Part),
134 velem_detail: &[usize],
135 vertices: &VerticesData,
136 ) -> usize {
137 const N_NUMBER_TYPE: usize = VolumeElementTypes::NUMBER_OF_TYPES;
138 let (i_part, part) = part_it;
139
140 let mut local_vec_counter = global_volume_element_counter;
153
154 let i_part_base_index = i_part * N_NUMBER_TYPE;
158
159 for element in part.elements.iter() {
160 if let ElementsType::VolumeElementType(vol_elem) = element.etype {
161 let n_vertex = element.etype.node_count() as usize;
162 let element_index = vol_elem.to_index();
163 let n_volume_element = velem_detail[i_part_base_index + element_index];
164
165 let current_vertex_in_part = vertices.get_current_vertex_from_part(i_part);
166
167 for ve_id in 0..n_volume_element {
168 let ve_global_id = local_vec_counter;
169
170 local_vec_counter += 1;
171
172 self.set_global_id(i_part, element_index, ve_id, ve_global_id);
173
174 self.vtype.push(vol_elem);
175 self.ids[ve_global_id] = ve_id;
176
177 for k_vertex in 0..n_vertex {
178 let vtx = element.get_vertex(ve_id, k_vertex);
179 self.set_vertex_from_vol_global_id(
180 ve_global_id,
181 k_vertex,
182 current_vertex_in_part[vtx - 1],
183 );
184 }
185 }
186 }
187 }
188
189 local_vec_counter - global_volume_element_counter
190 }
191}
192
193#[derive(Default)]
195pub struct VerticesData {
196 ve_gid: Vec<Vec<usize>>, xyz: Vec<f64>, }
205
206impl VerticesData {
207 pub fn fill_from_part(
208 &mut self,
209 vertex_counter: usize,
210 vertex_detail: &[usize],
211 part_it: (usize, &Part),
212 ) -> usize {
213 let (i_part, part) = part_it;
214
215 let mut vertex_global_identifier = vertex_counter;
216 #[allow(clippy::explicit_counter_loop)]
217 for ve_id in 0..vertex_detail[i_part] {
218 self.ve_gid[i_part][ve_id] = vertex_global_identifier;
219 let offset = vertex_global_identifier * 3;
220 self.xyz[offset..offset + 3].copy_from_slice(part.get_vertex_coordinates_slice(ve_id));
221 vertex_global_identifier += 1;
222 }
223 vertex_detail[i_part]
224 }
225 pub fn resize(&mut self, n_vertices: usize, vertex_detail: &[usize]) {
226 self.ve_gid = vertex_detail
227 .iter()
228 .map(|n_vertex_p_part| vec![0; *n_vertex_p_part])
229 .collect();
230
231 self.xyz.resize(n_vertices * 3, 0.);
235 }
237
238 pub fn n_vertex(&self) -> usize {
239 self.xyz.len() / 3
240 }
241
242 fn get_current_vertex_from_part(&self, part_id: usize) -> &[usize] {
243 &self.ve_gid[part_id]
244 }
245
246 pub fn get_slice_xyz(&self, global_id: usize) -> &[f64; 3] {
247 let offset = global_id * 3;
248 self.xyz[offset..offset + 3]
249 .try_into()
250 .expect("Slice with exactly 3 elements")
251 }
252 pub fn get_radius_from_global_id(&self, vertex_global_id: usize) -> f64 {
253 let offset = vertex_global_id * 3;
254 self.xyz[offset].hypot(self.xyz[offset + 1])
255 }
256}