Browse Source

sparse + base

opt
Björn Steinbrink 8 months ago
parent
commit
c31c03707a
1 changed files with 43 additions and 35 deletions
  1. +43
    -35
      src/barnes_hut.rs

+ 43
- 35
src/barnes_hut.rs View File

@ -8,7 +8,7 @@ const THETA: f64 = 0.5;
pub struct Octree {
num_particles: Vec<usize>,
children: Vec<[isize; 8]>, // TODO make this an Option<[usize; 8]>
children: Vec<(isize, u8)>, // TODO make this an Option<[usize; 8]>
mass: Vec<f64>,
min_coord: Vec<Vector3D>,
max_coord: Vec<Vector3D>,
@ -36,7 +36,7 @@ impl Octree {
let s = if depth > s { depth } else { s };
o.num_particles.push(0);
o.children.push([-1; 8]);
o.children.push((-1, 0));
o.mass.push(0.0);
o.min_coord.push(min);
o.max_coord.push(max);
@ -86,8 +86,13 @@ impl Octree {
else {
//println!("A{}", self.nodes[cur_node].num_particles);
//Divide and conquer
for &child in &self.children[cur_node] {
self.barnes_hut_specific_node(particle, child as usize, delta);
let (base, mask) = self.children[cur_node];
let mut off = 0;
for c in 0..8 {
if mask & (1 << c) != 0 {
self.barnes_hut_specific_node(particle, base as usize + off, delta);
off += 1;
}
}
}
}
@ -106,34 +111,6 @@ impl Octree {
let center_point = (self.min_coord[cur_node] + self.max_coord[cur_node]) / 2.0;
if self.children[cur_node][0] == -1 {
for i in 0..8 {
let idx = self.num_particles.len();
let (min, max) = Octree::get_octant_bounding_box_from_id(self.min_coord[cur_node],
self.max_coord[cur_node],
center_point,
i);
let width = max.x - min.x;
let height = max.y - min.y;
let depth = max.z - min.z;
let s = if width > height { width } else { height };
let s = if depth > s { depth } else { s };
self.num_particles.push(0);
self.children.push([-1; 8]);
self.mass.push(0.0);
self.min_coord.push(min);
self.max_coord.push(max);
self.avg_weighted_position.push(Vector3D::new(0.0, 0.0, 0.0));
self.s.push(s);
self.children[cur_node][i] = idx as isize;
}
}
else {
println!("This should never happen :S");
}
let mut particle_octs: [Vec<&RigidPoint>; 8] = [
Vec::with_capacity(particles.len()/4),
Vec::with_capacity(particles.len()/4),
@ -144,8 +121,8 @@ impl Octree {
Vec::with_capacity(particles.len()/4),
Vec::with_capacity(particles.len()/4),
];
for &particle in particles {
// Update ourself
self.mass[cur_node] += particle.mass;
self.num_particles[cur_node] += 1;
@ -156,9 +133,40 @@ impl Octree {
}
//Recurse
let idx = self.num_particles.len();
self.children[cur_node].0 = idx as isize;
for (i, particle_oct) in particle_octs.iter().enumerate() {
self.add_particles_to_specific_node(&particle_oct,
self.children[cur_node][i] as usize);
if !particle_oct.is_empty() {
self.children[cur_node].1 |= 1 << i;
let (min, max) = Octree::get_octant_bounding_box_from_id(self.min_coord[cur_node],
self.max_coord[cur_node],
center_point,
i);
let width = max.x - min.x;
let height = max.y - min.y;
let depth = max.z - min.z;
let s = if width > height { width } else { height };
let s = if depth > s { depth } else { s };
self.num_particles.push(0);
self.children.push((-1, 0));
self.mass.push(0.0);
self.min_coord.push(min);
self.max_coord.push(max);
self.avg_weighted_position.push(Vector3D::new(0.0, 0.0, 0.0));
self.s.push(s);
}
}
let mut off = 0;
for (i, particle_oct) in particle_octs.iter().enumerate() {
if !particle_oct.is_empty() {
self.add_particles_to_specific_node(&particle_oct,
self.children[cur_node].0 as usize + off);
off += 1;
}
}
}


Loading…
Cancel
Save