cmtool_core/model/
scalar.rs1use std::ops::Index;
4
5use cmtool_data::ScalarValueType;
6
7use crate::{
8 CoreError,
9 ensight_gold::{self, types::ElementsType},
10 model::CMGeometry,
11};
12
13pub struct Scalar {
14 pub(crate) value_in_vo: Vec<cmtool_data::ScalarValueType>,
15 pub name: String,
16}
17
18impl Scalar {
19 pub(crate) fn new(
20 eg_scalar: ensight_gold::scalar::ScalarField,
21 geometry: &CMGeometry,
22 eg_geometry: &ensight_gold::Geometry,
23 ) -> Self {
24 let mut value_in_vo: Vec<cmtool_data::ScalarValueType> =
25 vec![0.; geometry.volume_elements.n_element()];
26
27 for (i_part, part) in eg_geometry.parts.iter().enumerate() {
28 for (i_e, element) in part.elements.iter().enumerate() {
29 if let ElementsType::VolumeElementType(vetype) = element.etype {
30 let element_index = vetype.to_index();
31
32 for volume_element_id in 0..element.n_elements {
33 let volume_element_global_id = geometry.volume_elements.get_global_id(
34 i_part,
35 element_index,
36 volume_element_id,
37 );
38 value_in_vo[volume_element_global_id] =
39 eg_scalar.get_value(i_part, i_e, volume_element_id).into();
40 }
41 }
42 }
43 }
44
45 Self {
46 value_in_vo,
47 name: eg_scalar.get_name().to_string(),
48 }
49 }
50
51 pub fn element_wise(self, a: &Self) -> Result<Self, CoreError> {
52 if a.value_in_vo.len() != self.value_in_vo.len() {
53 return Err(CoreError::Custom(format!(
54 "Bad size for scalar scaling {} vs {} ",
55 self.value_in_vo.len(),
56 a.value_in_vo.len()
57 )));
58 }
59
60 let values: Vec<cmtool_data::ScalarValueType> = a
61 .value_in_vo
62 .iter()
63 .zip(&self.value_in_vo)
64 .map(|(a, b)| a * b)
65 .collect();
66 Ok(Self {
67 value_in_vo: values,
68 name: format!("{} per {} scalar ", self.name, a.name),
69 })
70 }
71
72 pub fn scalar_shift(self, lambda: ScalarValueType) -> Self {
73 let value_in_vo = self.value_in_vo.iter().map(|i| lambda - i).collect();
74
75 Self {
76 value_in_vo,
77 name: format!("{} shifted by {} ", self.name, lambda),
78 }
79 }
80}
81
82impl Index<usize> for Scalar {
83 type Output = cmtool_data::ScalarValueType;
84
85 fn index(&self, index: usize) -> &Self::Output {
86 #[cfg(debug_assertions)]
87 {
88 &self.value_in_vo[index]
90 }
91
92 #[cfg(not(debug_assertions))]
93 unsafe {
94 self.value_in_vo.get_unchecked(index)
96 }
97 }
98}
99
100