numerics
Loading...
Searching...
No Matches
spatial_hash.hpp
Go to the documentation of this file.
1/// @file spatial_hash.hpp
2/// @brief SPH neighbour search -- now powered by num::CellList2D
3///
4/// Replaces the original chained hash table with the counting-sort cell list
5/// from src/spatial/cell_list.hpp. The public interface is unchanged so that
6/// heat.cpp keeps working without modification.
7///
8/// Improvements over the old chained-list hash:
9///
10/// Old (chained hash table)
11/// build : O(n) -- fill table[] + next[] via random writes
12/// query : O(9 * avg_bucket) -- pointer-chase linked list in each of 9 cells
13///
14/// New (counting sort cell list)
15/// build : O(n + C) -- two sequential passes + one prefix sum
16/// query : O(k) sequential reads -- particles in same cell are contiguous
17/// pairs : iterate_pairs() -- visits each (i,j) pair once (Newton 3rd law)
18///
19/// The key cache-behaviour difference: the old next_[] array creates a random
20/// walk through the particle array. sorted_[] in CellList2D is laid out so
21/// that all particles in a cell sit next to each other in memory.
22#pragma once
23
24#include "particle.hpp"
25#include "spatial/cell_list.hpp"
26#include <vector>
27
28namespace physics {
29
31public:
32 /// @param cell_size Kernel support radius (2h).
33 /// @param xmin..ymax Simulation domain -- required by CellList2D for the
34 /// flat grid (no hash collisions, zero false positives).
35 SpatialHash(float cell_size,
36 float xmin, float xmax,
37 float ymin, float ymax)
38 : cl_(cell_size, xmin, xmax, ymin, ymax) {}
39
40 /// Rebuild from the particle array. O(n + C).
41 void build(const std::vector<Particle>& particles) {
42 const int n = static_cast<int>(particles.size());
43 cl_.build([&](int i) {
44 return std::make_pair(particles[i].x, particles[i].y);
45 }, n);
46 }
47
48 /// Point query: calls f(int j) for every candidate in the 3x3 neighbourhood.
49 /// Caller must verify |r_ij| < cutoff. (Same contract as before.)
50 template<typename F>
51 void query(float px, float py, F&& f) const {
52 cl_.query(px, py, std::forward<F>(f));
53 }
54
55 /// Newton's 3rd law pair traversal.
56 /// Calls f(int i, int j) for every unique unordered pair {i,j} whose cells
57 /// are within one cell of each other. Each pair appears exactly once.
58 /// Caller can apply equal-and-opposite contributions to both i and j.
59 template<typename F>
60 void iterate_pairs(F&& f) const {
61 cl_.iterate_pairs(std::forward<F>(f));
62 }
63
64private:
66};
67
68} // namespace physics
Cache-coherent 2D cell list for O(1) amortized neighbour queries.
void query(Scalar px, Scalar py, F &&f) const
Point query: calls f(int j) for every particle in the 3x3 cell neighbourhood of (px,...
void iterate_pairs(F &&f) const
Newton's 3rd law pair traversal.
void build(PosAccessor &&get_pos, int n)
Rebuild the cell list from n particles.
Definition cell_list.hpp:93
void iterate_pairs(F &&f) const
void query(float px, float py, F &&f) const
SpatialHash(float cell_size, float xmin, float xmax, float ymin, float ymax)
void build(const std::vector< Particle > &particles)
Rebuild from the particle array. O(n + C).
SPH particle data structure.