treams_core/smatrix/array/
saved.rs

1//! Fixed saved state for periodic-array radiation.
2//!
3//! treams-rs extension.
4
5use super::FromArrayResidual;
6use crate::{
7    Result,
8    saved::{Reader, SavedState, Writer},
9    smatrix::saved::{invalid, product, read_matrix, total, write_matrix},
10};
11
12impl FromArrayResidual {
13    /// Byte count for array radiation state with multipole and plane-wave counts.
14    pub fn state_size(multipoles: usize, modes: usize) -> Result<usize> {
15        if multipoles == 0 || modes == 0 {
16            return Err(invalid());
17        }
18        total(&[
19            16,
20            product(&[16, multipoles, multipoles])?,
21            product(&[96, multipoles, modes])?,
22        ])
23    }
24}
25
26impl SavedState for FromArrayResidual {
27    fn save_state(&self) -> Result<Vec<u8>> {
28        let (multipoles, modes) = self.input_shape();
29        let mut writer = Writer::new(Self::state_size(multipoles, modes)?);
30        writer.usize(multipoles);
31        writer.usize(modes);
32        write_matrix(&mut writer, &self.response);
33        for matrix in self.channels.iter().chain(&self.scattered) {
34            write_matrix(&mut writer, matrix);
35        }
36        Ok(writer.finish())
37    }
38
39    fn from_state(bytes: &[u8]) -> Result<Self> {
40        let mut reader = Reader::new(bytes);
41        let (multipoles, modes) = (reader.usize()?, reader.usize()?);
42        if bytes.len() != Self::state_size(multipoles, modes)? {
43            return Err(invalid());
44        }
45        let response = read_matrix(&mut reader, multipoles, multipoles)?;
46        let mut read = || read_matrix(&mut reader, multipoles, modes);
47        let channels = [read()?, read()?, read()?, read()?];
48        let scattered = [read()?, read()?];
49        reader.finish()?;
50        Ok(Self {
51            response,
52            channels,
53            scattered,
54        })
55    }
56}