phyz_particle/
particle.rs1use phyz_math::{Mat3, Vec3};
4
5use crate::material::Material;
6
7#[derive(Debug, Clone)]
9pub struct Particle {
10 pub x: Vec3,
12 pub v: Vec3,
14 pub mass: f64,
16 pub volume: f64,
18 pub f: Mat3,
20 pub c: Mat3,
22 pub j: f64,
24 pub material: Material,
26}
27
28impl Particle {
29 pub fn new(x: Vec3, v: Vec3, mass: f64, volume: f64, material: Material) -> Self {
31 Self {
32 x,
33 v,
34 mass,
35 volume,
36 f: Mat3::identity(),
37 c: Mat3::zeros(),
38 j: 1.0,
39 material,
40 }
41 }
42
43 pub fn update_deformation(&mut self, grad_v: &Mat3, dt: f64) {
45 self.f = (Mat3::identity() + grad_v * dt) * self.f;
47 self.j = self.f.determinant();
48
49 if !self.j.is_finite() || self.j < 0.01 {
51 self.f = Mat3::identity();
52 self.j = 1.0;
53 }
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60 use crate::material::Material;
61
62 #[test]
63 fn test_particle_creation() {
64 let mat = Material::Elastic { e: 1e6, nu: 0.3 };
65 let p = Particle::new(
66 Vec3::new(0.0, 0.0, 0.0),
67 Vec3::new(1.0, 0.0, 0.0),
68 1.0,
69 0.1,
70 mat,
71 );
72
73 assert_eq!(p.mass, 1.0);
74 assert_eq!(p.j, 1.0);
75 assert_eq!(p.f, Mat3::identity());
76 }
77
78 #[test]
79 fn test_deformation_update() {
80 let mat = Material::Elastic { e: 1e6, nu: 0.3 };
81 let mut p = Particle::new(Vec3::zeros(), Vec3::zeros(), 1.0, 0.1, mat);
82
83 let grad_v = Mat3::identity() * -0.1; p.update_deformation(&grad_v, 0.1);
86
87 assert!((p.j - 0.99_f64.powi(3)).abs() < 1e-6);
89 }
90}