use super::super::hall_symbol::LayerHallSymbol;
use super::layer_arithmetic_crystal_class::LayerArithmeticNumber;
use super::layer_centering::LayerCentering;
use super::layer_hall_symbol_database::iter_layer_hall_symbol_entry;
use crate::base::{Rotations, project_rotations};
#[derive(Debug)]
pub struct LayerPointGroupRepresentative {
pub generators: Rotations,
pub centering: LayerCentering,
}
impl LayerPointGroupRepresentative {
fn new(generators: Rotations, centering: LayerCentering) -> Self {
Self {
generators,
centering,
}
}
pub fn from_layer_arithmetic_crystal_class(arithmetic_number: LayerArithmeticNumber) -> Self {
let entry = iter_layer_hall_symbol_entry()
.find(|e| e.arithmetic_number == arithmetic_number)
.unwrap_or_else(|| {
panic!(
"no LayerHallSymbolEntry for arithmetic_number={}",
arithmetic_number
)
});
let layer_hall_symbol = LayerHallSymbol::from_hall_number(entry.hall_number)
.expect("LayerHallSymbol::from_hall_number for db entry");
Self::new(
project_rotations(layer_hall_symbol.generators()),
entry.centering,
)
}
pub fn primitive_generators(&self) -> Rotations {
let prim_trans_mat_inv = self.centering.linear().map(|e| e as f64);
let prim_trans_mat = self.centering.inverse();
self.generators
.iter()
.map(|g| {
let prim_g = prim_trans_mat_inv * g.map(|e| e as f64) * prim_trans_mat;
prim_g.map(|e| e.round() as i32)
})
.collect()
}
}
#[cfg(test)]
mod tests {
use super::super::layer_arithmetic_crystal_class::iter_layer_arithmetic_crystal_entry;
use super::*;
use crate::base::traverse;
#[test]
fn test_layer_point_group_representative() {
for entry in iter_layer_arithmetic_crystal_entry() {
let rep = LayerPointGroupRepresentative::from_layer_arithmetic_crystal_class(
entry.arithmetic_number,
);
let prim_gens = rep.primitive_generators();
let rotations = traverse(&prim_gens);
assert!(
!rotations.is_empty(),
"empty rotation group for layer arithmetic_number={}",
entry.arithmetic_number
);
}
}
}