cmtool_core/ensight_gold/
variable.rs1use std::{io::ErrorKind, path::Path, str::FromStr, sync::Arc};
4
5use crate::ensight_gold::{
6 Reader,
7 geo::{Geometry, MeshElementType},
8 reader::EnsightGoldReader,
9 types::ElementsType,
10};
11
12pub(crate) trait VarTypeReader {
13 type VarType: Clone;
14 fn read_elements(
15 reader: &mut EnsightGoldReader,
16 element: &MeshElementType,
17 ) -> std::io::Result<Self::VarType>;
18}
19
20#[derive(Debug)]
21pub(crate) struct PerElementVariable<T: VarTypeReader> {
22 name: String,
27 pub part_id: Vec<u32>,
28 pub(super) data: Vec<Vec<T::VarType>>,
29 _marker: std::marker::PhantomData<T>,
30}
31
32impl<T: VarTypeReader> PerElementVariable<T> {
33 fn new() -> Self {
34 let data = Vec::new();
35 let part_id = Vec::new();
36 Self {
37 data,
38 part_id,
39 name: String::new(),
40 _marker: std::marker::PhantomData,
41 }
42 }
43 pub fn get_name(&self) -> &str {
44 &self.name
45 }
46 pub fn init(geometry: Arc<Geometry>, path: impl AsRef<Path>) -> std::io::Result<Self> {
47 let mut reader = Reader::new(path)?;
48 Self::read(&geometry, &mut reader)
49 }
50
51 fn read(geometry: &Geometry, reader: &mut EnsightGoldReader) -> std::io::Result<Self> {
52 let mut variable = Self::new();
54 variable.name = reader.get_line_string()?;
55
56 variable.data.resize(geometry.number_of_part(), Vec::new());
57 for data_in_part in &mut variable.data {
58 reader.check_lines_contains("part")?;
59
60 let id = reader.read_i32()?;
61 variable.part_id.push(id as u32);
62
63 if let Some(part) = geometry.get_part_by_id(id as u32) {
64 let n_elements = part.elements.len();
65 data_in_part.reserve(n_elements);
67
68 for element in &part.elements {
69 let element_type_name = reader.get_line_string()?;
70 if element_type_name.contains("undef") {
71 unimplemented!("Undef varaible per element");
72 }
73 if ElementsType::from_str(&element_type_name) == Ok(element.etype) {
76 data_in_part.push(T::read_elements(reader, element)?);
77 } else {
78 return Err(std::io::Error::new(
79 ErrorKind::Unsupported,
80 format!(
81 "Scalar and geometry part are not the same: {} vs {:?}",
82 element_type_name, element.etype
83 ),
84 ));
85 }
86 }
87 }
88 }
89 if reader.check_eof()? {
90 Ok(variable)
91 } else {
92 Err(std::io::Error::new(
93 ErrorKind::Unsupported,
94 "Reader should have been reached EOF".to_string(),
95 ))
96 }
97 }
98}