ak_core/geometry/
structure.rs1use crate::geometry::{AtomicNumber, Cell, Pbc, StructureView};
2
3#[derive(Clone)]
4pub struct Structure {
5 pub positions: Vec<[f64; 3]>,
6 pub numbers: Vec<AtomicNumber>,
7 pub cell: Cell,
8 pub pbc: Pbc,
9}
10
11impl Structure {
12 pub fn new(
13 positions: Vec<[f64; 3]>,
14 numbers: Vec<i32>,
15 cell: [[f64; 3]; 3],
16 pbc: [bool; 3],
17 ) -> Self {
18 assert_eq!(positions.len(), numbers.len());
19
20 let atomic_numbers = numbers
21 .iter()
22 .map(|z| AtomicNumber::new(*z).expect("Atomic number was not in [1, 110]"))
23 .collect();
24
25 Self {
26 positions,
27 numbers: atomic_numbers,
28 cell: { Cell::new(cell) },
29 pbc: { Pbc::new(pbc) },
30 }
31 }
32
33 pub fn view(&self) -> StructureView<'_> {
34 StructureView {
35 positions: &self.positions,
36 numbers: &self.numbers,
37 cell: self.cell,
38 pbc: self.pbc,
39 }
40 }
41
42 pub fn from_xyz_reader<R: std::io::BufRead>(r: R) -> Self {
43 crate::io::read_xyz(r)
44 }
45
46 pub fn from_xyz_file<P: AsRef<std::path::Path>>(path: P) -> Self {
47 let f = std::fs::File::open(path).unwrap();
48 let r = std::io::BufReader::new(f);
49 Self::from_xyz_reader(r)
50 }
51}
52
53#[cfg(test)]
54mod test {
55 use crate::Structure;
56
57 fn test_structure() -> Structure {
58 let positions = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]].to_vec();
59 let numbers = [1, 1].to_vec();
60 let cell = [[10.0, 0.0, 0.0], [0.0, 10.0, 0.0], [0.0, 0.0, 10.0]];
61 let pbc = [false, false, false];
62 Structure::new(positions.clone(), numbers.clone(), cell, pbc)
63 }
64
65 #[test]
66 fn test_positions() {
67 let structure = test_structure();
68 let positions = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]].to_vec();
69 assert_eq!(structure.positions, positions)
70 }
71
72 #[test]
73 fn test_view() {
74 let structure = test_structure();
75 let view = structure.view();
76 let positions = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]].to_vec();
77 assert_eq!(view.positions, positions)
78 }
79}