cmtool_data/transitioner/
buffer.rs1use crate::{CMCase, DataError, FlowMapDescriptor, IterationState, RawData, rawdata};
4use std::{collections::HashMap, ops::Index, sync::Arc};
5
6pub struct RawStateBuffer(
7 FlowMapDescriptor,
8 Option<FlowMapDescriptor>,
9 HashMap<String, Vec<f64>>,
10);
11
12pub struct FlowMapBuffer(
13 Vec<FlowMapDescriptor>,
14 Option<Vec<FlowMapDescriptor>>,
15 Vec<HashMap<String, Vec<f64>>>,
16);
17
18impl FlowMapBuffer {
19 pub(crate) fn new_unique(RawStateBuffer(l, gas, m): RawStateBuffer) -> Self {
20 Self(vec![l], gas.map(|g| vec![g]), vec![m])
21 }
22
23 pub(crate) fn new(buffers: Vec<RawStateBuffer>) -> Option<Self> {
24 if buffers.is_empty() {
25 return None;
26 }
27
28 let mut liq = Vec::with_capacity(buffers.len());
29 let mut gas = Vec::with_capacity(buffers.len());
30 let mut misc = Vec::with_capacity(buffers.len());
31
32 let mut has_gas: Option<bool> = None;
33
34 for RawStateBuffer(l, g, m) in buffers {
35 liq.push(l);
36 misc.push(m);
37
38 match g {
39 Some(gs) => {
40 match has_gas {
41 None => has_gas = Some(true),
42 Some(false) => return None, _ => {}
44 }
45 gas.push(gs);
46 }
47 None => {
48 match has_gas {
49 None => has_gas = Some(false),
50 Some(true) => return None, _ => {}
52 }
53 }
54 }
55 }
56
57 let gas_out = match has_gas {
58 Some(true) => Some(gas),
59 Some(false) => None,
60 None => None,
61 };
62
63 Some(Self(liq, gas_out, misc))
64 }
65 pub fn into_state_buffer(self) -> Vec<Arc<IterationState>> {
66 match self.1 {
67 Some(gas) => self
68 .0
69 .into_iter()
70 .zip(gas)
71 .zip(self.2)
72 .map(|((liq, _gas), _misc)| Arc::new(IterationState::new(liq, Some(_gas), _misc)))
73 .collect(),
74 None => self
75 .0
76 .into_iter()
77 .zip(self.2)
78 .map(|(fd, misc)| Arc::new(IterationState::new(fd, None, misc)))
79 .collect(),
80 }
81 }
82}
83
84impl Index<usize> for FlowMapBuffer {
85 type Output = FlowMapDescriptor;
86
87 fn index(&self, index: usize) -> &Self::Output {
88 &self.0[index]
89 }
90}
91
92pub(super) fn read_descriptors(root: &str, case: &CMCase) -> Result<RawStateBuffer, DataError> {
93 let mut misc = HashMap::new();
94
95 if let Some(eps_path) = case.resolve(root, crate::CMAExportType::EnergyDissipation) {
97 let scalar_field = rawdata::RawDataScalar::read_raw(eps_path).ok_or(DataError::BadData)?;
98 let value: Vec<f64> = scalar_field.values.iter().map(|v| v.value).collect();
99 misc.insert(String::from("energy_dissipation"), value);
100 }
101
102 let liq_flow_path = case
103 .resolve(root, crate::CMAExportType::LiquidFlow)
104 .ok_or(DataError::BadData)?;
105 let liq_vol_path = case
106 .resolve(root, crate::CMAExportType::LiquidVolume)
107 .ok_or(DataError::BadData)?;
108
109 let liquid_descriptor = FlowMapDescriptor::from_path(liq_flow_path, liq_vol_path)?;
110
111 let gas_descriptor = match (
112 case.resolve(root, crate::CMAExportType::GasFlow),
113 case.resolve(root, crate::CMAExportType::GasVolume),
114 ) {
115 (Some(gas_flow), Some(gas_volume)) => {
116 Some(FlowMapDescriptor::from_path(gas_flow, gas_volume)?)
117 }
118 _ => None,
119 };
120
121 Ok(RawStateBuffer(liquid_descriptor, gas_descriptor, misc))
122}