rusty_tree/octree/
regular_octree.rs1use super::{Statistics, Octree, OctreeType};
9use ndarray::{ArrayView2, Axis};
10use rusty_kernel_tools::RealType;
11use std::time::Instant;
12
13
14pub fn regular_octree<T: RealType>(
22 particles: ArrayView2<T>,
23 max_level: usize,
24) -> Octree<'_, T> {
25 use crate::helpers::compute_bounds;
26
27 const TOL: f64 = 1E-5;
28
29 let bounds = compute_bounds(particles);
30 let diameter = [
31 (bounds[0][1] - bounds[0][0]).to_f64().unwrap() * (1.0 + TOL),
32 (bounds[1][1] - bounds[1][0]).to_f64().unwrap() * (1.0 + TOL),
33 (bounds[2][1] - bounds[2][0]).to_f64().unwrap() * (1.0 + TOL),
34 ];
35
36 let origin = [
37 bounds[0][0].to_f64().unwrap(),
38 bounds[1][0].to_f64().unwrap(),
39 bounds[2][0].to_f64().unwrap(),
40 ];
41
42 regular_octree_with_bounding_box(particles, max_level, origin, diameter)
43}
44
45pub fn regular_octree_with_bounding_box<T: RealType>(
55 particles: ArrayView2<T>,
56 max_level: usize,
57 origin: [f64; 3],
58 diameter: [f64; 3],
59) -> Octree<'_, T> {
60 use crate::morton::encode_points;
61 use super::{compute_near_field_map, compute_interaction_list_map, compute_leaf_map, compute_level_information};
62
63 let now = Instant::now();
64
65
66 let leaf_keys = encode_points(particles, max_level, &origin, &diameter);
67 let (max_level, all_keys, level_keys) = compute_level_information(leaf_keys.view());
68 let leaf_key_to_particles = compute_leaf_map(leaf_keys.view());
69
70 let near_field = compute_near_field_map(&all_keys);
71 let interaction_list = compute_interaction_list_map(&all_keys);
72
73 let duration = now.elapsed();
74
75 let statistics = Statistics {
76 number_of_particles: particles.len_of(Axis(1)),
77 max_level,
78 number_of_leafs: leaf_key_to_particles.keys().len(),
79 number_of_keys: all_keys.len(),
80 creation_time: duration,
81 minimum_number_of_particles_in_leaf: leaf_key_to_particles
82 .values()
83 .map(|item| item.len())
84 .reduce(std::cmp::min)
85 .unwrap(),
86 maximum_number_of_particles_in_leaf: leaf_key_to_particles
87 .values()
88 .map(|item| item.len())
89 .reduce(std::cmp::max)
90 .unwrap(),
91 average_number_of_particles_in_leaf: (leaf_key_to_particles
92 .values()
93 .map(|item| item.len())
94 .sum::<usize>() as f64)
95 / (leaf_key_to_particles.keys().len() as f64),
96 };
97
98 Octree {
99 particles,
100 max_level,
101 origin,
102 diameter,
103 level_keys,
104 particle_keys: leaf_keys,
105 near_field,
106 interaction_list,
107 leaf_key_to_particles,
108 all_keys,
109 octree_type: OctreeType::Regular,
110 statistics,
111 }
112}