treams_core/lattice/
saved.rs

1//! Canonical numerical lattice geometry, including optional reduced bases.
2//! treams-rs extension.
3
4use super::{BlochLattice, cell::Reduction};
5use crate::{
6    Error, Result,
7    saved::{Reader, Writer, read_f64},
8};
9
10fn invalid() -> Error {
11    Error::InvalidInput("invalid saved lattice geometry".into())
12}
13
14impl BlochLattice {
15    /// Fixed geometry size; absent reductions occupy zero-filled slots.
16    pub(crate) const STATE_SIZE: usize = 474;
17
18    pub(crate) fn write_state(&self, writer: &mut Writer) {
19        writer.usize(self.dim);
20        for &value in self
21            .direct
22            .iter()
23            .flatten()
24            .chain(self.reciprocal.iter().flatten())
25            .chain(&self.kpar)
26            .chain(std::iter::once(&self.measure))
27        {
28            writer.f64(value);
29        }
30        for reduction in [self.direct_reduction, self.reciprocal_reduction] {
31            writer.byte(u8::from(reduction.is_some()));
32            let reduction = reduction.unwrap_or(Reduction {
33                rows: [[0.0; 3]; 3],
34                dual: [[0.0; 3]; 3],
35            });
36            for &value in reduction
37                .rows
38                .iter()
39                .flatten()
40                .chain(reduction.dual.iter().flatten())
41            {
42                writer.f64(value);
43            }
44        }
45    }
46
47    pub(crate) fn read_state(reader: &mut Reader<'_>) -> Result<Self> {
48        let dim = reader.usize()?;
49        if !(1..=3).contains(&dim) {
50            return Err(invalid());
51        }
52        let mut direct = [[0.0; 3]; 3];
53        let mut reciprocal = [[0.0; 3]; 3];
54        let mut kpar = [0.0; 3];
55        let mut measure = 0.0;
56        for value in direct
57            .iter_mut()
58            .flatten()
59            .chain(reciprocal.iter_mut().flatten())
60            .chain(&mut kpar)
61            .chain(std::iter::once(&mut measure))
62        {
63            *value = read_f64(reader)?;
64        }
65        if measure <= 0.0 {
66            return Err(invalid());
67        }
68        let mut reductions = [None, None];
69        for reduction in &mut reductions {
70            let present = reader.byte()?;
71            if present > 1 {
72                return Err(invalid());
73            }
74            let mut rows = [[0.0; 3]; 3];
75            let mut dual = [[0.0; 3]; 3];
76            for value in rows.iter_mut().flatten().chain(dual.iter_mut().flatten()) {
77                *value = read_f64(reader)?;
78            }
79            *reduction = (present == 1).then_some(Reduction { rows, dual });
80        }
81        let [direct_reduction, reciprocal_reduction] = reductions;
82        Ok(Self {
83            dim,
84            direct,
85            reciprocal,
86            kpar,
87            measure,
88            direct_reduction,
89            reciprocal_reduction,
90        })
91    }
92}