#[cfg(test)]
mod test_cof3 {
use crate::cell::{Cell, TensorRank};
use crate::mathfunc::Mat3;
use crate::pointgroup::ptg_get_pointgroup;
#[test]
fn test_cof3_hardcoded() {
let lattice: Mat3 = [
[4.9790000916, -2.4895000458, 0.0 ], [0.0, 4.3119405647, 0.0 ], [0.0, 0.0, 13.1809997559 ], ];
let positions = [
[0.617923975, 0.0, 0.25 ],
[0.0, 0.617923975, 0.25 ],
[0.382076025, 0.382076025, 0.25 ],
[0.382076025, 0.0, 0.75 ],
[0.0, 0.382076025, 0.75 ],
[0.617923975, 0.617923975, 0.75 ],
[0.284590632, 0.333333343, 0.583333313],
[0.666666687, 0.951257288, 0.583333313],
[0.048742693, 0.715409338, 0.583333313],
[0.048742693, 0.333333343, 0.083333336],
[0.666666687, 0.715409338, 0.083333336],
[0.284590632, 0.951257288, 0.083333336],
[0.951257288, 0.666666687, 0.916666687],
[0.333333343, 0.284590632, 0.916666687],
[0.715409338, 0.048742693, 0.916666687],
[0.715409338, 0.666666687, 0.416666657],
[0.333333343, 0.048742693, 0.416666657],
[0.951257288, 0.284590632, 0.416666657],
[0.0, 0.0, 0.0 ],
[0.333333343, 0.666666687, 0.166666672],
[0.666666687, 0.333333343, 0.333333343],
[0.0, 0.0, 0.5 ],
[0.333333343, 0.666666687, 0.666666687],
[0.666666687, 0.333333343, 0.833333313],
];
let mut types = Vec::with_capacity(24);
for _ in 0..18 { types.push(9_i32); } for _ in 0..6 { types.push(24_i32); }
eprintln!("=== CoF₃ 手动构造 Cell ===");
eprintln!("n_atoms = {}", positions.len());
let a_col = [lattice[0][0], lattice[1][0], lattice[2][0]];
let b_col = [lattice[0][1], lattice[1][1], lattice[2][1]];
let len_a = (a_col[0]*a_col[0] + a_col[1]*a_col[1] + a_col[2]*a_col[2]).sqrt();
let len_b = (b_col[0]*b_col[0] + b_col[1]*b_col[1] + b_col[2]*b_col[2]).sqrt();
let dot = a_col[0]*b_col[0] + a_col[1]*b_col[1] + a_col[2]*b_col[2];
let gamma = (dot / (len_a * len_b)).acos() * 180.0 / std::f64::consts::PI;
eprintln!("|a| = {:.6}, |b| = {:.6}, γ = {:.4}°", len_a, len_b, gamma);
assert!((len_a - len_b).abs() < 1e-6, "a must equal b for hexagonal");
assert!((gamma - 120.0).abs() < 0.1, "γ must be 120° for hexagonal");
let mut cell = Cell::new(24, TensorRank::NoSpin);
cell.set_cell(&lattice, &positions, &types);
cell.aperiodic_axis = None;
let primitive = crate::primitive::prm_get_primitive(&cell, 1e-5, -1.0)
.expect("primitive failed");
eprintln!("primitive: n_atoms={}", primitive.size);
if let Some(ref prim_cell) = primitive.cell {
let sym = crate::symmetry::sym_get_operation(prim_cell, 1e-5, -1.0)
.expect("sym_get_operation failed");
eprintln!("symmetry ops on primitive cell: {}", sym.size);
let pointsym = crate::pointgroup::ptg_get_pointsymmetry(&sym.rot);
eprintln!("unique point symmetry rotations: {}", pointsym.size);
for (i, r) in pointsym.rot.iter().enumerate() {
let det = crate::mathfunc::mat_get_determinant_i3(r);
let trace = crate::mathfunc::mat_get_trace_i3(r);
eprintln!(" rot[{}]: det={}, trace={}", i, det, trace);
}
}
if let Some(ref prim_cell) = primitive.cell {
let p_lat = &prim_cell.lattice;
eprintln!("\n=== 约化后原胞结构 ===");
eprintln!("n_atoms = {}", prim_cell.size);
eprintln!("lattice = [{:?},", p_lat[0]);
eprintln!(" {:?},", p_lat[1]);
eprintln!(" {:?}]", p_lat[2]);
for j in 0..3 {
let len = (p_lat[0][j]*p_lat[0][j] + p_lat[1][j]*p_lat[1][j] + p_lat[2][j]*p_lat[2][j]).sqrt();
eprintln!(" |v{}| = {:.6}", j, len);
}
for j in 0..3 {
for k in (j+1)..3 {
let dot = p_lat[0][j]*p_lat[0][k] + p_lat[1][j]*p_lat[1][k] + p_lat[2][j]*p_lat[2][k];
let len_j = (p_lat[0][j]*p_lat[0][j] + p_lat[1][j]*p_lat[1][j] + p_lat[2][j]*p_lat[2][j]).sqrt();
let len_k = (p_lat[0][k]*p_lat[0][k] + p_lat[1][k]*p_lat[1][k] + p_lat[2][k]*p_lat[2][k]).sqrt();
let angle = (dot / (len_j * len_k)).acos() * 180.0 / std::f64::consts::PI;
eprintln!(" ∠(v{}, v{}) = {:.4}°", j, k, angle);
}
}
for i in 0..prim_cell.size {
eprintln!(" atom {:2}: pos=[{:.6}, {:.6}, {:.6}] type={}",
i+1, prim_cell.position[i][0], prim_cell.position[i][1],
prim_cell.position[i][2], prim_cell.types[i]);
}
}
let spg = crate::spacegroup::spa_search_spacegroup(&primitive, 0, 1e-5, -1.0)
.expect("spacegroup search failed");
eprintln!("\n=== 空间群结果 ===");
eprintln!(" Number: {}", spg.number);
eprintln!(" International: {}", spg.international_short.trim());
eprintln!(" International full:{}", spg.international.trim());
eprintln!(" Schoenflies: {}", spg.schoenflies.trim());
eprintln!(" Hall number: {}", spg.hall_number);
eprintln!(" Point group number:{}", spg.pointgroup_number);
let pg = ptg_get_pointgroup(spg.pointgroup_number);
eprintln!("\n=== 点群 ===");
eprintln!(" Number: {}", pg.number);
eprintln!(" Symbol: {}", pg.symbol.trim());
eprintln!(" Schoenflies:{}", pg.schoenflies.trim());
assert_eq!(spg.number, 167, "CoF₃ should be R-3c (#167)");
assert_eq!(spg.pointgroup_number, 20, "point group should be -3m");
}
#[test]
fn test_cof3_magnetic() {
let symprec = 1e-5;
let lattice: Mat3 = [
[4.9790000916, -2.4895000458, 0.0 ],
[0.0, 4.3119405647, 0.0 ],
[0.0, 0.0, 13.1809997559 ],
];
let positions = [
[0.617923975, 0.0, 0.25 ],
[0.0, 0.617923975, 0.25 ],
[0.382076025, 0.382076025, 0.25 ],
[0.382076025, 0.0, 0.75 ],
[0.0, 0.382076025, 0.75 ],
[0.617923975, 0.617923975, 0.75 ],
[0.284590632, 0.333333343, 0.583333313],
[0.666666687, 0.951257288, 0.583333313],
[0.048742693, 0.715409338, 0.583333313],
[0.048742693, 0.333333343, 0.083333336],
[0.666666687, 0.715409338, 0.083333336],
[0.284590632, 0.951257288, 0.083333336],
[0.951257288, 0.666666687, 0.916666687],
[0.333333343, 0.284590632, 0.916666687],
[0.715409338, 0.048742693, 0.916666687],
[0.715409338, 0.666666687, 0.416666657],
[0.333333343, 0.048742693, 0.416666657],
[0.951257288, 0.284590632, 0.416666657],
[0.0, 0.0, 0.0 ],
[0.333333343, 0.666666687, 0.166666672],
[0.666666687, 0.333333343, 0.333333343],
[0.0, 0.0, 0.5 ],
[0.333333343, 0.666666687, 0.666666687],
[0.666666687, 0.333333343, 0.833333313],
];
let mut types = Vec::with_capacity(24);
for _ in 0..18 { types.push(9_i32); }
for _ in 0..6 { types.push(24_i32); }
let mut moments = vec![[0.0; 3]; 24];
moments[18] = [0.0, 0.0, 1.0]; moments[19] = [0.0, 0.0, -1.0]; moments[20] = [0.0, 0.0, 1.0]; moments[21] = [0.0, 0.0, -1.0]; moments[22] = [0.0, 0.0, 1.0]; moments[23] = [0.0, 0.0, -1.0];
eprintln!("=== CoF₃ AFM [001] 磁性测试 ===");
let result = crate::spg_get_magnetic_dataset(
&lattice, &positions, &types, Some(&moments), symprec,
).expect("spg_get_magnetic_dataset must succeed");
eprintln!("{}", crate::spg_format_magnetic_symmetry(&result));
assert_eq!(result.spacegroup_number, 167, "non-mag: R-3c");
assert_eq!(result.uni_number, 1333, "UNI=1333");
assert_eq!(result.bns_number.trim(), "167.103");
assert_eq!(result.magnetic_type, crate::MagneticType::Ordinary);
eprintln!("UNI={}, BNS={}, type={:?}", result.uni_number, result.bns_number.trim(), result.magnetic_type);
}
}