1mod case;
4mod descriptors;
5mod flowmap;
6mod rawdata;
7mod states;
8#[cfg(test)]
9mod test_utils;
10mod transitioner;
11pub use case::{
12 CCMCaseInfo, CMCase, CMCaseJson, CMCaseReader, CMCaseWriter, DEFAULT_CASE_FILE_NAME, read_case,
13};
14use core::f64;
15pub use descriptors::{CMAExportType, CMExportType, PhaseCM};
16pub use flowmap::FlowMapDescriptor;
17pub use rawdata::{
18 FluxFileHeader, RawData, RawDataFlux, RawDataScalar, RawFlux, RawPhase, RawScalar,
19 ScalarFileHeader, ScalarValueType,
20};
21pub use states::*;
22use std::io;
23use thiserror::Error;
24pub use transitioner::*;
25
26#[derive(Error, Debug)]
31pub enum DataError {
32 #[error("I/O error occurred while handling the file: {0}")]
38 IO(#[from] io::Error),
39
40 #[error("Serialization/Deserialization error occurred")]
45 Serde,
46
47 #[error("An unknown error occurred during data operation")]
52 Unknown,
53
54 #[error("Data is illed-format")]
55 BadData,
56
57 #[error("Index {index} is out of range, {size} element(s) available")]
59 OutOfRange { index: usize, size: usize },
60}
61
62#[inline(always)]
63#[allow(unused)]
64fn linear_index_row_major(_n_row: usize, n_col: usize, i: usize, j: usize) -> usize {
65 i * n_col + j
66}
67
68#[inline(always)]
69#[allow(unused)]
70fn linear_index_col_major(n_row: usize, _n_col: usize, i: usize, j: usize) -> usize {
71 j * n_row + i
72}
73
74pub fn get_transitioner<T: FlowMapTransitioner>(root: &str) -> Result<T, DataError> {
76 let case_path = format!("{}/{}", root, DEFAULT_CASE_FILE_NAME);
77 let p = std::path::Path::new(&case_path);
78 let case = read_case(p)?;
79
80 T::from_case(root, &case)
82}
83
84pub fn get_min_residence_time<T: FlowMapTransitioner>(fmt: &T) -> f64 {
86 let n_states = fmt.size();
87 let mut min_all = f64::MAX;
88
89 for i_state in 0..n_states {
90 let state = fmt
91 .get_at(i_state)
92 .expect("Transitioner error: n_state != real stored states");
93
94 if state.liquid.out_flows.len() != state.liquid.volumes.len() {
95 panic!("Mismatched lengths between out_flows and volumes.");
96 }
97
98 let min_i = state
99 .liquid
100 .out_flows
101 .iter()
102 .zip(state.liquid.volumes.iter())
103 .map(|(&f, &v)| f / v)
104 .filter(|&x| x.is_finite())
105 .min_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Greater))
106 .expect("Should exist a minimum for the state");
107
108 min_all = f64::min(min_all, min_i);
109 }
110
111 min_all
112}