#[cfg(test)]
mod test_la2nio4 {
use crate::cell::{Cell, TensorRank};
use crate::mathfunc::Mat3;
use crate::pointgroup::ptg_get_pointgroup;
#[test]
fn test_la2nio4_hardcoded() {
let lattice: Mat3 = [
[5.4994997978, 0.0, 0.0 ], [0.0, 5.4994997978, 0.0 ], [0.0, 0.0, 12.5052003860 ], ];
let positions = [
[0.992799997, 0.992799997, 0.363900006],
[0.492799997, 0.007200000, 0.136099994],
[0.007200000, 0.492799997, 0.136099994],
[0.507200003, 0.507200003, 0.363900006],
[0.007200000, 0.007200000, 0.636099994],
[0.507200003, 0.992799997, 0.863900006],
[0.992799997, 0.507200003, 0.863900006],
[0.492799997, 0.492799997, 0.636099994],
[0.000000000, 0.000000000, 0.000000000],
[0.500000000, 0.000000000, 0.500000000],
[0.000000000, 0.500000000, 0.500000000],
[0.500000000, 0.500000000, 0.000000000],
[0.750000000, 0.750000000, 0.015500000],
[0.250000000, 0.250000000, 0.484499991],
[0.250000000, 0.250000000, 0.984499991],
[0.750000000, 0.750000000, 0.515500009],
[0.750000000, 0.250000000, 0.000000000],
[0.250000000, 0.750000000, 0.500000000],
[0.250000000, 0.750000000, 0.000000000],
[0.750000000, 0.250000000, 0.500000000],
[0.031399999, 0.031399999, 0.177100003],
[0.531400025, 0.968599975, 0.322899997],
[0.968599975, 0.531400025, 0.322899997],
[0.468600005, 0.468600005, 0.177100003],
[0.968599975, 0.968599975, 0.822899997],
[0.468600005, 0.031399999, 0.677100003],
[0.031399999, 0.468600005, 0.677100003],
[0.531400025, 0.531400025, 0.822899997],
];
let mut types = Vec::with_capacity(28);
for _ in 0..8 { types.push(57_i32); } for _ in 0..4 { types.push(28_i32); } for _ in 0..16 { types.push(8_i32); }
eprintln!("=== La₂NiO₄ 手动构造 Cell ===");
eprintln!("n_atoms = {}", positions.len());
let a = [lattice[0][0], lattice[1][0], lattice[2][0]];
let b = [lattice[0][1], lattice[1][1], lattice[2][1]];
let c = [lattice[0][2], lattice[1][2], lattice[2][2]];
let len_a = (a[0]*a[0] + a[1]*a[1] + a[2]*a[2]).sqrt();
let len_b = (b[0]*b[0] + b[1]*b[1] + b[2]*b[2]).sqrt();
let len_c = (c[0]*c[0] + c[1]*c[1] + c[2]*c[2]).sqrt();
eprintln!("|a| = {:.6}, |b| = {:.6}, |c| = {:.6}", len_a, len_b, len_c);
assert!((len_a - len_b).abs() < 1e-6, "a must equal b for tetragonal");
let mut cell = Cell::new(28, 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!("\n原胞原子数: {}", primitive.size);
if let Some(ref prim_cell) = primitive.cell {
let p_lat = &prim_cell.lattice;
eprintln!("原胞晶格:");
eprintln!(" [{:>10.6}, {:>10.6}, {:>10.6}]", p_lat[0][0], p_lat[0][1], p_lat[0][2]);
eprintln!(" [{:>10.6}, {:>10.6}, {:>10.6}]", p_lat[1][0], p_lat[1][1], p_lat[1][2]);
eprintln!(" [{:>10.6}, {:>10.6}, {:>10.6}]", p_lat[2][0], p_lat[2][1], p_lat[2][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 lj = (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 lk = (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 / (lj * lk)).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]);
}
}
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!("\n原胞对称操作数: {}", sym.size);
let pointsym = crate::pointgroup::ptg_get_pointsymmetry(&sym.rot);
eprintln!("独特旋转操作数: {}", 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);
}
}
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, 138,
"La₂NiO₄ expected P4₂/ncm (#138), got #{}", spg.number);
assert_eq!(spg.hall_number, 422,
"expected Hall 422, got {}", spg.hall_number);
assert_eq!(spg.pointgroup_number, 15,
"expected point group 15 (4/mmm), got {}", spg.pointgroup_number);
assert_eq!(spg.international_short.trim(), "P4_2/ncm",
"expected P4_2/ncm, got '{}'", spg.international_short.trim());
assert_eq!(spg.schoenflies.trim(), "D4h^16",
"expected D4h^16, got '{}'", spg.schoenflies.trim());
assert_eq!(pg.number, 15, "point group number mismatch");
assert_eq!(pg.symbol.trim(), "4/mmm",
"expected 4/mmm, got '{}'", pg.symbol.trim());
assert_eq!(pg.schoenflies.trim(), "D4h",
"expected D4h, got '{}'", pg.schoenflies.trim());
assert_eq!(primitive.size, 28,
"primitive cell should have 28 atoms, got {}", primitive.size);
if let Some(ref prim_cell) = primitive.cell {
let p = &prim_cell.lattice;
let va2 = p[0][0]*p[0][0] + p[1][0]*p[1][0] + p[2][0]*p[2][0];
let vb2 = p[0][1]*p[0][1] + p[1][1]*p[1][1] + p[2][1]*p[2][1];
let vc2 = p[0][2]*p[0][2] + p[1][2]*p[1][2] + p[2][2]*p[2][2];
let va = va2.sqrt();
let vb = vb2.sqrt();
let vc = vc2.sqrt();
assert!((va - vb).abs() < 0.01, "tetragonal: |a| ≈ |b| expected");
assert!((va - 5.50).abs() < 0.1, "|a| ≈ 5.50, got {:.4}", va);
assert!((vc - 12.51).abs() < 0.1, "|c| ≈ 12.51, got {:.4}", vc);
let sym = crate::symmetry::sym_get_operation(prim_cell, 1e-5, -1.0)
.expect("sym_get_operation failed");
assert_eq!(sym.size, 16,
"expected 16 symmetry ops (D4h), got {}", sym.size);
let pointsym = crate::pointgroup::ptg_get_pointsymmetry(&sym.rot);
assert_eq!(pointsym.size, 16,
"expected 16 unique rotations (D4h), got {}", pointsym.size);
}
}
}