24#ifndef PECLET_VORO_CONVEX_CELL_HPP
25#define PECLET_VORO_CONVEX_CELL_HPP
27#include <Kokkos_Core.hpp>
35#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
36#define VOR_UNROLL _Pragma("unroll")
47template <
class Real,
int K>
52template <
class Real,
int K>
56 for (
int i = 0; i < K; ++i)
60template <
class Real,
int K>
66template <
class Real,
int K>
70 for (
int i = 0;
i <
K; ++
i)
74template <
class Real,
int K>
78 for (
int i = 0;
i <
K; ++
i)
82template <
class Real,
int K>
86 for (
int i = 0;
i <
K; ++
i)
87 r.
d[
i] = a.
d[
i] * b.
v + a.
v * b.
d[
i];
90template <
class Real,
int K>
95 for (
int i = 0;
i <
K; ++
i)
99template <
class Real,
int K>
102 r.
v = Kokkos::sqrt(a.
v);
104 for (
int i = 0;
i <
K; ++
i)
108template <
class Real,
int K>
110 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
112template <
class Real,
int K>
115 o[0] = a[1] * b[2] - a[2] * b[1];
116 o[1] = a[2] * b[0] - a[0] * b[2];
117 o[2] = a[0] * b[1] - a[1] * b[0];
119template <
class Real,
int K>
126template <
class Real,
int K>
130 f[0] = v[0] - s * c[0];
131 f[1] = v[1] - s * c[1];
132 f[2] = v[2] - s * c[2];
139template <
class Real,
int MAXP = kMaxPlanes,
int MAXT = kMaxTriangles,
bool TrackAdj = false>
141 static_assert(MAXP <= 255,
"plane index must fit in unsigned char");
153 unsigned char t0[MAXT],
t1[MAXT],
t2[MAXT];
172 Kokkos::Array<int, (TrackAdj ? MAXT : 0) * 3>
adj;
176 KOKKOS_INLINE_FUNCTION
void initBox(Real L0, Real L1, Real L2) {
177 const Real h[3] = {Real(0.5) * L0, Real(0.5) * L1, Real(0.5) * L2};
178 for (
int ax = 0; ax < 3; ++ax) {
179 for (
int s = 0; s < 2; ++s) {
180 const int k = 2 * ax + s;
181 n[k][0] =
n[k][1] =
n[k][2] = 0;
182 n[k][ax] = (s == 0) ? h[ax] : -h[ax];
183 nn[k] = h[ax] * h[ax];
191 for (
int sx = 0; sx < 2; ++sx)
192 for (
int sy = 0; sy < 2; ++sy)
193 for (
int sz = 0; sz < 2; ++sz) {
194 t0[
nt] = (
unsigned char)(0 + sx);
195 t1[
nt] = (
unsigned char)(2 + sy);
196 t2[
nt] = (
unsigned char)(4 + sz);
201 if constexpr (TrackAdj)
210 const Real* a =
n[
t0[t]];
211 const Real* b =
n[
t1[t]];
212 const Real* c =
n[
t2[t]];
213 const Real da =
nn[
t0[t]], db =
nn[
t1[t]], dc =
nn[
t2[t]];
214 const Real bc[3] = {b[1] * c[2] - b[2] * c[1], b[2] * c[0] - b[0] * c[2],
215 b[0] * c[1] - b[1] * c[0]};
216 const Real ca[3] = {c[1] * a[2] - c[2] * a[1], c[2] * a[0] - c[0] * a[2],
217 c[0] * a[1] - c[1] * a[0]};
218 const Real ab[3] = {a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2],
219 a[0] * b[1] - a[1] * b[0]};
220 const Real det = a[0] * bc[0] + a[1] * bc[1] + a[2] * bc[2];
221 const Real inv = det != Real(0) ? Real(1) / det : Real(0);
222 vx[t] = (da * bc[0] + db * ca[0] + dc * ab[0]) * inv;
223 vy[t] = (da * bc[1] + db * ca[1] + dc * ab[1]) * inv;
224 vz[t] = (da * bc[2] + db * ca[2] + dc * ab[2]) * inv;
232 const Real h[3] = {Real(0.5) * L0, Real(0.5) * L1, Real(0.5) * L2};
233 for (
int ax = 0; ax < 3; ++ax)
234 for (
int s = 0; s < 2; ++s) {
235 const int k = 2 * ax + s;
236 n[k][0] =
n[k][1] =
n[k][2] = 0;
237 n[k][ax] = (s == 0) ? h[ax] : -h[ax];
238 nn[k] = h[ax] * h[ax];
257 template <
class Policy = Voronoi>
258 KOKKOS_INLINE_FUNCTION
void reevalGeometry(Real sx, Real sy, Real sz,
const Real* pos, Real L,
259 Real wSelf = Real(0),
const Real* weight =
nullptr) {
260 const Real Lh = Real(0.5) * L;
261 for (
int k = 0; k <
np; ++k) {
264 const int g =
pnbr[k];
265 Real rx = pos[3 * g] - sx, ry = pos[3 * g + 1] - sy, rz = pos[3 * g + 2] - sz;
266 rx = rx > Lh ? rx - L : (rx < -Lh ? rx + L : rx);
267 ry = ry > Lh ? ry - L : (ry < -Lh ? ry + L : ry);
268 rz = rz > Lh ? rz - L : (rz < -Lh ? rz + L : rz);
269 if constexpr (Policy::kHasWeightDof) {
271 const Real r[3] = {rx, ry, rz};
272 const Real rho = rx * rx + ry * ry + rz * rz;
273 const Real off = Policy::template offsetFromRel<Real>(r, wSelf, weight[g]);
274 const Real a = rho > Real(0) ? off / rho : Real(0);
278 nn[k] =
n[k][0] *
n[k][0] +
n[k][1] *
n[k][1] +
n[k][2] *
n[k][2];
281 const Real hx = Real(0.5) * rx, hy = Real(0.5) * ry, hz = Real(0.5) * rz;
285 nn[k] = hx * hx + hy * hy + hz * hz;
288 for (
int t = 0; t <
nt; ++t)
310 for (
int t = 0; t <
nt; ++t) {
313 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
314 for (
int k = 0; k <
np; ++k) {
315 if (
t0[t] == k ||
t1[t] == k ||
t2[t] == k)
317 const Real s =
n[k][0] * v[0] +
n[k][1] * v[1] +
n[k][2] * v[2] -
nn[k];
320 const Real invlen = (
nn[k] > Real(0)) ? Real(1) / Kokkos::sqrt(
nn[k]) : Real(0);
321 maxd = Kokkos::max(maxd, s * invlen);
346 int& nPartners)
const {
348 bool consistent =
true;
349 for (
int t = 0; t <
nt; ++t) {
352 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
353 for (
int k = 0; k <
np; ++k) {
354 if (
t0[t] == k ||
t1[t] == k ||
t2[t] == k)
356 const Real s =
n[k][0] * v[0] +
n[k][1] * v[1] +
n[k][2] * v[2] -
nn[k];
358 const Real invlen = (
nn[k] > Real(0)) ? Real(1) / Kokkos::sqrt(
nn[k]) : Real(0);
359 if (s * invlen > tol) {
361 const int part =
pnbr[k];
364 for (
int q = 0; q < nPartners; ++q)
365 if (outPartners[q] == part) {
369 if (!seen && nPartners < maxPartners)
370 outPartners[nPartners++] = part;
382 const int a =
t0[s], b =
t1[s], c =
t2[s];
383 return (a != x && a != y) ? a : (b != x && b != y) ? b : c;
395 static_assert(TrackAdj,
"computePoke4 requires TrackAdj");
396 for (
int t = 0; t <
nt; ++t) {
398 out[t * 4 + 0] = out[t * 4 + 1] = out[t * 4 + 2] = out[t * 4 + 3] = 0xff;
401 const int vt[3] = {
t0[t],
t1[t],
t2[t]};
403 for (
int e = 0; e < 3; ++e) {
404 const int s =
adj[t * 3 + e];
406 out[t * 4 + e] = (
unsigned char)(eo[e] & 0xff);
408 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
409 Real best = Real(3.4e38);
411 for (
int k = 0; k <
np; ++k) {
412 if (k == vt[0] || k == vt[1] || k == vt[2])
414 if (k == eo[0] || k == eo[1] || k == eo[2])
416 const Real slack =
nn[k] - (
n[k][0] * v[0] +
n[k][1] * v[1] +
n[k][2] * v[2]);
417 if (slack >= Real(0) && slack < best) {
422 out[t * 4 + 3] = (
unsigned char)(g & 0xff);
432 KOKKOS_INLINE_FUNCTION
bool isLocallyConvex(
const unsigned char* poke4, Real tol)
const {
434 for (
int t = 0; t <
nt; ++t) {
437 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
438 for (
int j = 0; j < 4; ++j) {
439 const int k = (int)poke4[t * 4 + j];
442 const Real sl =
n[k][0] * v[0] +
n[k][1] * v[1] +
n[k][2] * v[2] -
nn[k];
444 const Real invlen = (
nn[k] > Real(0)) ? Real(1) / Kokkos::sqrt(
nn[k]) : Real(0);
445 maxd = Kokkos::max(maxd, sl * invlen);
457 int* outPartners,
int maxPartners,
458 int& nPartners)
const {
460 bool consistent =
true;
461 for (
int t = 0; t <
nt; ++t) {
464 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
465 for (
int j = 0; j < 4; ++j) {
466 const int k = (int)poke4[t * 4 + j];
469 const Real sl =
n[k][0] * v[0] +
n[k][1] * v[1] +
n[k][2] * v[2] -
nn[k];
471 const Real invlen = (
nn[k] > Real(0)) ? Real(1) / Kokkos::sqrt(
nn[k]) : Real(0);
472 if (sl * invlen > tol) {
474 const int part =
pnbr[k];
477 for (
int q = 0; q < nPartners; ++q)
478 if (outPartners[q] == part) {
482 if (!seen && nPartners < maxPartners)
483 outPartners[nPartners++] = part;
500 const Real nx =
n[k][0], ny =
n[k][1], nz =
n[k][2];
501 const Real nl = Kokkos::sqrt(
nn[k]);
504 const Real ux = nx / nl, uy = ny / nl, uz = nz / nl;
506 for (
int q = 0; q < m; ++q) {
507 const int r = (q + 1) % m;
508 const Real a[3] = {fx[q] - nx, fy[q] - ny, fz[q] - nz};
509 const Real b[3] = {fx[r] - nx, fy[r] - ny, fz[r] - nz};
510 const Real cr[3] = {a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2],
511 a[0] * b[1] - a[1] * b[0]};
512 const Real At = Real(0.5) * (cr[0] * ux + cr[1] * uy + cr[2] * uz);
513 const Real aa = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
514 const Real bb = b[0] * b[0] + b[1] * b[1] + b[2] * b[2];
515 const Real ab = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
516 M2 += At / Real(6) * (aa + bb + ab);
526 KOKKOS_INLINE_FUNCTION Real
planeGap(
const Real pdir[3], Real d)
const {
527 const Real l2 = pdir[0] * pdir[0] + pdir[1] * pdir[1] + pdir[2] * pdir[2];
530 Real m = Real(-1e30);
531 for (
int t = 0; t <
nt; ++t) {
534 const Real s = pdir[0] *
vx[t] + pdir[1] *
vy[t] + pdir[2] *
vz[t] - d;
538 return m / Kokkos::sqrt(l2);
549 unsigned char used[MAXP];
552 for (
int k = 0; k <
np; ++k)
553 used[k] = (k < 6) ? 1 : 0;
554 for (
int t = 0; t <
nt; ++t)
560 unsigned char map[MAXP];
562 for (
int k = 0; k <
np; ++k) {
567 map[k] = (
unsigned char)m;
577 const int removed =
np - m;
579 for (
int t = 0; t <
nt; ++t)
593 for (
int t = 0; t <
nt; ++t) {
596 const Real r =
vx[t] *
vx[t] +
vy[t] *
vy[t] +
vz[t] *
vz[t];
609 KOKKOS_INLINE_FUNCTION
int findSharing(
int self,
int x,
int y)
const {
610 for (
int s = 0; s <
nt; ++s) {
611 if (s == self || !
alive[s])
613 const int a =
t0[s], b =
t1[s], c =
t2[s];
614 const bool hasX = (a == x || b == x || c == x);
615 const bool hasY = (a == y || b == y || c == y);
625 if constexpr (TrackAdj) {
626 for (
int t = 0; t <
nt; ++t) {
629 const int vt[3] = {
t0[t],
t1[t],
t2[t]};
630 for (
int e = 0; e < 3; ++e)
641 if constexpr (!TrackAdj) {
644 for (
int t = 0; t <
nt; ++t) {
647 const int vt[3] = {
t0[t],
t1[t],
t2[t]};
648 for (
int e = 0; e < 3; ++e) {
649 const int x = vt[e], y = vt[(e + 1) % 3];
650 const int s =
adj[t * 3 + e];
651 if (s < 0 || s >=
nt || !
alive[s])
653 const int vs[3] = {
t0[s],
t1[s],
t2[s]};
654 const bool hasX = (vs[0] == x || vs[1] == x || vs[2] == x);
655 const bool hasY = (vs[0] == y || vs[1] == y || vs[2] == y);
659 for (
int f = 0; f < 3; ++f)
660 if (
adj[s * 3 + f] == t)
671 for (
int s = 0; s <
nt; ++s)
688 KOKKOS_INLINE_FUNCTION
bool clip(
const Real pdir[3], Real d,
int nbr, Real* gapOut =
nullptr) {
700 *gapOut = Real(-1e30);
704 const Real l2 = pdir[0] * pdir[0] + pdir[1] * pdir[1] + pdir[2] * pdir[2];
705 const Real a = (l2 > Real(0)) ? d / l2 : Real(0);
706 n[pi][0] = a * pdir[0];
707 n[pi][1] = a * pdir[1];
708 n[pi][2] = a * pdir[2];
709 nn[pi] =
n[pi][0] *
n[pi][0] +
n[pi][1] *
n[pi][1] +
n[pi][2] *
n[pi][2];
715 Real smax = Real(-1e30);
716 for (
int t = 0; t <
nt; ++t) {
720 const Real s =
n[pi][0] *
vx[t] +
n[pi][1] *
vy[t] +
n[pi][2] *
vz[t] -
nn[pi];
729 const Real nl = Kokkos::sqrt(
nn[pi]);
730 *gapOut = nl > Real(0) ? smax / nl : Real(-1e30);
737 if constexpr (!TrackAdj) {
741 unsigned char nA[MAXT], nB[MAXT];
743 for (
int t = 0; t <
nt; ++t) {
746 const int vtx[3] = {
t0[t],
t1[t],
t2[t]};
747 for (
int e = 0; e < 3; ++e) {
748 const int x = vtx[e], y = vtx[(e + 1) % 3];
750 if (other >= 0 && !kill[other]) {
752 nA[nnew] = (
unsigned char)x;
753 nB[nnew] = (
unsigned char)y;
762 for (
int t = 0; t <
nt; ++t)
766 for (
int i = 0; i < nnew; ++i) {
772 t2[slot] = (
unsigned char)pi;
781 int hA[MAXT], hB[MAXT], hSurv[MAXT],
785 int t0k = -1, e0 = -1;
786 for (
int t = 0; t <
nt && t0k < 0; ++t) {
789 for (
int e = 0; e < 3; ++e) {
790 const int s =
adj[t * 3 + e];
791 if (s >= 0 &&
alive[s] && !kill[s]) {
802 const int vstart[3] = {
t0[t0k],
t1[t0k],
t2[t0k]};
803 int A = vstart[e0], B = vstart[(e0 + 1) % 3];
804 int tt = t0k, ee = e0;
805 const int guardMax = 6 *
nt + 12;
808 const int surv =
adj[tt * 3 + ee];
810 for (
int f = 0; f < 3; ++f)
811 if (
adj[surv * 3 + f] == tt) {
828 int rt = tt, arrival = ee, rotGuard = 0;
830 const int rv[3] = {
t0[rt],
t1[rt],
t2[rt]};
831 const int lv = (rv[0] == pivot) ? 0
832 : (rv[1] == pivot) ? 1
834 const int crossSlot = (arrival == lv) ? (lv + 2) % 3 : lv;
835 const int rn =
adj[rt * 3 + crossSlot];
836 if (rn >= 0 && kill[rn]) {
837 int f = (
adj[rn * 3 + 0] == rt) ? 0 : (
adj[rn * 3 + 1] == rt) ? 1 : 2;
840 if (++rotGuard > guardMax) {
848 const int u = rv[crossSlot], w = rv[(crossSlot + 1) % 3];
850 B = (u == pivot) ? w : u;
857 if (++guard > guardMax) {
861 }
while (!(tt == t0k && ee == e0));
864 for (
int t = 0; t <
nt; ++t)
871 for (
int i = 0; i < H && ok; ++i) {
876 alive[tau[i]] =
true;
879 for (
int i = 0; i < H; ++i) {
880 const int s = tau[i];
881 t0[s] = (
unsigned char)hA[i];
882 t1[s] = (
unsigned char)hB[i];
883 t2[s] = (
unsigned char)pi;
886 adj[s * 3 + 0] = hSurv[i];
887 adj[s * 3 + 1] = tau[(i + 1) % H];
888 adj[s * 3 + 2] = tau[(i - 1 + H) % H];
889 adj[hSurv[i] * 3 + hBack[i]] = s;
896 KOKKOS_INLINE_FUNCTION
bool empty()
const {
897 for (
int t = 0; t <
nt; ++t)
905 for (
int k = 0; k <
np; ++k) {
907 for (
int t = 0; t <
nt && !used; ++t)
908 if (
alive[t] && (
t0[t] == k ||
t1[t] == k ||
t2[t] == k))
926 for (
int t = 0; t <
nt; ++t) {
929 if (
t0[t] != k &&
t1[t] != k &&
t2[t] != k)
941 const Real nx =
n[k][0], ny =
n[k][1], nz =
n[k][2];
942 const Real nlen = Kokkos::sqrt(nx * nx + ny * ny + nz * nz);
945 const Real un[3] = {nx / nlen, ny / nlen, nz / nlen};
947 if (Kokkos::fabs(un[0]) <= Kokkos::fabs(un[1]) && Kokkos::fabs(un[0]) <= Kokkos::fabs(un[2])) {
951 }
else if (Kokkos::fabs(un[1]) <= Kokkos::fabs(un[2])) {
960 const Real e1l = Kokkos::sqrt(e1[0] * e1[0] + e1[1] * e1[1] + e1[2] * e1[2]);
964 const Real e2[3] = {un[1] * e1[2] - un[2] * e1[1], un[2] * e1[0] - un[0] * e1[2],
965 un[0] * e1[1] - un[1] * e1[0]};
966 Real cx = 0, cy = 0, cz = 0;
967 for (
int i = 0; i < m; ++i) {
976 for (
int i = 0; i < m; ++i) {
977 const Real dx = fx[i] - cx, dy = fy[i] - cy, dz = fz[i] - cz;
978 const Real px = dx * e1[0] + dy * e1[1] + dz * e1[2];
979 const Real py = dx * e2[0] + dy * e2[1] + dz * e2[2];
981 const Real s = Kokkos::fabs(px) + Kokkos::fabs(py);
982 const Real t = (s > Real(0)) ? py / s : Real(0);
983 ang[i] = (px < Real(0)) ? (Real(2) - t) : (py < Real(0) ? Real(4) + t : t);
985 for (
int i = 1; i < m; ++i) {
986 const Real ka = ang[i];
987 const int ki = out[i];
989 while (j >= 0 && ang[j] > ka) {
1005 Real fz[
MAXFV])
const {
1008 for (
int i = 0; i < m; ++i) {
1017 KOKKOS_INLINE_FUNCTION
static void polyAreaVec(
const Real fx[],
const Real fy[],
const Real fz[],
1019 Real ax = 0, ay = 0, az = 0;
1020 for (
int i = 0; i < m; ++i) {
1021 const int j = (i + 1 == m) ? 0 : i + 1;
1022 ax += fy[i] * fz[j] - fz[i] * fy[j];
1023 ay += fz[i] * fx[j] - fx[i] * fz[j];
1024 az += fx[i] * fy[j] - fy[i] * fx[j];
1026 A[0] = Real(0.5) * ax;
1027 A[1] = Real(0.5) * ay;
1028 A[2] = Real(0.5) * az;
1045 for (
int i = 0; i <
nt; ++i) {
1048 const Real di = (
vx[i] - p0[0]) * u[0] + (
vy[i] - p0[1]) * u[1] + (
vz[i] - p0[2]) * u[2];
1049 const unsigned char a0 =
t0[i], a1 =
t1[i], a2 =
t2[i];
1050 for (
int j = i + 1; j <
nt; ++j) {
1053 const unsigned char b0 =
t0[j], b1 =
t1[j], b2 =
t2[j];
1054 const int common = (a0 == b0) + (a0 == b1) + (a0 == b2) + (a1 == b0) + (a1 == b1) +
1055 (a1 == b2) + (a2 == b0) + (a2 == b1) + (a2 == b2);
1058 const Real dj = (
vx[j] - p0[0]) * u[0] + (
vy[j] - p0[1]) * u[1] + (
vz[j] - p0[2]) * u[2];
1059 if ((di > Real(0)) == (dj > Real(0)))
1061 const Real denom = di - dj;
1062 if (denom == Real(0))
1064 const Real tt = di / denom;
1067 px[m] =
vx[i] + tt * (
vx[j] -
vx[i]);
1068 py[m] =
vy[i] + tt * (
vy[j] -
vy[i]);
1069 pz[m] =
vz[i] + tt * (
vz[j] -
vz[i]);
1075 const Real ulen = Kokkos::sqrt(u[0] * u[0] + u[1] * u[1] + u[2] * u[2]);
1076 if (ulen == Real(0))
1078 const Real un[3] = {u[0] / ulen, u[1] / ulen, u[2] / ulen};
1080 if (Kokkos::fabs(un[0]) <= Kokkos::fabs(un[1]) && Kokkos::fabs(un[0]) <= Kokkos::fabs(un[2])) {
1084 }
else if (Kokkos::fabs(un[1]) <= Kokkos::fabs(un[2])) {
1093 const Real e1l = Kokkos::sqrt(e1[0] * e1[0] + e1[1] * e1[1] + e1[2] * e1[2]);
1097 const Real e2[3] = {un[1] * e1[2] - un[2] * e1[1], un[2] * e1[0] - un[0] * e1[2],
1098 un[0] * e1[1] - un[1] * e1[0]};
1099 Real cx = 0, cy = 0, cz = 0;
1100 for (
int i = 0; i < m; ++i) {
1109 for (
int i = 0; i < m; ++i) {
1110 const Real dx = px[i] - cx, dy = py[i] - cy, dz = pz[i] - cz;
1111 const Real qx = dx * e1[0] + dy * e1[1] + dz * e1[2];
1112 const Real qy = dx * e2[0] + dy * e2[1] + dz * e2[2];
1113 const Real s = Kokkos::fabs(qx) + Kokkos::fabs(qy);
1114 const Real tt = (s > Real(0)) ? qy / s : Real(0);
1115 ang[i] = (qx < Real(0)) ? (Real(2) - tt) : (qy < Real(0) ? Real(4) + tt : tt);
1117 for (
int i = 1; i < m; ++i) {
1118 Real ka = ang[i], kx = px[i], ky = py[i], kz = pz[i];
1120 while (j >= 0 && ang[j] > ka) {
1121 ang[j + 1] = ang[j];
1140 for (
int k = 0; k <
np; ++k) {
1146 const Real area = Kokkos::sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2]);
1147 const Real support = Kokkos::sqrt(
nn[k]);
1148 vol += support * area;
1150 return vol * (Real(1) / Real(3));
1164 KOKKOS_INLINE_FUNCTION
void planeN(
int k, Real out[3])
const {
1169 KOKKOS_INLINE_FUNCTION
static void xprod(
const Real a[3],
const Real b[3], Real o[3]) {
1170 o[0] = a[1] * b[2] - a[2] * b[1];
1171 o[1] = a[2] * b[0] - a[0] * b[2];
1172 o[2] = a[0] * b[1] - a[1] * b[0];
1174 KOKKOS_INLINE_FUNCTION
static Real
dot3(
const Real a[3],
const Real b[3]) {
1175 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
1177 KOKKOS_INLINE_FUNCTION
static Real
det3(
const Real a[3],
const Real b[3],
const Real c[3]) {
1183 KOKKOS_INLINE_FUNCTION
static void edgeFoot(
const Real v[3],
const Real ck[3], Real f[3]) {
1184 const Real c2 =
dot3(ck, ck), s = (c2 > Real(0)) ?
dot3(v, ck) / c2 : Real(0);
1185 f[0] = v[0] - s * ck[0];
1186 f[1] = v[1] - s * ck[1];
1187 f[2] = v[2] - s * ck[2];
1194 for (
int t = 0; t <
nt; ++t) {
1197 Real n1[3], n2[3], n3[3];
1201 Real c1[3], c2[3], c3[3];
1205 Real D =
dot3(n1, c1);
1207 for (
int a = 0; a < 3; ++a) {
1215 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1216 Real f12[3], f23[3], f31[3];
1221 e[0] = n1[0] - n2[0];
1222 e[1] = n1[1] - n2[1];
1223 e[2] = n1[2] - n2[2];
1224 d +=
det3(e, f12, v);
1225 e[0] = n2[0] - n3[0];
1226 e[1] = n2[1] - n3[1];
1227 e[2] = n2[2] - n3[2];
1228 d +=
det3(e, f23, v);
1229 e[0] = n3[0] - n1[0];
1230 e[1] = n3[1] - n1[1];
1231 e[2] = n3[2] - n1[2];
1232 d +=
det3(e, f31, v);
1235 return vol * (Real(1) / Real(6));
1242 for (
int t = 0; t <
nt; ++t) {
1245 int k1 =
t0[t], k2 =
t1[t], k3 =
t2[t];
1246 Real n1[3], n2[3], n3[3];
1250 Real c1[3], c2[3], c3[3];
1254 Real D =
dot3(n1, c1);
1256 for (
int a = 0; a < 3; ++a) {
1268 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1269 Real f12[3], f23[3], f31[3];
1274 g[0] = f12[0] - f31[0];
1275 g[1] = f12[1] - f31[1];
1276 g[2] = f12[2] - f31[2];
1277 area[k1] +=
det3(n1, g, v) / (Real(2) * Kokkos::sqrt(
dot3(n1, n1)));
1278 g[0] = f23[0] - f12[0];
1279 g[1] = f23[1] - f12[1];
1280 g[2] = f23[2] - f12[2];
1281 area[k2] +=
det3(n2, g, v) / (Real(2) * Kokkos::sqrt(
dot3(n2, n2)));
1282 g[0] = f31[0] - f23[0];
1283 g[1] = f31[1] - f23[1];
1284 g[2] = f31[2] - f23[2];
1285 area[k3] +=
det3(n3, g, v) / (Real(2) * Kokkos::sqrt(
dot3(n3, n3)));
1293 const Real fl[3],
const Real v[3],
1294 Real* area, Real* mx, Real* my, Real* mz) {
1295 const Real inv2n = Real(0.5) / Kokkos::sqrt(
dot3(ni, ni));
1296 const Real sa =
det3(ni, ff, v) * inv2n;
1297 const Real sb = -
det3(ni, fl, v) * inv2n;
1298 area[ki] += sa + sb;
1299 mx[ki] += sa * (ni[0] + ff[0] + v[0]) / Real(3) + sb * (ni[0] + v[0] + fl[0]) / Real(3);
1300 my[ki] += sa * (ni[1] + ff[1] + v[1]) / Real(3) + sb * (ni[1] + v[1] + fl[1]) / Real(3);
1301 mz[ki] += sa * (ni[2] + ff[2] + v[2]) / Real(3) + sb * (ni[2] + v[2] + fl[2]) / Real(3);
1310 for (
int t = 0; t <
nt; ++t) {
1313 int k1 =
t0[t], k2 =
t1[t], k3 =
t2[t];
1314 Real n1[3], n2[3], n3[3];
1318 Real c1[3], c2[3], c3[3];
1322 if (
dot3(n1, c1) < Real(0)) {
1323 for (
int a = 0; a < 3; ++a) {
1335 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1336 Real f12[3], f23[3], f31[3];
1352 KOKKOS_INLINE_FUNCTION
static void scatterGradRaw(
int ki,
const Real ni[3],
const Real ff[3],
1353 const Real fl[3],
const Real v[3], Real* dgx,
1354 Real* dgy, Real* dgz) {
1355 const Real sa =
det3(ni, ff, v);
1356 const Real sb = -
det3(ni, fl, v);
1357 const Real da = sa + sb;
1358 const Real momx = sa * (ni[0] + ff[0] + v[0]) / Real(3) + sb * (ni[0] + v[0] + fl[0]) / Real(3);
1359 const Real momy = sa * (ni[1] + ff[1] + v[1]) / Real(3) + sb * (ni[1] + v[1] + fl[1]) / Real(3);
1360 const Real momz = sa * (ni[2] + ff[2] + v[2]) / Real(3) + sb * (ni[2] + v[2] + fl[2]) / Real(3);
1361 dgx[ki] += Real(2) * da * ni[0] - momx;
1362 dgy[ki] += Real(2) * da * ni[1] - momy;
1363 dgz[ki] += Real(2) * da * ni[2] - momz;
1374 KOKKOS_INLINE_FUNCTION
void geomVolumeGrad(Real& vol, Real* dgx, Real* dgy, Real* dgz)
const {
1376 for (
int t = 0; t <
nt; ++t) {
1379 int k1 =
t0[t], k2 =
t1[t], k3 =
t2[t];
1380 Real n1[3], n2[3], n3[3];
1384 Real c1[3], c2[3], c3[3];
1388 if (
dot3(n1, c1) < Real(0)) {
1389 for (
int a = 0; a < 3; ++a) {
1401 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1402 Real f12[3], f23[3], f31[3];
1407 e[0] = n1[0] - n2[0];
1408 e[1] = n1[1] - n2[1];
1409 e[2] = n1[2] - n2[2];
1410 V +=
det3(e, f12, v);
1411 e[0] = n2[0] - n3[0];
1412 e[1] = n2[1] - n3[1];
1413 e[2] = n2[2] - n3[2];
1414 V +=
det3(e, f23, v);
1415 e[0] = n3[0] - n1[0];
1416 e[1] = n3[1] - n1[1];
1417 e[2] = n3[2] - n1[2];
1418 V +=
det3(e, f31, v);
1423 for (
int k = 0; k <
np; ++k) {
1424 const Real inv = (
nn[k] > Real(0)) ? Real(1) / (Real(2) *
nn[k]) : Real(0);
1429 vol = V * (Real(1) / Real(6));
1437 const Real ff[3],
const Real fl[3],
1438 const Real v[3], Real* sa_acc, Real* smx,
1439 Real* smy, Real* smz) {
1440 const Real sa =
det3(ni, ff, v);
1441 const Real sb = -
det3(ni, fl, v);
1442 sa_acc[ki] += sa + sb;
1443 smx[ki] += sa * (ni[0] + ff[0] + v[0]) / Real(3) + sb * (ni[0] + v[0] + fl[0]) / Real(3);
1444 smy[ki] += sa * (ni[1] + ff[1] + v[1]) / Real(3) + sb * (ni[1] + v[1] + fl[1]) / Real(3);
1445 smz[ki] += sa * (ni[2] + ff[2] + v[2]) / Real(3) + sb * (ni[2] + v[2] + fl[2]) / Real(3);
1457 KOKKOS_INLINE_FUNCTION
void geomVolumeArea(Real& vol, Real* avx, Real* avy, Real* avz, Real* dgx,
1458 Real* dgy, Real* dgz)
const {
1460 for (
int t = 0; t <
nt; ++t) {
1463 int k1 =
t0[t], k2 =
t1[t], k3 =
t2[t];
1464 Real n1[3], n2[3], n3[3];
1468 Real c1[3], c2[3], c3[3];
1472 if (
dot3(n1, c1) < Real(0)) {
1473 for (
int a = 0; a < 3; ++a) {
1485 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1486 Real f12[3], f23[3], f31[3];
1491 e[0] = n1[0] - n2[0];
1492 e[1] = n1[1] - n2[1];
1493 e[2] = n1[2] - n2[2];
1494 V +=
det3(e, f12, v);
1495 e[0] = n2[0] - n3[0];
1496 e[1] = n2[1] - n3[1];
1497 e[2] = n2[2] - n3[2];
1498 V +=
det3(e, f23, v);
1499 e[0] = n3[0] - n1[0];
1500 e[1] = n3[1] - n1[1];
1501 e[2] = n3[2] - n1[2];
1502 V +=
det3(e, f31, v);
1508 for (
int k = 0; k <
np; ++k) {
1509 const Real inv = (
nn[k] > Real(0)) ? Real(1) / (Real(2) *
nn[k]) : Real(0);
1510 const Real sa = avx[k];
1511 const Real smx = dgx[k], smy = dgy[k], smz = dgz[k];
1512 dgx[k] = (Real(2) * sa *
n[k][0] - smx) * inv;
1513 dgy[k] = (Real(2) * sa *
n[k][1] - smy) * inv;
1514 dgz[k] = (Real(2) * sa *
n[k][2] - smz) * inv;
1515 avx[k] = sa *
n[k][0] * inv;
1516 avy[k] = sa *
n[k][1] * inv;
1517 avz[k] = sa *
n[k][2] * inv;
1519 vol = V * (Real(1) / Real(6));
1524 KOKKOS_INLINE_FUNCTION
static void edgeCrossAdj(
int j,
int p,
int q,
const Real Nn[3][3],
1525 const Real w[3], Real out[3]) {
1527 xprod(Nn[q], w, out);
1528 }
else if (j == q) {
1530 xprod(Nn[p], w, tm);
1535 out[0] = out[1] = out[2] = Real(0);
1551 Real grad[3][3][3])
const {
1555 int kk[3] = {
t0[t],
t1[t],
t2[t]};
1558 Nn[a][0] =
n[kk[a]][0];
1559 Nn[a][1] =
n[kk[a]][1];
1560 Nn[a][2] =
n[kk[a]][2];
1564 xprod(Nn[1], Nn[2], c01);
1565 if (
dot3(Nn[0], c01) < Real(0)) {
1568 Nn[1][d] = Nn[2][d];
1579 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1580 Real nn3[3], u[3][3];
1582 nn3[a] =
dot3(Nn[a], Nn[a]);
1583 VOR_UNROLL for (
int d = 0; d < 3; ++d) u[a][d] = Real(2) * Nn[a][d] - v[d];
1587 const int eP[3] = {0, 1, 2}, eQ[3] = {1, 2, 0};
1588 Real e[3][3], ecc[3], es[3], F[3][3];
1590 xprod(Nn[eP[m]], Nn[eQ[m]], e[m]);
1591 ecc[m] =
dot3(e[m], e[m]);
1592 const Real evc =
dot3(v, e[m]);
1593 es[m] = (ecc[m] > Real(0)) ? evc / ecc[m] : Real(0);
1594 VOR_UNROLL for (
int d = 0; d < 3; ++d) F[m][d] =
1595 v[d] - es[m] * e[m][d];
1597 const Real D =
dot3(Nn[0], e[1]);
1598 Real g[3][3], den[3];
1600 const int mb = (i + 2) % 3;
1601 VOR_UNROLL for (
int d = 0; d < 3; ++d) g[i][d] = F[i][d] - F[mb][d];
1602 const Real Ni =
det3(Nn[i], g[i], v);
1603 den[i] = Real(2) * Kokkos::sqrt(nn3[i]);
1604 contrib[i] = (den[i] > Real(0)) ? Ni / den[i] : Real(0);
1608 xprod(v, Nn[i], wi);
1610 xprod(Nn[i], g[i], nixg);
1611 const int mb = (i + 2) % 3;
1613 const Real* cj = e[(j + 1) % 3];
1614 Real gN[3] = {0, 0, 0};
1617 xprod(g[i], v, gxv);
1618 VOR_UNROLL for (
int d = 0; d < 3; ++d) gN[d] += gxv[d];
1620 const Real alpha =
dot3(nixg, cj) / D;
1621 VOR_UNROLL for (
int d = 0; d < 3; ++d) gN[d] += alpha * u[j][d];
1624 const int m = (s == 0) ? i : mb;
1625 const Real sgn = (s == 0) ? Real(1) : Real(-1);
1626 const int p = eP[m], q = eQ[m];
1627 const Real cjw =
dot3(cj, wi);
1628 const Real cje =
dot3(cj, e[m]);
1629 const Real emw =
dot3(e[m], wi);
1630 Real eaW[3], eaV[3], eaE[3];
1634 const Real inv_ecc = (ecc[m] > Real(0)) ? Real(1) / ecc[m] : Real(0);
1636 VOR_UNROLL for (
int d = 0; d < 3; ++d) dS[d] =
1637 ((cje / D) * u[j][d] + eaV[d]) * inv_ecc - (es[m] * inv_ecc) * Real(2) * eaE[d];
1639 VOR_UNROLL for (
int d = 0; d < 3; ++d) gN[d] +=
1640 sgn * ((cjw / D) * u[j][d] - emw * dS[d] - es[m] * eaW[d]);
1642 const Real invden = (den[i] > Real(0)) ? Real(1) / den[i] : Real(0);
1643 VOR_UNROLL for (
int d = 0; d < 3; ++d) grad[i][j][d] = gN[d] * invden;
1645 const Real f = (nn3[i] > Real(0)) ? contrib[i] / nn3[i] : Real(0);
1646 VOR_UNROLL for (
int d = 0; d < 3; ++d) grad[i][j][d] -= f * Nn[i][d];
1657 Real grad[3][3][3])
const {
1659 int k1 =
t0[t], k2 =
t1[t], k3 =
t2[t];
1660 Real rn1[3] = {
n[k1][0],
n[k1][1],
n[k1][2]};
1661 Real rn2[3] = {
n[k2][0],
n[k2][1],
n[k2][2]};
1662 Real rn3[3] = {
n[k3][0],
n[k3][1],
n[k3][2]};
1666 xprod(rn2, rn3, cc);
1667 if (
dot3(rn1, cc) < Real(0)) {
1668 for (
int a = 0; a < 3; ++a) {
1681 D n1[3], n2[3], n3[3];
1682 for (
int a = 0; a < 3; ++a) {
1689 D c1[3], c2[3], c3[3];
1695 for (
int a = 0; a < 3; ++a)
1696 v[a] = (nn1 * c1[a] + nn2 * c2[a] + nn3 * c3[a]) / Dd;
1697 D f12[3], f23[3], f31[3];
1703 for (
int a = 0; a < 3; ++a)
1704 g[a] = f12[a] - f31[a];
1706 for (
int a = 0; a < 3; ++a)
1707 g[a] = f23[a] - f12[a];
1709 for (
int a = 0; a < 3; ++a)
1710 g[a] = f31[a] - f23[a];
1712 for (
int i = 0; i < 3; ++i) {
1713 contrib[i] = aa[i].v;
1714 for (
int j = 0; j < 3; ++j)
1715 for (
int c = 0; c < 3; ++c)
1716 grad[i][j][c] = aa[i].d[3 * j + c];
1730 for (
int t = 0; t <
nt; ++t) {
1733 int k1 =
t0[t], k2 =
t1[t], k3 =
t2[t];
1734 Real n1[3], n2[3], n3[3];
1738 Real c1[3], c2[3], c3[3];
1742 if (
dot3(n1, c1) < Real(0)) {
1743 for (
int a = 0; a < 3; ++a) {
1755 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1756 Real f12[3], f23[3], f31[3];
1761 e[0] = n1[0] - n2[0];
1762 e[1] = n1[1] - n2[1];
1763 e[2] = n1[2] - n2[2];
1764 V +=
det3(e, f12, v);
1765 e[0] = n2[0] - n3[0];
1766 e[1] = n2[1] - n3[1];
1767 e[2] = n2[2] - n3[2];
1768 V +=
det3(e, f23, v);
1769 e[0] = n3[0] - n1[0];
1770 e[1] = n3[1] - n1[1];
1771 e[2] = n3[2] - n1[2];
1772 V +=
det3(e, f31, v);
1777 vol = V * (Real(1) / Real(6));
1790 Real conn[3])
const {
1797 const Real r[3] = {Real(2) *
n[k][0], Real(2) *
n[k][1],
1799 if (A[0] * r[0] + A[1] * r[1] + A[2] * r[2] < Real(0)) {
1804 const Real area = Kokkos::sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2]);
1806 Real cx = 0, cy = 0, cz = 0, asum = 0;
1807 for (
int i = 1; i + 1 < m; ++i) {
1808 const Real ux = fx[i] - fx[0], uy = fy[i] - fy[0], uz = fz[i] - fz[0];
1809 const Real wx = fx[i + 1] - fx[0], wy = fy[i + 1] - fy[0], wz = fz[i + 1] - fz[0];
1810 const Real tx = uy * wz - uz * wy, ty = uz * wx - ux * wz, tz = ux * wy - uy * wx;
1811 const Real at = Real(0.5) * Kokkos::sqrt(tx * tx + ty * ty + tz * tz);
1812 cx += at * (fx[0] + fx[i] + fx[i + 1]);
1813 cy += at * (fy[0] + fy[i] + fy[i + 1]);
1814 cz += at * (fz[0] + fz[i] + fz[i + 1]);
1817 const Real inv = asum > Real(0) ? Real(1) / (Real(3) * asum) : Real(0);
1821 const Real s = area / Kokkos::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]);
1825 dv[0] = s * (r[0] - cx);
1826 dv[1] = s * (r[1] - cy);
1827 dv[2] = s * (r[2] - cz);
1842template <
class Real,
int MAXP,
int MAXT,
bool TrackAdj,
class Policy = Voronoi>
1844 const Real L[3],
const Real* relx,
const Real* rely,
1845 const Real* relz,
const int* ids,
int nNbr,
1846 Real wSelf = Real(0),
const Real* weights =
nullptr) {
1848 for (
int i = 0; i < nNbr; ++i) {
1849 const Real n[3] = {relx[i], rely[i], relz[i]};
1850 Real wNbr = Real(0);
1851 if constexpr (Policy::kHasWeightDof)
1853 const Real off = Policy::template offsetFromRel<Real>(n, wSelf, wNbr);
1854 if constexpr (!Policy::kHasWeightDof) {
1858 c.
clip(n, off, ids[i]);
#define VOR_UNROLL
Definition convex_cell.hpp:38
KOKKOS_INLINE_FUNCTION Dual< Real, K > dnum(Real c)
Definition convex_cell.hpp:53
KOKKOS_INLINE_FUNCTION void dedgeFoot(const Dual< Real, K > v[3], const Dual< Real, K > c[3], Dual< Real, K > f[3])
Definition convex_cell.hpp:127
KOKKOS_INLINE_FUNCTION Dual< Real, K > ddet3(const Dual< Real, K > a[3], const Dual< Real, K > b[3], const Dual< Real, K > c[3])
Definition convex_cell.hpp:120
KOKKOS_INLINE_FUNCTION Dual< Real, K > operator-(const Dual< Real, K > &a, const Dual< Real, K > &b)
Definition convex_cell.hpp:75
KOKKOS_INLINE_FUNCTION Dual< Real, K > operator*(const Dual< Real, K > &a, const Dual< Real, K > &b)
Definition convex_cell.hpp:83
KOKKOS_INLINE_FUNCTION Dual< Real, K > operator+(const Dual< Real, K > &a, const Dual< Real, K > &b)
Definition convex_cell.hpp:67
KOKKOS_INLINE_FUNCTION Dual< Real, K > dsqrt(const Dual< Real, K > &a)
Definition convex_cell.hpp:100
KOKKOS_INLINE_FUNCTION Dual< Real, K > dseed(Real c, int s)
Definition convex_cell.hpp:61
KOKKOS_INLINE_FUNCTION Dual< Real, K > ddot(const Dual< Real, K > a[3], const Dual< Real, K > b[3])
Definition convex_cell.hpp:109
KOKKOS_INLINE_FUNCTION void dcross(const Dual< Real, K > a[3], const Dual< Real, K > b[3], Dual< Real, K > o[3])
Definition convex_cell.hpp:113
KOKKOS_INLINE_FUNCTION Dual< Real, K > operator/(const Dual< Real, K > &a, const Dual< Real, K > &b)
Definition convex_cell.hpp:91
Device-native Voronoi tessellation, geometry and finite-volume physics.
Definition convex_cell.hpp:41
KOKKOS_INLINE_FUNCTION void buildConvexCell(ConvexCell< Real, MAXP, MAXT, TrackAdj > &c, const Real L[3], const Real *relx, const Real *rely, const Real *relz, const int *ids, int nNbr, Real wSelf=Real(0), const Real *weights=nullptr)
Definition convex_cell.hpp:1843
The named engine defaults of peclet.voro — one header-level home for every capacity and default the l...
Definition convex_cell.hpp:140
KOKKOS_INLINE_FUNCTION Real volumePerVertex() const
Definition convex_cell.hpp:1192
static constexpr int MAXFV
Definition convex_cell.hpp:916
KOKKOS_INLINE_FUNCTION int findSharing(int self, int x, int y) const
Definition convex_cell.hpp:609
Kokkos::Array< int,(TrackAdj ? MAXT :0) *3 > adj
Definition convex_cell.hpp:172
KOKKOS_INLINE_FUNCTION int compactPlanes()
Definition convex_cell.hpp:548
KOKKOS_INLINE_FUNCTION Real planeGap(const Real pdir[3], Real d) const
Definition convex_cell.hpp:526
KOKKOS_INLINE_FUNCTION bool isLocallyConvexPartners(const unsigned char *poke4, Real tol, int *outPartners, int maxPartners, int &nPartners) const
Definition convex_cell.hpp:456
KOKKOS_INLINE_FUNCTION int faceOrderedIdx(int k, int out[MAXFV]) const
Definition convex_cell.hpp:923
KOKKOS_INLINE_FUNCTION int sectionPolygon(const Real p0[3], const Real u[3], Real px[MAXSV], Real py[MAXSV], Real pz[MAXSV]) const
Definition convex_cell.hpp:1042
KOKKOS_INLINE_FUNCTION void facetMomentsPerVertex(Real *area, Real *mx, Real *my, Real *mz) const
Definition convex_cell.hpp:1308
static KOKKOS_INLINE_FUNCTION void scatterFacetMoment(int ki, const Real ni[3], const Real ff[3], const Real fl[3], const Real v[3], Real *area, Real *mx, Real *my, Real *mz)
Definition convex_cell.hpp:1292
KOKKOS_INLINE_FUNCTION int oppositePlane(int s, int x, int y) const
Definition convex_cell.hpp:381
unsigned char t1[MAXT]
Definition convex_cell.hpp:153
KOKKOS_INLINE_FUNCTION void facetAreasPerVertex(Real *area) const
Definition convex_cell.hpp:1241
static KOKKOS_INLINE_FUNCTION void edgeFoot(const Real v[3], const Real ck[3], Real f[3])
foot of the perpendicular from v onto the edge line of direction ck: v − (v·ck/ck·ck) ck.
Definition convex_cell.hpp:1183
KOKKOS_INLINE_FUNCTION Real faceMoment2(int k) const
Definition convex_cell.hpp:495
static KOKKOS_INLINE_FUNCTION Real dot3(const Real a[3], const Real b[3])
Definition convex_cell.hpp:1174
KOKKOS_INLINE_FUNCTION void initBoxPlanes(Real L0, Real L1, Real L2)
Definition convex_cell.hpp:231
static constexpr bool kTrackAdj
lets templated consumers (store save/load) branch at compile time
Definition convex_cell.hpp:144
KOKKOS_INLINE_FUNCTION void initBox(Real L0, Real L1, Real L2)
Definition convex_cell.hpp:176
static constexpr int kMaxT
dual-triangle (vertex) capacity
Definition convex_cell.hpp:143
bool overflow
set if MAXP/MAXT exceeded -> cell invalid, caller falls back
Definition convex_cell.hpp:157
int nt
triangle high-water mark
Definition convex_cell.hpp:156
Real nn[MAXP]
cached n·n, i.e. the half-space offset (so the cull test is n·x <= nn)
Definition convex_cell.hpp:150
Real n[MAXP][3]
Definition convex_cell.hpp:147
static KOKKOS_INLINE_FUNCTION void polyAreaVec(const Real fx[], const Real fy[], const Real fz[], int m, Real A[3])
Polygon area vector (0.5 Σ vi × v(i+1)) of an ordered face.
Definition convex_cell.hpp:1017
KOKKOS_INLINE_FUNCTION bool isLocallyConvex(const unsigned char *poke4, Real tol) const
Definition convex_cell.hpp:432
KOKKOS_INLINE_FUNCTION void rebuildAdjacency()
Definition convex_cell.hpp:624
KOKKOS_INLINE_FUNCTION int faceOrdered(int k, Real fx[MAXFV], Real fy[MAXFV], Real fz[MAXFV]) const
Definition convex_cell.hpp:1004
Real vy[MAXT]
Definition convex_cell.hpp:154
KOKKOS_INLINE_FUNCTION bool isSelfConsistentPartners(Real tol, int *outPartners, int maxPartners, int &nPartners) const
Definition convex_cell.hpp:345
KOKKOS_INLINE_FUNCTION void geomVolumeAreaGrad(int t, int pl[3], Real contrib[3], Real grad[3][3][3]) const
Definition convex_cell.hpp:1550
KOKKOS_INLINE_FUNCTION bool empty() const
Definition convex_cell.hpp:896
int pnbr[MAXP]
neighbour seed id per plane (<0 => bounding box)
Definition convex_cell.hpp:151
static constexpr int MAXSV
max vertices on a cross-section polygon
Definition convex_cell.hpp:1031
KOKKOS_INLINE_FUNCTION void geomVolumeGrad(Real &vol, Real *dgx, Real *dgy, Real *dgz) const
Definition convex_cell.hpp:1374
KOKKOS_INLINE_FUNCTION Real maxVertexRsq() const
Largest squared dual-vertex radius over live triangles (drives the security radius).
Definition convex_cell.hpp:591
static KOKKOS_INLINE_FUNCTION void edgeCrossAdj(int j, int p, int q, const Real Nn[3][3], const Real w[3], Real out[3])
Definition convex_cell.hpp:1524
KOKKOS_INLINE_FUNCTION bool isSelfConsistent(Real tol) const
Definition convex_cell.hpp:303
KOKKOS_INLINE_FUNCTION bool checkAdjacencyInvariant() const
Definition convex_cell.hpp:640
Real vx[MAXT]
Definition convex_cell.hpp:154
KOKKOS_INLINE_FUNCTION void geometryPerVertex(Real &vol, Real *area, Real *mx, Real *my, Real *mz) const
Definition convex_cell.hpp:1727
KOKKOS_INLINE_FUNCTION int countFaces() const
Definition convex_cell.hpp:903
unsigned char t2[MAXT]
triangle = triple of plane indices
Definition convex_cell.hpp:153
KOKKOS_INLINE_FUNCTION void geomVolumeArea(Real &vol, Real *avx, Real *avy, Real *avz, Real *dgx, Real *dgy, Real *dgz) const
Definition convex_cell.hpp:1457
KOKKOS_INLINE_FUNCTION void computeVertex(int t)
Definition convex_cell.hpp:209
int np
number of planes
Definition convex_cell.hpp:152
KOKKOS_INLINE_FUNCTION bool clip(const Real pdir[3], Real d, int nbr, Real *gapOut=nullptr)
Definition convex_cell.hpp:688
static constexpr int kMaxP
plane capacity (consumers size scratch by these)
Definition convex_cell.hpp:142
KOKKOS_INLINE_FUNCTION Real volume() const
Definition convex_cell.hpp:1137
KOKKOS_INLINE_FUNCTION void geomVolumeAreaGradAD(int t, int pl[3], Real contrib[3], Real grad[3][3][3]) const
Definition convex_cell.hpp:1656
static KOKKOS_INLINE_FUNCTION void scatterAreaMomentRaw(int ki, const Real ni[3], const Real ff[3], const Real fl[3], const Real v[3], Real *sa_acc, Real *smx, Real *smy, Real *smz)
Definition convex_cell.hpp:1436
KOKKOS_INLINE_FUNCTION void planeN(int k, Real out[3]) const
Definition convex_cell.hpp:1164
unsigned char t0[MAXT]
Definition convex_cell.hpp:153
KOKKOS_INLINE_FUNCTION void reevalGeometry(Real sx, Real sy, Real sz, const Real *pos, Real L, Real wSelf=Real(0), const Real *weight=nullptr)
Definition convex_cell.hpp:258
KOKKOS_INLINE_FUNCTION int allocTri()
Definition convex_cell.hpp:670
KOKKOS_INLINE_FUNCTION void computePoke4(unsigned char *out) const
Definition convex_cell.hpp:394
bool alive[MAXT]
triangle live flag
Definition convex_cell.hpp:155
static KOKKOS_INLINE_FUNCTION void scatterGradRaw(int ki, const Real ni[3], const Real ff[3], const Real fl[3], const Real v[3], Real *dgx, Real *dgy, Real *dgz)
Definition convex_cell.hpp:1352
KOKKOS_INLINE_FUNCTION bool facetGeometry(int k, Real areaVec[3], Real dv[3], Real conn[3]) const
Definition convex_cell.hpp:1789
Real vz[MAXT]
cached dual-vertex position per triangle
Definition convex_cell.hpp:154
static KOKKOS_INLINE_FUNCTION Real det3(const Real a[3], const Real b[3], const Real c[3])
Definition convex_cell.hpp:1177
static KOKKOS_INLINE_FUNCTION void xprod(const Real a[3], const Real b[3], Real o[3])
Definition convex_cell.hpp:1169
Definition convex_cell.hpp:48
Real d[K]
Definition convex_cell.hpp:50
Real v
Definition convex_cell.hpp:49