Skip to main content

cmtool_core/ensight_gold/
variable.rs

1// SPDX-License-Identifier: GPL-3.0-or-later
2
3use 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    // data: Vec<f32>,
23    // parts: usize,
24    // mesh_element_types: usize,
25    // mesh_cells: usize,
26    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        // reader.ignore_line()?; //description
53        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                // println!("{}", n_elements);
66                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                    // let _ = reader.read_f32()?; //undef
74                    // println!("{}", element_type_name);
75                    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}