1use crate::math::{Matrix, Point, Real, Vector};
2use crate::utils::RealStruct;
3#[cfg(not(feature = "std"))]
4use na::ComplexField;
5
6#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
15#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
16#[derive(Copy, Clone, Debug, Default, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
17#[repr(C)]
18pub struct ParticlePosition {
19 pub point: Point<Real>,
20}
21unsafe impl RealStruct for ParticlePosition {}
22
23impl ParticlePosition {
24 pub fn closest_grid_pos(&self, cell_width: Real) -> Point<Real> {
25 (self.point / cell_width).map(|e| e.round()) * cell_width
26 }
27
28 pub fn associated_cell_index_in_block_off_by_two(&self, cell_width: Real) -> Point<u32> {
29 (self.point / cell_width).map(|e| {
30 let assoc_cell = e.round() as i32 - 2;
31 let assoc_block = (assoc_cell as Real / 4.0).floor() as i32 * 4;
33 (assoc_cell - assoc_block) as u32 })
35 }
36
37 pub fn associated_grid_pos(&self, cell_width: Real) -> Point<Real> {
38 ((self.point / cell_width).map(|e| e.round()) - Vector::repeat(1.0)) * cell_width
39 }
40
41 pub fn dir_to_closest_grid_node(&self, cell_width: Real) -> Vector<Real> {
42 self.closest_grid_pos(cell_width) - self.point
43 }
44
45 pub fn dir_to_associated_grid_node(&self, cell_width: Real) -> Vector<Real> {
46 self.associated_grid_pos(cell_width) - self.point
47 }
48}
49
50#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
51#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
52#[derive(Copy, Clone, Debug, Default, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
53#[repr(C)]
54pub struct ParticleVelocity {
55 pub vector: Vector<Real>,
56}
57
58unsafe impl RealStruct for ParticleVelocity {}
59
60#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
61#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
62#[derive(Copy, Clone, Debug, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
63#[repr(C)]
64pub struct ParticleVolume {
65 pub mass: Real,
66 pub volume0: Real,
67 pub radius0: Real,
68 pub deformation_gradient: Matrix<Real>, pub plastic_deformation_gradient_det: Real, }
71unsafe impl RealStruct for ParticleVolume {}
72impl Default for ParticleVolume {
73 fn default() -> Self {
74 Self {
75 mass: 0.0,
76 volume0: 0.0,
77 radius0: 0.0,
78 deformation_gradient: Matrix::identity(),
79 plastic_deformation_gradient_det: 1.0,
80 }
81 }
82}
83
84impl ParticleVolume {
85 pub fn density0(&self) -> Real {
86 self.mass / self.volume0
87 }
88
89 pub fn fluid_deformation_gradient_det(&self) -> Real {
90 self.deformation_gradient[(0, 0)]
91 }
92
93 pub fn volume_fluid(&self) -> Real {
94 self.volume0 * self.fluid_deformation_gradient_det()
95 }
96
97 pub fn volume_def_grad(&self) -> Real {
98 self.volume0 * self.deformation_gradient.determinant()
99 }
100
101 pub fn density_fluid(&self) -> Real {
102 self.density0() / self.fluid_deformation_gradient_det()
103 }
104
105 pub fn density_def_grad(&self) -> Real {
106 self.density0() / self.deformation_gradient.determinant()
107 }
108}
109
110#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
111#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
112#[derive(Copy, Clone, Debug, PartialEq, bytemuck::Zeroable)]
113#[repr(C)]
114pub struct ParticleStatus {
115 pub failed: bool,
117 pub is_static: bool,
118 pub kinematic_vel_enabled: bool,
119 pub kinematic_vel: Vector<Real>,
120 pub model_index: usize,
121}
122impl Default for ParticleStatus {
123 fn default() -> Self {
124 Self {
125 failed: false,
126 is_static: false,
127 kinematic_vel_enabled: false,
128 kinematic_vel: Vector::zeros(),
129 model_index: 0,
130 }
131 }
132}
133
134#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
135#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
136#[derive(Copy, Clone, Debug, PartialEq, bytemuck::Zeroable)]
137#[repr(C)]
138pub struct ParticlePhase {
139 pub phase: Real,
140 pub psi_pos: Real,
141}
142
143impl Default for ParticlePhase {
144 fn default() -> Self {
145 Self {
146 phase: 1.0,
147 psi_pos: 0.0,
148 }
149 }
150}
151
152#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
161#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
162#[derive(Copy, Clone, Debug, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
163#[repr(C)]
164pub struct ParticleContact {
165 pub boundary_normal: Vector<Real>,
166 pub boundary_dist: Real, }
168unsafe impl RealStruct for ParticleContact {}
169impl Default for ParticleContact {
170 fn default() -> Self {
171 Self {
172 boundary_normal: Vector::zeros(),
173 boundary_dist: 0.0,
174 }
175 }
176}
177
178#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
179#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
180#[derive(Copy, Clone, Debug, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
181#[repr(C)]
182pub struct ParticleFracture {
183 pub crack_propagation_factor: Real,
185 pub crack_threshold: Real,
186}
187unsafe impl RealStruct for ParticleFracture {}
188impl Default for ParticleFracture {
189 fn default() -> Self {
190 Self {
191 crack_propagation_factor: 0.0,
192 crack_threshold: Real::MAX,
193 }
194 }
195}
196
197#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
198#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
199#[derive(Copy, Clone, Debug, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
200#[repr(C)]
201pub struct ParticleData {
202 pub nacc_alpha: Real,
204 pub plastic_hardening: Real,
205 pub elastic_hardening: Real,
206 pub log_vol_gain: Real,
207}
208unsafe impl RealStruct for ParticleData {}
209
210impl Default for ParticleData {
211 fn default() -> Self {
212 Self {
213 nacc_alpha: -0.01,
214 plastic_hardening: 1.0,
215 elastic_hardening: 1.0,
216 log_vol_gain: 0.0,
217 }
218 }
219}