include!("msg_database_gen.rs");
use crate::debug;
use crate::mathfunc::Mat3I;
use crate::symmetry::{MagneticSymmetry, Symmetry};
use crate::MagneticType;
pub fn msgdb_get_magnetic_spacegroup_type(uni_number: usize) -> &'static MagneticSpacegroupType {
if uni_number > 0 && (uni_number as usize) < MAGNETIC_SPACEGROUP_TYPES.len() {
&MAGNETIC_SPACEGROUP_TYPES[uni_number as usize]
} else {
&MAGNETIC_SPACEGROUP_TYPES[0]
}
}
pub fn msgdb_get_uni_candidates(hall_number: usize) -> Option<[usize; 2]> {
if hall_number >= MAGNETIC_SPACEGROUP_HALL_MAPPING.len() {
return None;
}
let raw = MAGNETIC_SPACEGROUP_HALL_MAPPING[hall_number];
Some([raw[0] as usize, raw[1] as usize])
}
pub fn msgdb_get_spacegroup_operations(
uni_number: usize,
hall_number: usize,
) -> Option<MagneticSymmetry> {
let hall_number_offset = get_hall_number_offset(uni_number, hall_number)?;
let order = MAGNETIC_SPACEGROUP_OPERATION_INDEX[uni_number as usize][hall_number_offset as usize][0];
let start = MAGNETIC_SPACEGROUP_OPERATION_INDEX[uni_number as usize][hall_number_offset as usize][1];
debug::debug_print(format_args!(
"Load operations with UNI={}, hall={}: hall_number_offset={} order={} starts={}\n",
uni_number, hall_number, hall_number_offset, order, start
));
let mut sym = MagneticSymmetry::new(order as usize);
for i in 0..order {
let idx = (start + i) as usize;
let (rot, trans, timerev) = msgdb_get_magnetic_operation(idx);
sym.rot[i as usize] = rot;
sym.trans[i as usize] = trans;
sym.timerev[i as usize] = timerev;
}
Some(sym)
}
pub fn msgdb_get_std_transformations(
uni_number: usize,
hall_number: usize,
) -> Option<Symmetry> {
let hall_number_offset = get_hall_number_offset(uni_number, hall_number)?;
let mut sym = Symmetry::new(7);
sym.rot[0] = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
sym.trans[0] = [0.0; 3];
for i in 0..7 {
let enc = ALTERNATIVE_TRANSFORMATIONS[uni_number as usize][hall_number_offset as usize][i];
if enc == 0 {
sym.size = i + 1;
break;
}
let (tmat, origin_shift) = crate::spg_database::spgdb_decode_symmetry(enc);
sym.rot[i + 1] = tmat;
sym.trans[i + 1] = origin_shift;
}
Some(sym)
}
fn msgdb_get_magnetic_operation(op_number: usize) -> (Mat3I, [f64; 3], bool) {
let enc = MAGNETIC_SYMMETRY_OPERATIONS[op_number];
let timerev = (enc / 34012224) != 0;
let (rot, trans) = crate::spg_database::spgdb_decode_symmetry(enc % 34012224);
(rot, trans, timerev)
}
fn get_hall_number_offset(uni_number: usize, hall_number: usize) -> Option<usize> {
if uni_number == 0 || uni_number > 1651 {
return None;
}
let num_halls = MAGNETIC_SPACEGROUP_UNI_MAPPING[uni_number][0] as usize;
let first_hall = MAGNETIC_SPACEGROUP_UNI_MAPPING[uni_number][1] as usize;
let hall_number_offset = if hall_number > 0 && hall_number <= 530 {
if hall_number < first_hall {
return None;
}
hall_number - first_hall
} else if hall_number == 0 {
0
} else {
return None;
};
if hall_number_offset >= num_halls {
return None;
}
Some(hall_number_offset)
}