37 PairsV outPairs, CountV outCount,
float boxCap = 0.0f) {
39 using Box = ArborX::Box<3>;
46#define PECLET_DEM_SANE_BOX(i, px, py, pz, b) \
47 float px = pos(i, 0), py = pos(i, 1), pz = pos(i, 2), b = rad(i) + margin; \
48 if (!(b == b) || !(px == px) || !(py == py) || !(pz == pz) || \
49 (boxCap > 0.0f && b > boxCap)) { \
50 px = py = pz = -1.0e30f; \
55 Kokkos::View<Box*, BpMem> boxes(
56 Kokkos::view_alloc(space,
"peclet::dem::bp::boxes", Kokkos::WithoutInitializing),
59 "peclet::dem::bp::aabb", Kokkos::RangePolicy<BpExec>(space, 0, numParticles),
60 KOKKOS_LAMBDA(
int i) {
62 boxes(i) = Box{{px - b, py - b, pz - b}, {px + b, py + b, pz + b}};
65 ArborX::BoundingVolumeHierarchy
const tree(space, ArborX::Experimental::attach_indices(boxes));
68 using Predicate =
decltype(ArborX::intersects(std::declval<Box>()));
69 Kokkos::View<Predicate*, BpMem> preds(
70 Kokkos::view_alloc(space,
"peclet::dem::bp::preds", Kokkos::WithoutInitializing), numReal);
72 "peclet::dem::bp::preds", Kokkos::RangePolicy<BpExec>(space, 0, numReal),
73 KOKKOS_LAMBDA(
int i) {
75 preds(i) = ArborX::intersects(Box{{px - b, py - b, pz - b}, {px + b, py + b, pz + b}});
77#undef PECLET_DEM_SANE_BOX
79 Kokkos::View<
typename decltype(tree)::value_type*,
BpMem> values(
"peclet::dem::bp::values", 0);
80 Kokkos::View<int*, BpMem> offsets(
"peclet::dem::bp::offsets", 0);
81 tree.query(space, preds, values, offsets);
84 Kokkos::deep_copy(space, outCount, 0);
85 const int maxPairs =
static_cast<int>(outPairs.extent(0));
86 Kokkos::View<int* [2], BpMem> pairs = outPairs;
87 Kokkos::View<int, BpMem> cnt = outCount;
89 "peclet::dem::bp::emit", Kokkos::RangePolicy<BpExec>(space, 0, numReal),
90 KOKKOS_LAMBDA(
int i) {
91 for (
int k = offsets(i); k < offsets(i + 1); ++k) {
92 const int j = values(k).index;
94 const int slot = Kokkos::atomic_fetch_add(&cnt(), 1);
95 if (slot < maxPairs) {
105 Kokkos::deep_copy(h_count, outCount);