vox_geometry_rust/
particle_system_data3.rs1use crate::vector3::Vector3D;
10use crate::point_neighbor_searcher3::*;
11use crate::point_parallel_hash_grid_searcher3::*;
12use crate::usize3::USize3;
13use std::sync::{RwLock, Arc};
14
15pub struct ParticleSystemData3 {
23    _radius: f64,
24    _mass: f64,
25    _number_of_particles: usize,
26    _position_idx: usize,
27    _velocity_idx: usize,
28    _force_idx: usize,
29
30    _scalar_data_list: Vec<Vec<f64>>,
31    _vector_data_list: Vec<Vec<Vector3D>>,
32
33    _neighbor_searcher: PointParallelHashGridSearcher3Ptr,
34    _neighbor_lists: Vec<Vec<usize>>,
35}
36
37impl ParticleSystemData3 {
38    pub fn new_default() -> ParticleSystemData3 {
40        return ParticleSystemData3 {
41            _radius: 1.0e-3,
42            _mass: 1.0e-3,
43            _number_of_particles: 0,
44            _position_idx: 0,
45            _velocity_idx: 0,
46            _force_idx: 0,
47            _scalar_data_list: vec![],
48            _vector_data_list: vec![],
49            _neighbor_searcher: PointParallelHashGridSearcher3::builder()
50                .with_resolution(USize3::new(64, 64, 64))
51                .with_grid_spacing(2.0 * 1.0e-3)
52                .make_shared(),
53            _neighbor_lists: vec![],
54        };
55    }
56
57    pub fn new(number_of_particles: usize) -> ParticleSystemData3 {
59        let mut system = ParticleSystemData3::new_default();
60        system._position_idx = system.add_vector_data(None);
61        system._velocity_idx = system.add_vector_data(None);
62        system._force_idx = system.add_vector_data(None);
63        system.resize(number_of_particles);
64        return system;
65    }
66}
67
68impl ParticleSystemData3 {
69    pub fn resize(&mut self, new_number_of_particles: usize) {
81        self._number_of_particles = new_number_of_particles;
82
83        for attr in &mut self._scalar_data_list {
84            attr.resize(new_number_of_particles, 0.0);
85        }
86
87        for attr in &mut self._vector_data_list {
88            attr.resize(new_number_of_particles, Vector3D::new_default());
89        }
90    }
91
92    pub fn number_of_particles(&self) -> usize {
94        return self._number_of_particles;
95    }
96
97    pub fn add_scalar_data(&mut self, initial_val: Option<f64>) -> usize {
106        let attr_idx = self._scalar_data_list.len();
107        let mut data: Vec<f64> = Vec::new();
108        data.resize(self.number_of_particles(), initial_val.unwrap_or(0.0));
109        self._scalar_data_list.push(data);
110        return attr_idx;
111    }
112
113    pub fn add_vector_data(&mut self, initial_val: Option<Vector3D>) -> usize {
122        let attr_idx = self._vector_data_list.len();
123        let mut data: Vec<Vector3D> = Vec::new();
124        data.resize(self.number_of_particles(), initial_val.unwrap_or(Vector3D::new_default()));
125        self._vector_data_list.push(data);
126        return attr_idx;
127    }
128
129    pub fn radius(&self) -> f64 {
131        return self._radius;
132    }
133
134    pub fn set_radius(&mut self, new_radius: f64) {
136        self._radius = f64::max(new_radius, 0.0);
137    }
138
139    pub fn mass(&self) -> f64 {
141        return self._mass;
142    }
143
144    pub fn set_mass(&mut self, new_mass: f64) {
146        self._mass = f64::max(new_mass, 0.0);
147    }
148
149    pub fn positions(&self) -> &Vec<Vector3D> {
151        return self.vector_data_at(self._position_idx);
152    }
153
154    pub fn positions_mut(&mut self) -> &mut Vec<Vector3D> {
156        return self.vector_data_at_mut(self._position_idx);
157    }
158
159    pub fn velocities(&self) -> &Vec<Vector3D> {
161        return self.vector_data_at(self._velocity_idx);
162    }
163
164    pub fn velocities_mut(&mut self) -> &mut Vec<Vector3D> {
166        return self.vector_data_at_mut(self._velocity_idx);
167    }
168
169    pub fn forces(&self) -> &Vec<Vector3D> {
171        return self.vector_data_at(self._force_idx);
172    }
173
174    pub fn forces_mut(&mut self) -> &mut Vec<Vector3D> {
176        return self.vector_data_at_mut(self._force_idx);
177    }
178
179    pub fn scalar_data_at(&self, idx: usize) -> &Vec<f64> {
181        return &self._scalar_data_list[idx];
182    }
183
184    pub fn scalar_data_at_mut(&mut self, idx: usize) -> &mut Vec<f64> {
186        return &mut self._scalar_data_list[idx];
187    }
188
189    pub fn vector_data_at(&self, idx: usize) -> &Vec<Vector3D> {
191        return &self._vector_data_list[idx];
192    }
193
194    pub fn vector_data_at_mut(&mut self, idx: usize) -> &mut Vec<Vector3D> {
196        return &mut self._vector_data_list[idx];
197    }
198
199    pub fn add_particle(&mut self,
214                        new_position: &Vector3D,
215                        new_velocity: Option<Vector3D>,
216                        new_force: Option<Vector3D>) {
217        let new_positions = vec![*new_position];
218        let new_velocities = vec![new_velocity.unwrap_or(Vector3D::new_default())];
219        let new_forces = vec![new_force.unwrap_or(Vector3D::new_default())];
220
221        self.add_particles(&new_positions,
222                           Some(&new_velocities),
223                           Some(&new_forces));
224    }
225
226    pub fn add_particles(&mut self,
240                         new_positions: &Vec<Vector3D>,
241                         new_velocities: Option<&Vec<Vector3D>>,
242                         new_forces: Option<&Vec<Vector3D>>) {
243        let old_number_of_particles = self.number_of_particles();
244        let new_number_of_particles = old_number_of_particles + new_positions.len();
245
246        self.resize(new_number_of_particles);
247
248        let pos = self.positions_mut();
249        pos.append(&mut new_positions.clone());
250        let vel = self.velocities_mut();
251        vel.append(&mut new_velocities.unwrap_or(&vec![]).clone());
252        let frc = self.forces_mut();
253        frc.append(&mut new_forces.unwrap_or(&vec![]).clone());
254    }
255
256    pub fn neighbor_searcher(&self) -> PointParallelHashGridSearcher3Ptr {
265        return self._neighbor_searcher.clone();
266    }
267
268    pub fn neighbor_lists(&self) -> &Vec<Vec<usize>> {
278        return &self._neighbor_lists;
279    }
280
281    pub fn build_neighbor_searcher(&mut self, max_search_radius: f64) {
283        self._neighbor_searcher = PointParallelHashGridSearcher3::builder()
285            .with_resolution(USize3::new(64, 64, 64))
286            .with_grid_spacing(2.0 * max_search_radius)
287            .make_shared();
288
289        self._neighbor_searcher.write().unwrap().build(self.positions());
290    }
291
292    pub fn build_neighbor_lists(&mut self, max_search_radius: f64) {
294        self._neighbor_lists.resize(self.number_of_particles(), vec![]);
295
296        for i in 0..self.number_of_particles() {
297            let origin = self.positions()[i];
298            self._neighbor_lists[i].clear();
299
300            self._neighbor_searcher.clone().read().unwrap().for_each_nearby_point(
301                &origin, max_search_radius,
302                &mut |j: usize, _: &Vector3D| {
303                    if i != j {
304                        self._neighbor_lists[i].push(j);
305                    }
306                });
307        }
308    }
309}
310
311pub type ParticleSystemData3Ptr = Arc<RwLock<ParticleSystemData3>>;