use physics_in_parallel::models::particles::attrs::{is_alive, is_rigid, set_alive, set_rigid};
use physics_in_parallel::models::particles::create_state::{
ATTR_M, ATTR_M_INV, ATTR_R, ATTR_RIGID, ATTR_V, MassiveParticlesError, VelocitySamplingMethod,
create_template, randomize_r, randomize_v,
};
use physics_in_parallel::space::continuous::sampling::VectorSamplingMethod;
#[test]
fn create_template_shapes_and_defaults() {
let obj = create_template(3, 4).unwrap();
let r = obj.core.get::<f64>(ATTR_R).unwrap();
let v = obj.core.get::<f64>(ATTR_V).unwrap();
let m = obj.core.get::<f64>(ATTR_M).unwrap();
let m_inv = obj.core.get::<f64>(ATTR_M_INV).unwrap();
let rigid = obj.core.get::<u8>(ATTR_RIGID).unwrap();
assert_eq!(r.dim(), 3);
assert_eq!(r.num_vectors(), 4);
assert_eq!(v.dim(), 3);
assert_eq!(v.num_vectors(), 4);
assert_eq!(m.dim(), 1);
assert_eq!(m_inv.dim(), 1);
assert_eq!(rigid.dim(), 1);
assert_eq!(obj.meta.label, "particles");
for i in 0..4 {
assert_eq!(m.get(i as isize, 0), 1.0);
assert_eq!(m_inv.get(i as isize, 0), 1.0);
assert!(is_alive(&obj, i).unwrap());
assert!(!is_rigid(&obj, i).unwrap());
}
let mut obj = obj;
set_alive(&mut obj, 2, false).unwrap();
assert!(!is_alive(&obj, 2).unwrap());
set_rigid(&mut obj, 1, true).unwrap();
assert!(is_rigid(&obj, 1).unwrap());
}
#[test]
fn create_template_rejects_zero_shape_inputs() {
assert_eq!(
create_template(0, 4).unwrap_err(),
MassiveParticlesError::InvalidDimension { dim: 0 }
);
assert_eq!(
create_template(3, 0).unwrap_err(),
MassiveParticlesError::InvalidParticleCount { n: 0 }
);
}
#[test]
fn randomize_r_uniform_stays_inside_box() {
let mut obj = create_template(2, 256).unwrap();
randomize_r(
&mut obj,
VectorSamplingMethod::UniformCentered {
box_size: &[2.0, 4.0],
},
)
.unwrap();
let r = obj.core.get::<f64>(ATTR_R).unwrap();
for i in 0..r.num_vectors() {
let row = r.get_vector(i as isize);
assert!(row[0] >= -1.0 && row[0] <= 1.0);
assert!(row[1] >= -2.0 && row[1] <= 2.0);
}
}
#[test]
fn randomize_r_rejects_invalid_position_parameters() {
let mut obj = create_template(2, 4).unwrap();
let err = randomize_r(
&mut obj,
VectorSamplingMethod::UniformCentered { box_size: &[1.0] },
)
.unwrap_err();
assert!(matches!(err, MassiveParticlesError::Distribution { .. }));
let err = randomize_r(
&mut obj,
VectorSamplingMethod::JitteredLattice {
spacings: &[1.0, f64::NAN],
sigmas: &[0.0, 0.0],
},
)
.unwrap_err();
assert!(matches!(err, MassiveParticlesError::Distribution { .. }));
}
#[test]
fn randomize_v_invalid_and_mass_inv_validation() {
let mut obj = create_template(2, 3).unwrap();
let err = randomize_v(
&mut obj,
VelocitySamplingMethod::Uniform {
low: 1.0,
high: 1.0,
},
)
.unwrap_err();
assert!(matches!(err, MassiveParticlesError::Distribution { .. }));
obj.core
.set_vector_of::<f64>(ATTR_M_INV, 1, &[-1.0])
.unwrap();
let err = randomize_v(
&mut obj,
VelocitySamplingMethod::MaxwellBoltzmann { tau: 1.0 },
)
.unwrap_err();
assert!(matches!(
err,
MassiveParticlesError::InvalidMassInv {
index: 1,
value: -1.0
}
));
}
#[test]
fn randomize_v_gaussian_per_axis_validates_parameters() {
let mut obj = create_template(2, 3).unwrap();
let err = randomize_v(
&mut obj,
VelocitySamplingMethod::GaussianPerAxis {
mean: &[0.0],
std: &[1.0, 1.0],
},
)
.unwrap_err();
assert!(matches!(err, MassiveParticlesError::Distribution { .. }));
let err = randomize_v(
&mut obj,
VelocitySamplingMethod::GaussianPerAxis {
mean: &[0.0, 0.0],
std: &[1.0, -1.0],
},
)
.unwrap_err();
assert!(matches!(err, MassiveParticlesError::Distribution { .. }));
}