cmtool_core/model/
vectors.rs1use crate::{
4 CoreError,
5 ensight_gold::{self, types::ElementsType},
6 model::{CMGeometry, Scalar},
7};
8
9pub struct Vector {
10 value_in_vo: Vec<cmtool_data::ScalarValueType>,
11}
12
13impl Vector {
14 pub fn get_slice_xyz(&self, global_id: usize) -> &[f64; 3] {
15 let offset = global_id * 3;
16 self.value_in_vo[offset..offset + 3]
17 .try_into()
18 .expect("Slice with exactly 3 elements")
19 }
20
21 pub fn scale_by(self, a: Scalar) -> Result<Self, CoreError> {
22 let values: Vec<cmtool_data::ScalarValueType> = self
31 .value_in_vo
32 .chunks(3)
33 .zip(&a.value_in_vo)
34 .flat_map(|(triplet, &s)| triplet.iter().map(move |&v| v * s))
35 .collect();
36 Ok(Self {
37 value_in_vo: values,
38 })
39 }
40
41 pub(crate) fn from_scalar(
42 scalars: [ensight_gold::scalar::ScalarField; 3],
43 geometry: &CMGeometry,
44 eg_geometry: &ensight_gold::Geometry,
45 ) -> Result<Self, CoreError> {
46 let functor = |i_part, i_e, volume_element_id| {
47 [
48 scalars[0].get_value(i_part, i_e, volume_element_id) as f64,
49 scalars[1].get_value(i_part, i_e, volume_element_id) as f64,
50 scalars[2].get_value(i_part, i_e, volume_element_id) as f64,
51 ]
52 };
53 Ok(Self::from_xyz(geometry, eg_geometry, functor))
54 }
55
56 fn from_xyz(
57 geometry: &CMGeometry,
58 eg_geometry: &ensight_gold::Geometry,
59 f: impl Fn(usize, usize, usize) -> [cmtool_data::ScalarValueType; 3],
60 ) -> Self {
61 let mut value_in_vo: Vec<cmtool_data::ScalarValueType> =
62 vec![0.; 3 * geometry.volume_elements.n_element()];
63 for (i_part, part) in eg_geometry.parts.iter().enumerate() {
64 for (i_e, element) in part.elements.iter().enumerate() {
65 if let ElementsType::VolumeElementType(vetype) = element.etype {
66 let element_index = vetype.to_index();
67
68 for volume_element_id in 0..element.n_elements {
69 let volume_element_global_id = geometry.volume_elements.get_global_id(
70 i_part,
71 element_index,
72 volume_element_id,
73 );
74 let offset = 3 * volume_element_global_id;
75 value_in_vo[offset..offset + 3].copy_from_slice(&f(
76 i_part,
77 i_e,
78 volume_element_id,
79 ));
80 }
81 }
82 }
83 }
84
85 Self { value_in_vo }
86 }
87
88 pub(crate) fn new(
91 eg_vector: ensight_gold::vectors::VectorField,
92 geometry: &CMGeometry,
93 eg_geometry: &ensight_gold::Geometry,
94 ) -> Self {
95 let functor =
96 |i_part, i_e, volume_element_id| eg_vector.get_xyz(i_part, i_e, volume_element_id);
97 Self::from_xyz(geometry, eg_geometry, functor)
98 }
99}
100
101