29#ifndef PECLET_VORO_PORE_CELLS_HPP
30#define PECLET_VORO_PORE_CELLS_HPP
33#include <Kokkos_Core.hpp>
36#include "peclet/core/common/view.hpp"
49 Kokkos::View<Real*, MemSpace>
points;
51 Kokkos::View<int64_t*, MemSpace>
faces;
53 Kokkos::View<Real*, MemSpace>
volume;
55 Kokkos::View<int*, MemSpace>
seed;
65 Kokkos::View<Real*, MemSpace>
verts;
66 Kokkos::View<int64_t*, MemSpace>
offset;
67 Kokkos::View<Real*, MemSpace>
volume;
68 Kokkos::View<int*, MemSpace>
seed;
81 if (c.empty() || c.overflow)
84 for (
int t = 0; t < c.nt; ++t)
92 int fidx[Cell::MAXFV];
93 for (
int k = 0; k < c.np; ++k) {
94 const int m = c.faceOrderedIdx(k,
fidx);
107template <
class Cell,
class Real>
112 for (
int t = 0; t < c.nt; ++t) {
118 pts[
o] = seed[0] + c.vx[t];
119 pts[
o + 1] = seed[1] + c.vy[t];
120 pts[
o + 2] = seed[2] + c.vz[t];
123 int fidx[Cell::MAXFV];
125 for (
int k = 0; k < c.np; ++k)
126 if (c.faceOrderedIdx(k,
fidx) >= 3)
130 for (
int k = 0; k < c.np; ++k) {
131 const int m = c.faceOrderedIdx(k,
fidx);
135 for (
int i = 0;
i < m; ++
i)
144template <
class Real,
class Sdf,
int MAXP,
int MAXT>
205template <
class Count,
class Off>
207 using Exec = peclet::core::ExecSpace;
208 using T =
typename Off::value_type;
209 Kokkos::parallel_scan(
210 "pore.scan", Kokkos::RangePolicy<Exec>(0, N + 1),
221 typename Off::value_type v;
222 Kokkos::deep_copy(v, Kokkos::subview(
off, N));
226template <
class Status>
228 using Exec = peclet::core::ExecSpace;
229 long ov = 0,
inc = 0;
230 Kokkos::parallel_reduce(
231 "pore.overflow", Kokkos::RangePolicy<Exec>(0, N),
233 Kokkos::parallel_reduce(
234 "pore.incomplete", Kokkos::RangePolicy<Exec>(0, N),
256template <
class Real,
class Sdf,
int MAXP = kMaxPlanes,
int MAXT = kMaxTriangles>
258 int N,
const Real L[3],
const Sdf& sdf,
260 using MemSpace = peclet::core::MemSpace;
261 using Exec = peclet::core::ExecSpace;
263 using Cell =
typename Gather::Cell;
264 using Kokkos::view_alloc;
265 using Kokkos::WithoutInitializing;
266 Kokkos::View<Real*, MemSpace> noW;
267 Kokkos::View<long*, MemSpace> noGid;
268 auto grid = buildTessGrid<Real, false>(posFlat, noW, N, L, sw, N, noGid,
nullptr);
269 const Gather g = Gather::make(grid, sdf);
270 auto binned = grid.binned;
273 Kokkos::View<int*, MemSpace> status(
"pore.status", N), emit(
"pore.emit", N), nPts(
"pore.nPts", N),
274 nEnt(
"pore.nEnt", N), wall(
"pore.wall", N);
275 Kokkos::parallel_for(
276 "pore.count", Kokkos::RangePolicy<Exec>(0, N), KOKKOS_LAMBDA(
const int pi) {
277 const int i = binned(pi);
280 const int st = g.clipped(pi, c, s);
293 Kokkos::View<int*, MemSpace> cellOff(
"pore.cellOff", N + 1);
294 Kokkos::View<int64_t*, MemSpace> ptOff(
"pore.ptOff", N + 1), entOff(
"pore.entOff", N + 1);
302 res.
points = Kokkos::View<Real*, MemSpace>(
303 view_alloc(std::string(
"pore.points"), WithoutInitializing), 3 * (
size_t)nPoints);
304 res.
faces = Kokkos::View<int64_t*, MemSpace>(
305 view_alloc(std::string(
"pore.faces"), WithoutInitializing), (
size_t)nEntries);
306 res.
faceOffset = Kokkos::View<int64_t*, MemSpace>(
"pore.faceOffset", nCells + 1);
307 res.
volume = Kokkos::View<Real*, MemSpace>(
"pore.volume", nCells);
308 res.
boundary = Kokkos::View<int*, MemSpace>(
"pore.boundary", nCells);
309 res.
seed = Kokkos::View<int*, MemSpace>(
"pore.seed", nCells);
311 auto faces = res.
faces;
315 auto seed = res.
seed;
316 Kokkos::deep_copy(Kokkos::subview(faceOffset, nCells), nEntries);
318 Kokkos::parallel_for(
319 "pore.fill", Kokkos::RangePolicy<Exec>(0, N), KOKKOS_LAMBDA(
const int pi) {
320 const int i = binned(pi);
326 const int ci = cellOff(i);
328 faceOffset(ci) = entOff(i);
329 volume(ci) = c.volumePerVertex();
330 boundary(ci) = wall(i);
344template <
class Real,
class Sdf,
int MAXP = kMaxPlanes,
int MAXT = kMaxTriangles>
346 int N,
const Real L[3],
const Sdf& sdf,
347 const Real point[3],
const Real normal[3],
349 using MemSpace = peclet::core::MemSpace;
350 using Exec = peclet::core::ExecSpace;
352 using Cell =
typename Gather::Cell;
353 using Kokkos::view_alloc;
354 using Kokkos::WithoutInitializing;
355 Kokkos::View<Real*, MemSpace> noW;
356 Kokkos::View<long*, MemSpace> noGid;
357 auto grid = buildTessGrid<Real, false>(posFlat, noW, N, L, sw, N, noGid,
nullptr);
358 const Gather g = Gather::make(grid, sdf);
359 auto binned = grid.binned;
360 const Real px = point[0], py = point[1], pz = point[2];
361 const Real ux = normal[0], uy = normal[1], uz = normal[2];
363 Kokkos::View<int*, MemSpace> status(
"pore.status", N), nV(
"pore.nV", N), emit(
"pore.emit", N);
364 Kokkos::parallel_for(
365 "pore.section.count", Kokkos::RangePolicy<Exec>(0, N), KOKKOS_LAMBDA(
const int pi) {
366 const int i = binned(pi);
369 const int st = g.clipped(pi, c, s);
373 const Real p0[3] = {px - s[0], py - s[1], pz - s[2]};
374 const Real u[3] = {ux, uy, uz};
375 Real spx[Cell::MAXSV], spy[Cell::MAXSV], spz[Cell::MAXSV];
376 const int m = c.sectionPolygon(p0, u, spx, spy, spz);
382 Kokkos::View<int*, MemSpace> polyOff(
"pore.polyOff", N + 1);
383 Kokkos::View<int64_t*, MemSpace> vOff(
"pore.vOff", N + 1);
390 res.
verts = Kokkos::View<Real*, MemSpace>(
391 view_alloc(std::string(
"pore.verts"), WithoutInitializing), 3 * (
size_t)nVerts);
392 res.
offset = Kokkos::View<int64_t*, MemSpace>(
"pore.offset", nPoly + 1);
393 res.
volume = Kokkos::View<Real*, MemSpace>(
"pore.volume", nPoly);
394 res.
seed = Kokkos::View<int*, MemSpace>(
"pore.seed", nPoly);
395 auto verts = res.
verts;
398 auto seed = res.
seed;
399 Kokkos::deep_copy(Kokkos::subview(offset, nPoly), nVerts);
400 Kokkos::parallel_for(
401 "pore.section.fill", Kokkos::RangePolicy<Exec>(0, N), KOKKOS_LAMBDA(
const int pi) {
402 const int i = binned(pi);
408 const Real p0[3] = {px - s[0], py - s[1], pz - s[2]};
409 const Real u[3] = {ux, uy, uz};
410 Real spx[Cell::MAXSV], spy[Cell::MAXSV], spz[Cell::MAXSV];
411 const int m = c.sectionPolygon(p0, u, spx, spy, spz);
412 const int64_t base = vOff(i);
413 for (
int k = 0; k < m; ++k) {
414 verts(3 * (base + k)) = s[0] + spx[k];
415 verts(3 * (base + k) + 1) = s[1] + spy[k];
416 verts(3 * (base + k) + 2) = s[2] + spz[k];
418 const int p = polyOff(i);
420 volume(p) = c.volumePerVertex();
KOKKOS_INLINE_FUNCTION Dual< Real, K > dnum(Real c)
Definition convex_cell.hpp:53
KOKKOS_INLINE_FUNCTION bool poreCellCount(const Cell &c, int &nPts, int &nEntries, bool &wall)
Definition pore_cells.hpp:80
void exclusiveScan(const Count &count, const Off &off, int N)
Exclusive scan of a per-seed count into offsets (N+1 entries; the last is the total).
Definition pore_cells.hpp:206
KOKKOS_INLINE_FUNCTION void poreCellFill(const Cell &c, const Real seed[3], int64_t ptBase, int64_t fBase, Real *pts, int64_t *faces)
Definition pore_cells.hpp:108
void statusCounts(const Status &status, int N, long &overflow, long &incomplete)
Definition pore_cells.hpp:227
Off::value_type lastOf(const Off &off, int N)
Definition pore_cells.hpp:220
Device-native Voronoi tessellation, geometry and finite-volume physics.
Definition convex_cell.hpp:41
PoreSectionResult< Real > buildPoreSection(const Kokkos::View< Real *, peclet::core::MemSpace > &posFlat, int N, const Real L[3], const Sdf &sdf, const Real point[3], const Real normal[3], int sw=kSearchWindow)
Definition pore_cells.hpp:345
@ kOverflow
Definition tessellator.hpp:50
@ kOk
Definition tessellator.hpp:49
@ kIncomplete
Definition tessellator.hpp:52
@ kEmpty
Definition tessellator.hpp:51
PoreCellsResult< Real > buildPoreCells(const Kokkos::View< Real *, peclet::core::MemSpace > &posFlat, int N, const Real L[3], const Sdf &sdf, int sw=kSearchWindow)
Definition pore_cells.hpp:257
constexpr int kBoundaryFacet
Definition sdf.hpp:36
constexpr int kSearchWindow
Definition params.hpp:28
The named engine defaults of peclet.voro — one header-level home for every capacity and default the l...
ConvexCell< Real, kMaxP, kMaxT, TrackAdj > Cell
Definition tessellator.hpp:241
int dimx
Definition tessellator.hpp:268
Kokkos::View< int *, MemSpace > binned
Definition tessellator.hpp:245
KOKKOS_INLINE_FUNCTION bool gatherCell(int pi, Cell &c, Real &pix, Real &piy, Real &piz, Real &wSelf, int &ncRec, int &nnRec) const
Definition tessellator.hpp:536
int wlS
Definition tessellator.hpp:268
Kokkos::View< Real *, MemSpace > posSorted
Definition tessellator.hpp:246
Kokkos::View< int *, MemSpace > wlOff
Definition tessellator.hpp:255
int sw
Definition tessellator.hpp:268
bool useMorton
Definition tessellator.hpp:269
Real minCsz
Definition tessellator.hpp:266
Real icx
Definition tessellator.hpp:266
Real Ly
Definition tessellator.hpp:266
Kokkos::View< Real *, MemSpace > wlRmin
Definition tessellator.hpp:256
Real icz
Definition tessellator.hpp:266
int dimy
Definition tessellator.hpp:268
Kokkos::View< int *, MemSpace > cellStart
Definition tessellator.hpp:249
Kokkos::View< gid_t *, MemSpace > gidSorted
Definition tessellator.hpp:248
bool haveGid
Definition tessellator.hpp:269
int nOff
Definition tessellator.hpp:268
Real wMaxAll
Definition tessellator.hpp:267
int dimz
Definition tessellator.hpp:268
Real Lz
Definition tessellator.hpp:266
Kokkos::View< Real *, MemSpace > wSorted
Definition tessellator.hpp:247
Real icy
Definition tessellator.hpp:266
Real Lx
Definition tessellator.hpp:266
Sdf sdf
Definition tessellator.hpp:271
The clipped polyhedra, packed as flat arrays in seed order (VTK_POLYHEDRON layout).
Definition pore_cells.hpp:47
long numIncomplete
exported cells whose gather coverage did not close (raise sw)
Definition pore_cells.hpp:57
peclet::core::MemSpace MemSpace
Definition pore_cells.hpp:48
Kokkos::View< Real *, MemSpace > points
Definition pore_cells.hpp:49
Kokkos::View< int64_t *, MemSpace > faces
Per exported cell: nf, then per face (m, m global point ids, CCW about the outward normal).
Definition pore_cells.hpp:51
long numOverflow
seeds skipped because their cell hit a capacity
Definition pore_cells.hpp:56
Kokkos::View< int64_t *, MemSpace > faceOffset
numCells+1: each cell's range in faces
Definition pore_cells.hpp:52
Kokkos::View< int *, MemSpace > boundary
numCells: 1 where a face is a wall facet
Definition pore_cells.hpp:54
Kokkos::View< int *, MemSpace > seed
numCells: the seed index of each cell
Definition pore_cells.hpp:55
Kokkos::View< Real *, MemSpace > volume
numCells: the clipped cell volume
Definition pore_cells.hpp:53
Definition pore_cells.hpp:63
Kokkos::View< Real *, MemSpace > verts
3·numVerts
Definition pore_cells.hpp:65
Kokkos::View< int *, MemSpace > seed
numPolygons: the seed index of the cut cell
Definition pore_cells.hpp:68
Kokkos::View< int64_t *, MemSpace > offset
numPolygons+1: each polygon's vertex range
Definition pore_cells.hpp:66
peclet::core::MemSpace MemSpace
Definition pore_cells.hpp:64
Kokkos::View< Real *, MemSpace > volume
numPolygons: the 3-D volume of the cut cell
Definition pore_cells.hpp:67
long numIncomplete
cut cells whose gather coverage did not close
Definition pore_cells.hpp:70
long numOverflow
seeds skipped because their cell hit a capacity
Definition pore_cells.hpp:69
Definition tess_grid.hpp:56
Definition pore_cells.hpp:145
typename Builder::Cell Cell
Definition pore_cells.hpp:147
Builder op
Definition pore_cells.hpp:148
KOKKOS_INLINE_FUNCTION int clipped(int pi, Cell &c, Real seedW[3]) const
Definition pore_cells.hpp:182
static PoreCellGather make(const TessGrid< Real > &grid, const Sdf &sdf)
Definition pore_cells.hpp:150