sparkl2d_core/dynamics/models/
plasticity_snow.rs1use crate::math::{Matrix, Real, Vector};
2
3#[cfg(not(feature = "std"))]
4use na::ComplexField;
5
6#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
8#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
9#[derive(Copy, Clone, Debug, PartialEq)]
10#[repr(C)]
11pub struct SnowPlasticity {
12 pub min_epsilon: Real,
13 pub max_epsilon: Real,
14 pub hardening_coeff: Real, }
16
17impl SnowPlasticity {
18 pub fn new() -> Self {
19 SnowPlasticity {
20 min_epsilon: 2.5e-2,
21 max_epsilon: 4.5e-3,
22 hardening_coeff: 10.0,
23 }
24 }
25
26 pub fn project_deformation_gradient(&self, singular_values: Vector<Real>) -> Vector<Real> {
27 singular_values.map(|e| e.max(1.0 - self.min_epsilon).min(1.0 + self.max_epsilon))
28 }
29
30 pub fn update_particle(
31 &self,
32 particle_deformation_gradient: &mut Matrix<Real>,
33 particle_elastic_hardening: &mut Real,
34 particle_plastic_deformation_gradient_det: &mut Real,
35 ) {
36 let mut svd = particle_deformation_gradient.svd_unordered(true, true);
37
38 let new_sig_vals = self.project_deformation_gradient(svd.singular_values);
39
40 *particle_plastic_deformation_gradient_det *=
41 svd.singular_values.product() / new_sig_vals.product();
42
43 *particle_elastic_hardening =
44 (self.hardening_coeff * (1.0 - *particle_plastic_deformation_gradient_det)).exp();
45
46 svd.singular_values = new_sig_vals;
47 *particle_deformation_gradient = svd.recompose().unwrap();
48 }
49}