use cartan_dec::mesh::FlatMesh;
use cartan_dec::Operators;
use cartan_manifolds::euclidean::Euclidean;
use volterra_core::ActiveNematicParams;
use volterra_dec::QFieldDec;
use volterra_solver::run_dry_active_nematic_dec;
#[test]
fn dec_dry_nematic_order_grows() {
let mesh = FlatMesh::unit_square_grid(8);
let manifold = Euclidean::<2>;
let ops = Operators::from_mesh(&mesh, &manifold);
let mut params = ActiveNematicParams::default_test();
params.dt = 0.005;
let nv = mesh.n_vertices();
let q0 = QFieldDec::random_perturbation(nv, 0.01, 42);
let s_before = q0.mean_order_param();
assert!(
params.a_eff() < 0.0,
"need active regime for this test (a_eff = {})",
params.a_eff()
);
let (q_fin, stats) = run_dry_active_nematic_dec(&q0, ¶ms, &ops, None, 2000, 1000);
let s_after = q_fin.mean_order_param();
assert!(
s_after > s_before,
"order should grow in active phase: s_before={s_before}, s_after={s_after}"
);
assert_eq!(stats.len(), 3, "expected snapshots at steps 0, 1000, 2000");
assert!(stats[0].time < 1e-10, "first snapshot should be at t=0");
}
#[test]
fn dec_uniform_q_laplacian_vanishes() {
let mesh = FlatMesh::unit_square_grid(8);
let manifold = Euclidean::<2>;
let ops = Operators::from_mesh(&mesh, &manifold);
let nv = mesh.n_vertices();
let q = QFieldDec::uniform(nv, 0.3, 0.1);
let q_layout = q.to_lichnerowicz_layout();
let lap = ops.apply_lichnerowicz_laplacian(&q_layout, None);
let lap_norm = lap.norm();
assert!(
lap_norm < 1e-10,
"Laplacian of uniform Q on flat mesh should vanish, got norm = {lap_norm}"
);
}
#[test]
fn dec_zero_activity_relaxes_to_equilibrium() {
let mesh = FlatMesh::unit_square_grid(4);
let manifold = Euclidean::<2>;
let ops = Operators::from_mesh(&mesh, &manifold);
let mut params = ActiveNematicParams::default_test();
params.zeta_eff = 0.0; params.a_landau = -0.5; params.dt = 0.001;
let nv = mesh.n_vertices();
let q0 = QFieldDec::random_perturbation(nv, 0.3, 99);
let (q_fin, _stats) = run_dry_active_nematic_dec(&q0, ¶ms, &ops, None, 500, 500);
let s_fin = q_fin.mean_order_param();
assert!(s_fin.is_finite(), "mean_s must be finite, got {s_fin}");
assert!(
s_fin < 10.0,
"passive nematic should not blow up: mean_s = {s_fin}"
);
}
#[test]
fn dec_molecular_field_zero_q() {
let mesh = FlatMesh::unit_square_grid(4);
let manifold = Euclidean::<2>;
let ops = Operators::from_mesh(&mesh, &manifold);
let params = ActiveNematicParams::default_test();
let q = QFieldDec::zeros(mesh.n_vertices());
let h = volterra_dec::molecular_field_dec(&q, ¶ms, &ops, None);
let h_norm: f64 = h.q1.iter().chain(&h.q2).map(|x| x.abs()).sum();
assert!(h_norm < 1e-12, "H(Q=0) should vanish, got {h_norm}");
}