1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
extern crate alloc;
pub use BarnesHutTree;
pub use ;
/// Per-cell force contribution, the pluggable half of the Barnes-Hut traversal.
///
/// [`BarnesHutTree::accumulate_forces`] and [`BarnesHutTree::accumulate_all`] call
/// [`ForceKernel::accumulate`] once per summarised cell (a leaf, or an internal cell
/// passing the theta test), handing it the cell's summary. The kernel turns that summary
/// into a force, so the force law lives entirely in the kernel and never in the tree.
///
/// The blanket implementation covers any closure of the matching shape, `#[inline]`d so
/// a monomorphised call compiles down to inline arithmetic.
///
/// # Example
///
/// ```
/// use barnes_hut_tree::BarnesHutTree;
///
/// // Inverse-cube repulsion: push the query away from a summarised cell with magnitude
/// // `mass / distance^3` on the displacement, one axis at a time.
/// let kernel = |displacement: &[f32; 2],
/// distance_squared: f32,
/// mass: f32,
/// _is_leaf: bool,
/// force: &mut [f32; 2]| {
/// let scale = mass / (distance_squared * distance_squared.sqrt());
/// force[0] += scale * displacement[0];
/// force[1] += scale * displacement[1];
/// };
///
/// let points = [0.0f32, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0];
/// let tree = BarnesHutTree::<f32, u64, 2>::new_uniform(&points);
/// let mut forces = [0.0f32; 8];
/// tree.accumulate_all(&points, 0.5, &kernel, &mut forces);
/// assert!(forces.iter().all(|value| value.is_finite()));
/// ```