parse_monitors/report/
mod.rs

1//! Collection of routines to build the CFD report
2
3use crate::cfd::{self, BaselineError};
4use crate::MonitorsError;
5use rayon::prelude::*;
6use std::{
7    io,
8    marker::{Send, Sync},
9    path::PathBuf,
10};
11use strum::IntoEnumIterator;
12
13pub mod domeseeing;
14pub use domeseeing::DomeSeeingPart;
15pub mod htc;
16pub use htc::HTC;
17pub mod windloads;
18pub use windloads::WindLoads;
19
20#[derive(Debug, thiserror::Error)]
21pub enum ReportError {
22    #[error("failed to create wind loads report: {1:?}")]
23    Creating(#[source] io::Error, PathBuf),
24    #[error("failed to write wind loads report: {1:?}")]
25    Writing(#[source] io::Error, PathBuf),
26    #[error("wind loads CFD baseline error")]
27    Baseline(#[from] BaselineError),
28    #[error("wind loads glob error")]
29    Glob(#[from] glob::GlobError),
30    #[error("wind loads pattern error")]
31    Pattern(#[from] glob::PatternError),
32    #[error("wind loads monitor error")]
33    Monitors(#[from] MonitorsError),
34}
35
36pub trait Report<const CFD_YEAR: u32>: Send + Sync {
37    type Error: std::fmt::Debug;
38    fn part_name(&self) -> String;
39    fn chapter_section(
40        &self,
41        cfd_case: cfd::CfdCase<CFD_YEAR>,
42        ri_pic_idx: Option<usize>,
43    ) -> Result<String, Self::Error>;
44    fn chapter(
45        &self,
46        zenith_angle: cfd::ZenithAngle,
47        cfd_cases_subset: Option<&[cfd::CfdCase<CFD_YEAR>]>,
48    ) -> Result<(), Self::Error>;
49    fn part(&self) -> Result<(), Self::Error> {
50        cfd::ZenithAngle::iter()
51            .collect::<Vec<cfd::ZenithAngle>>()
52            .into_par_iter()
53            .for_each(|zenith_angle| {
54                println!(" - {} @ {:?}", self.part_name(), zenith_angle);
55                self.chapter(zenith_angle, None).unwrap();
56            });
57        Ok(())
58    }
59    fn part_with(
60        &self,
61        may_be_cfd_cases_subset: Option<&[cfd::CfdCase<CFD_YEAR>]>,
62    ) -> Result<(), Self::Error> {
63        if let Some(cfd_cases_subset) = may_be_cfd_cases_subset {
64            cfd::ZenithAngle::iter()
65                .collect::<Vec<cfd::ZenithAngle>>()
66                .into_par_iter()
67                .for_each(|zenith_angle| {
68                    // println!(" - {} @ {:?}", self.part_name(), zenith_angle);
69                    self.chapter(zenith_angle, Some(cfd_cases_subset)).unwrap();
70                });
71            Ok(())
72        } else {
73            self.part()
74        }
75    }
76}