Skip to main content

molframe_spatial/model/
columns.rs

1//! Struct-of-arrays form of a pair list, ready to hand to column consumers.
2
3use super::NeighborPair;
4use crate::CrossPair;
5
6/// A pair list split into index columns and Euclidean distances.
7#[derive(Clone, Debug, Default, PartialEq)]
8pub struct PairColumns {
9    /// Lower atom index of every pair.
10    pub first: Vec<u32>,
11    /// Higher atom index of every pair.
12    pub second: Vec<u32>,
13    /// Euclidean separation of every pair, in ångström.
14    pub distance: Vec<f32>,
15}
16
17impl PairColumns {
18    /// Splits `pairs` into columns, taking the square root of each distance.
19    #[must_use]
20    pub fn from_pairs(pairs: &[NeighborPair]) -> Self {
21        let mut columns = Self {
22            first: Vec::with_capacity(pairs.len()),
23            second: Vec::with_capacity(pairs.len()),
24            distance: Vec::with_capacity(pairs.len()),
25        };
26        for pair in pairs {
27            columns.first.push(pair.first);
28            columns.second.push(pair.second);
29            columns.distance.push(pair.distance_squared.sqrt());
30        }
31        columns
32    }
33
34    /// Splits cross-set `pairs` into columns; indices stay local to each set.
35    #[must_use]
36    pub fn from_cross(pairs: &[CrossPair]) -> Self {
37        let mut columns = Self {
38            first: Vec::with_capacity(pairs.len()),
39            second: Vec::with_capacity(pairs.len()),
40            distance: Vec::with_capacity(pairs.len()),
41        };
42        for pair in pairs {
43            columns.first.push(pair.first);
44            columns.second.push(pair.second);
45            columns.distance.push(pair.distance_squared.sqrt());
46        }
47        columns
48    }
49}