24#ifndef PECLET_VORO_CONVEX_CELL_HPP
25#define PECLET_VORO_CONVEX_CELL_HPP
27#include <Kokkos_Core.hpp>
34#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
35#define VOR_UNROLL _Pragma("unroll")
46template <
class Real,
int K>
51template <
class Real,
int K>
55 for (
int i = 0; i < K; ++i)
59template <
class Real,
int K>
65template <
class Real,
int K>
69 for (
int i = 0;
i <
K; ++
i)
73template <
class Real,
int K>
77 for (
int i = 0;
i <
K; ++
i)
81template <
class Real,
int K>
85 for (
int i = 0;
i <
K; ++
i)
86 r.d[
i] =
a.d[
i] *
b.v +
a.v *
b.d[
i];
89template <
class Real,
int K>
94 for (
int i = 0;
i <
K; ++
i)
98template <
class Real,
int K>
101 r.
v = Kokkos::sqrt(
a.v);
103 for (
int i = 0;
i <
K; ++
i)
107template <
class Real,
int K>
109 return a[0] *
b[0] +
a[1] *
b[1] +
a[2] *
b[2];
111template <
class Real,
int K>
114 o[0] =
a[1] *
b[2] -
a[2] *
b[1];
115 o[1] =
a[2] *
b[0] -
a[0] *
b[2];
116 o[2] =
a[0] *
b[1] -
a[1] *
b[0];
118template <
class Real,
int K>
125template <
class Real,
int K>
129 f[0] = v[0] -
s *
c[0];
130 f[1] = v[1] -
s *
c[1];
131 f[2] = v[2] -
s *
c[2];
138template <
class Real,
int MAXP = 64,
int MAXT = 96,
bool TrackAdj = false>
140 static_assert(MAXP <= 255,
"plane index must fit in unsigned char");
150 unsigned char t0[MAXT],
t1[MAXT],
t2[MAXT];
169 Kokkos::Array<int, (TrackAdj ? MAXT : 0) * 3>
adj;
173 KOKKOS_INLINE_FUNCTION
void initBox(Real L0, Real L1, Real L2) {
174 const Real h[3] = {Real(0.5) * L0, Real(0.5) * L1, Real(0.5) * L2};
175 for (
int ax = 0; ax < 3; ++ax) {
176 for (
int s = 0; s < 2; ++s) {
177 const int k = 2 * ax + s;
178 n[k][0] =
n[k][1] =
n[k][2] = 0;
179 n[k][ax] = (s == 0) ? h[ax] : -h[ax];
180 nn[k] = h[ax] * h[ax];
188 for (
int sx = 0; sx < 2; ++sx)
189 for (
int sy = 0; sy < 2; ++sy)
190 for (
int sz = 0; sz < 2; ++sz) {
191 t0[
nt] = (
unsigned char)(0 + sx);
192 t1[
nt] = (
unsigned char)(2 + sy);
193 t2[
nt] = (
unsigned char)(4 + sz);
198 if constexpr (TrackAdj)
207 const Real* a =
n[
t0[t]];
208 const Real* b =
n[
t1[t]];
209 const Real* c =
n[
t2[t]];
210 const Real da =
nn[
t0[t]], db =
nn[
t1[t]], dc =
nn[
t2[t]];
211 const Real bc[3] = {b[1] * c[2] - b[2] * c[1], b[2] * c[0] - b[0] * c[2],
212 b[0] * c[1] - b[1] * c[0]};
213 const Real ca[3] = {c[1] * a[2] - c[2] * a[1], c[2] * a[0] - c[0] * a[2],
214 c[0] * a[1] - c[1] * a[0]};
215 const Real ab[3] = {a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2],
216 a[0] * b[1] - a[1] * b[0]};
217 const Real det = a[0] * bc[0] + a[1] * bc[1] + a[2] * bc[2];
218 const Real inv = det != Real(0) ? Real(1) / det : Real(0);
219 vx[t] = (da * bc[0] + db * ca[0] + dc * ab[0]) * inv;
220 vy[t] = (da * bc[1] + db * ca[1] + dc * ab[1]) * inv;
221 vz[t] = (da * bc[2] + db * ca[2] + dc * ab[2]) * inv;
229 const Real h[3] = {Real(0.5) * L0, Real(0.5) * L1, Real(0.5) * L2};
230 for (
int ax = 0; ax < 3; ++ax)
231 for (
int s = 0; s < 2; ++s) {
232 const int k = 2 * ax + s;
233 n[k][0] =
n[k][1] =
n[k][2] = 0;
234 n[k][ax] = (s == 0) ? h[ax] : -h[ax];
235 nn[k] = h[ax] * h[ax];
254 template <
class Policy = Voronoi>
255 KOKKOS_INLINE_FUNCTION
void reevalGeometry(Real sx, Real sy, Real sz,
const Real* pos, Real L,
256 Real wSelf = Real(0),
const Real* weight =
nullptr) {
257 const Real Lh = Real(0.5) * L;
258 for (
int k = 0; k <
np; ++k) {
261 const int g =
pnbr[k];
262 Real rx = pos[3 * g] - sx, ry = pos[3 * g + 1] - sy, rz = pos[3 * g + 2] - sz;
263 rx = rx > Lh ? rx - L : (rx < -Lh ? rx + L : rx);
264 ry = ry > Lh ? ry - L : (ry < -Lh ? ry + L : ry);
265 rz = rz > Lh ? rz - L : (rz < -Lh ? rz + L : rz);
266 if constexpr (Policy::kHasWeightDof) {
268 const Real r[3] = {rx, ry, rz};
269 const Real rho = rx * rx + ry * ry + rz * rz;
270 const Real off = Policy::template offsetFromRel<Real>(r, wSelf, weight[g]);
271 const Real a = rho > Real(0) ? off / rho : Real(0);
275 nn[k] =
n[k][0] *
n[k][0] +
n[k][1] *
n[k][1] +
n[k][2] *
n[k][2];
278 const Real hx = Real(0.5) * rx, hy = Real(0.5) * ry, hz = Real(0.5) * rz;
282 nn[k] = hx * hx + hy * hy + hz * hz;
285 for (
int t = 0; t <
nt; ++t)
307 for (
int t = 0; t <
nt; ++t) {
310 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
311 for (
int k = 0; k <
np; ++k) {
312 if (
t0[t] == k ||
t1[t] == k ||
t2[t] == k)
314 const Real s =
n[k][0] * v[0] +
n[k][1] * v[1] +
n[k][2] * v[2] -
nn[k];
317 const Real invlen = (
nn[k] > Real(0)) ? Real(1) / Kokkos::sqrt(
nn[k]) : Real(0);
318 maxd = Kokkos::max(maxd, s * invlen);
343 int& nPartners)
const {
345 bool consistent =
true;
346 for (
int t = 0; t <
nt; ++t) {
349 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
350 for (
int k = 0; k <
np; ++k) {
351 if (
t0[t] == k ||
t1[t] == k ||
t2[t] == k)
353 const Real s =
n[k][0] * v[0] +
n[k][1] * v[1] +
n[k][2] * v[2] -
nn[k];
355 const Real invlen = (
nn[k] > Real(0)) ? Real(1) / Kokkos::sqrt(
nn[k]) : Real(0);
356 if (s * invlen > tol) {
358 const int part =
pnbr[k];
361 for (
int q = 0; q < nPartners; ++q)
362 if (outPartners[q] == part) {
366 if (!seen && nPartners < maxPartners)
367 outPartners[nPartners++] = part;
379 const int a =
t0[s], b =
t1[s], c =
t2[s];
380 return (a != x && a != y) ? a : (b != x && b != y) ? b : c;
392 static_assert(TrackAdj,
"computePoke4 requires TrackAdj");
393 for (
int t = 0; t <
nt; ++t) {
395 out[t * 4 + 0] = out[t * 4 + 1] = out[t * 4 + 2] = out[t * 4 + 3] = 0xff;
398 const int vt[3] = {
t0[t],
t1[t],
t2[t]};
400 for (
int e = 0; e < 3; ++e) {
401 const int s =
adj[t * 3 + e];
403 out[t * 4 + e] = (
unsigned char)(eo[e] & 0xff);
405 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
406 Real best = Real(3.4e38);
408 for (
int k = 0; k <
np; ++k) {
409 if (k == vt[0] || k == vt[1] || k == vt[2])
411 if (k == eo[0] || k == eo[1] || k == eo[2])
413 const Real slack =
nn[k] - (
n[k][0] * v[0] +
n[k][1] * v[1] +
n[k][2] * v[2]);
414 if (slack >= Real(0) && slack < best) {
419 out[t * 4 + 3] = (
unsigned char)(g & 0xff);
429 KOKKOS_INLINE_FUNCTION
bool isLocallyConvex(
const unsigned char* poke4, Real tol)
const {
431 for (
int t = 0; t <
nt; ++t) {
434 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
435 for (
int j = 0; j < 4; ++j) {
436 const int k = (int)poke4[t * 4 + j];
439 const Real sl =
n[k][0] * v[0] +
n[k][1] * v[1] +
n[k][2] * v[2] -
nn[k];
441 const Real invlen = (
nn[k] > Real(0)) ? Real(1) / Kokkos::sqrt(
nn[k]) : Real(0);
442 maxd = Kokkos::max(maxd, sl * invlen);
454 int* outPartners,
int maxPartners,
455 int& nPartners)
const {
457 bool consistent =
true;
458 for (
int t = 0; t <
nt; ++t) {
461 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
462 for (
int j = 0; j < 4; ++j) {
463 const int k = (int)poke4[t * 4 + j];
466 const Real sl =
n[k][0] * v[0] +
n[k][1] * v[1] +
n[k][2] * v[2] -
nn[k];
468 const Real invlen = (
nn[k] > Real(0)) ? Real(1) / Kokkos::sqrt(
nn[k]) : Real(0);
469 if (sl * invlen > tol) {
471 const int part =
pnbr[k];
474 for (
int q = 0; q < nPartners; ++q)
475 if (outPartners[q] == part) {
479 if (!seen && nPartners < maxPartners)
480 outPartners[nPartners++] = part;
492 for (
int t = 0; t <
nt; ++t) {
495 const Real r =
vx[t] *
vx[t] +
vy[t] *
vy[t] +
vz[t] *
vz[t];
508 KOKKOS_INLINE_FUNCTION
int findSharing(
int self,
int x,
int y)
const {
509 for (
int s = 0; s <
nt; ++s) {
510 if (s == self || !
alive[s])
512 const int a =
t0[s], b =
t1[s], c =
t2[s];
513 const bool hasX = (a == x || b == x || c == x);
514 const bool hasY = (a == y || b == y || c == y);
524 if constexpr (TrackAdj) {
525 for (
int t = 0; t <
nt; ++t) {
528 const int vt[3] = {
t0[t],
t1[t],
t2[t]};
529 for (
int e = 0; e < 3; ++e)
540 if constexpr (!TrackAdj) {
543 for (
int t = 0; t <
nt; ++t) {
546 const int vt[3] = {
t0[t],
t1[t],
t2[t]};
547 for (
int e = 0; e < 3; ++e) {
548 const int x = vt[e], y = vt[(e + 1) % 3];
549 const int s =
adj[t * 3 + e];
550 if (s < 0 || s >=
nt || !
alive[s])
552 const int vs[3] = {
t0[s],
t1[s],
t2[s]};
553 const bool hasX = (vs[0] == x || vs[1] == x || vs[2] == x);
554 const bool hasY = (vs[0] == y || vs[1] == y || vs[2] == y);
558 for (
int f = 0; f < 3; ++f)
559 if (
adj[s * 3 + f] == t)
570 for (
int s = 0; s <
nt; ++s)
584 KOKKOS_INLINE_FUNCTION
bool clip(
const Real pdir[3], Real d,
int nbr) {
590 const Real l2 = pdir[0] * pdir[0] + pdir[1] * pdir[1] + pdir[2] * pdir[2];
591 const Real a = (l2 > Real(0)) ? d / l2 : Real(0);
592 n[pi][0] = a * pdir[0];
593 n[pi][1] = a * pdir[1];
594 n[pi][2] = a * pdir[2];
595 nn[pi] =
n[pi][0] *
n[pi][0] +
n[pi][1] *
n[pi][1] +
n[pi][2] *
n[pi][2];
601 for (
int t = 0; t <
nt; ++t) {
605 const Real s =
n[pi][0] *
vx[t] +
n[pi][1] *
vy[t] +
n[pi][2] *
vz[t] -
nn[pi];
616 if constexpr (!TrackAdj) {
620 unsigned char nA[MAXT], nB[MAXT];
622 for (
int t = 0; t <
nt; ++t) {
625 const int vtx[3] = {
t0[t],
t1[t],
t2[t]};
626 for (
int e = 0; e < 3; ++e) {
627 const int x = vtx[e], y = vtx[(e + 1) % 3];
629 if (other >= 0 && !kill[other]) {
631 nA[nnew] = (
unsigned char)x;
632 nB[nnew] = (
unsigned char)y;
641 for (
int t = 0; t <
nt; ++t)
645 for (
int i = 0; i < nnew; ++i) {
651 t2[slot] = (
unsigned char)pi;
660 int hA[MAXT], hB[MAXT], hSurv[MAXT],
664 int t0k = -1, e0 = -1;
665 for (
int t = 0; t <
nt && t0k < 0; ++t) {
668 for (
int e = 0; e < 3; ++e) {
669 const int s =
adj[t * 3 + e];
670 if (s >= 0 &&
alive[s] && !kill[s]) {
681 const int vstart[3] = {
t0[t0k],
t1[t0k],
t2[t0k]};
682 int A = vstart[e0], B = vstart[(e0 + 1) % 3];
683 int tt = t0k, ee = e0;
684 const int guardMax = 6 *
nt + 12;
687 const int surv =
adj[tt * 3 + ee];
689 for (
int f = 0; f < 3; ++f)
690 if (
adj[surv * 3 + f] == tt) {
707 int rt = tt, arrival = ee, rotGuard = 0;
709 const int rv[3] = {
t0[rt],
t1[rt],
t2[rt]};
710 const int lv = (rv[0] == pivot) ? 0
711 : (rv[1] == pivot) ? 1
713 const int crossSlot = (arrival == lv) ? (lv + 2) % 3 : lv;
714 const int rn =
adj[rt * 3 + crossSlot];
715 if (rn >= 0 && kill[rn]) {
716 int f = (
adj[rn * 3 + 0] == rt) ? 0 : (
adj[rn * 3 + 1] == rt) ? 1 : 2;
719 if (++rotGuard > guardMax) {
727 const int u = rv[crossSlot], w = rv[(crossSlot + 1) % 3];
729 B = (u == pivot) ? w : u;
736 if (++guard > guardMax) {
740 }
while (!(tt == t0k && ee == e0));
743 for (
int t = 0; t <
nt; ++t)
750 for (
int i = 0; i < H && ok; ++i) {
755 alive[tau[i]] =
true;
758 for (
int i = 0; i < H; ++i) {
759 const int s = tau[i];
760 t0[s] = (
unsigned char)hA[i];
761 t1[s] = (
unsigned char)hB[i];
762 t2[s] = (
unsigned char)pi;
765 adj[s * 3 + 0] = hSurv[i];
766 adj[s * 3 + 1] = tau[(i + 1) % H];
767 adj[s * 3 + 2] = tau[(i - 1 + H) % H];
768 adj[hSurv[i] * 3 + hBack[i]] = s;
775 KOKKOS_INLINE_FUNCTION
bool empty()
const {
776 for (
int t = 0; t <
nt; ++t)
784 for (
int k = 0; k <
np; ++k) {
786 for (
int t = 0; t <
nt && !used; ++t)
787 if (
alive[t] && (
t0[t] == k ||
t1[t] == k ||
t2[t] == k))
802 Real fz[
MAXFV])
const {
804 for (
int t = 0; t <
nt; ++t) {
807 if (
t0[t] != k &&
t1[t] != k &&
t2[t] != k)
818 const Real nx =
n[k][0], ny =
n[k][1], nz =
n[k][2];
819 const Real nlen = Kokkos::sqrt(nx * nx + ny * ny + nz * nz);
822 const Real un[3] = {nx / nlen, ny / nlen, nz / nlen};
824 if (Kokkos::fabs(un[0]) <= Kokkos::fabs(un[1]) && Kokkos::fabs(un[0]) <= Kokkos::fabs(un[2])) {
828 }
else if (Kokkos::fabs(un[1]) <= Kokkos::fabs(un[2])) {
837 const Real e1l = Kokkos::sqrt(e1[0] * e1[0] + e1[1] * e1[1] + e1[2] * e1[2]);
841 const Real e2[3] = {un[1] * e1[2] - un[2] * e1[1], un[2] * e1[0] - un[0] * e1[2],
842 un[0] * e1[1] - un[1] * e1[0]};
843 Real cx = 0, cy = 0, cz = 0;
844 for (
int i = 0; i < m; ++i) {
853 for (
int i = 0; i < m; ++i) {
854 const Real dx = fx[i] - cx, dy = fy[i] - cy, dz = fz[i] - cz;
855 const Real px = dx * e1[0] + dy * e1[1] + dz * e1[2];
856 const Real py = dx * e2[0] + dy * e2[1] + dz * e2[2];
858 const Real s = Kokkos::fabs(px) + Kokkos::fabs(py);
859 const Real t = (s > Real(0)) ? py / s : Real(0);
860 ang[i] = (px < Real(0)) ? (Real(2) - t) : (py < Real(0) ? Real(4) + t : t);
862 for (
int i = 1; i < m; ++i) {
863 Real ka = ang[i], kx = fx[i], ky = fy[i], kz = fz[i];
865 while (j >= 0 && ang[j] > ka) {
881 KOKKOS_INLINE_FUNCTION
static void polyAreaVec(
const Real fx[],
const Real fy[],
const Real fz[],
883 Real ax = 0, ay = 0, az = 0;
884 for (
int i = 0; i < m; ++i) {
885 const int j = (i + 1 == m) ? 0 : i + 1;
886 ax += fy[i] * fz[j] - fz[i] * fy[j];
887 ay += fz[i] * fx[j] - fx[i] * fz[j];
888 az += fx[i] * fy[j] - fy[i] * fx[j];
890 A[0] = Real(0.5) * ax;
891 A[1] = Real(0.5) * ay;
892 A[2] = Real(0.5) * az;
908 for (
int i = 0; i <
nt; ++i) {
911 const Real di = (
vx[i] - p0[0]) * u[0] + (
vy[i] - p0[1]) * u[1] + (
vz[i] - p0[2]) * u[2];
912 const unsigned char a0 =
t0[i], a1 =
t1[i], a2 =
t2[i];
913 for (
int j = i + 1; j <
nt; ++j) {
916 const unsigned char b0 =
t0[j], b1 =
t1[j], b2 =
t2[j];
917 const int common = (a0 == b0) + (a0 == b1) + (a0 == b2) + (a1 == b0) + (a1 == b1) +
918 (a1 == b2) + (a2 == b0) + (a2 == b1) + (a2 == b2);
921 const Real dj = (
vx[j] - p0[0]) * u[0] + (
vy[j] - p0[1]) * u[1] + (
vz[j] - p0[2]) * u[2];
922 if ((di > Real(0)) == (dj > Real(0)))
924 const Real denom = di - dj;
925 if (denom == Real(0))
927 const Real tt = di / denom;
930 px[m] =
vx[i] + tt * (
vx[j] -
vx[i]);
931 py[m] =
vy[i] + tt * (
vy[j] -
vy[i]);
932 pz[m] =
vz[i] + tt * (
vz[j] -
vz[i]);
938 const Real ulen = Kokkos::sqrt(u[0] * u[0] + u[1] * u[1] + u[2] * u[2]);
941 const Real un[3] = {u[0] / ulen, u[1] / ulen, u[2] / ulen};
943 if (Kokkos::fabs(un[0]) <= Kokkos::fabs(un[1]) && Kokkos::fabs(un[0]) <= Kokkos::fabs(un[2])) {
944 e1[0] = 0; e1[1] = -un[2]; e1[2] = un[1];
945 }
else if (Kokkos::fabs(un[1]) <= Kokkos::fabs(un[2])) {
946 e1[0] = -un[2]; e1[1] = 0; e1[2] = un[0];
948 e1[0] = -un[1]; e1[1] = un[0]; e1[2] = 0;
950 const Real e1l = Kokkos::sqrt(e1[0] * e1[0] + e1[1] * e1[1] + e1[2] * e1[2]);
951 e1[0] /= e1l; e1[1] /= e1l; e1[2] /= e1l;
952 const Real e2[3] = {un[1] * e1[2] - un[2] * e1[1], un[2] * e1[0] - un[0] * e1[2],
953 un[0] * e1[1] - un[1] * e1[0]};
954 Real cx = 0, cy = 0, cz = 0;
955 for (
int i = 0; i < m; ++i) { cx += px[i]; cy += py[i]; cz += pz[i]; }
956 cx /= m; cy /= m; cz /= m;
958 for (
int i = 0; i < m; ++i) {
959 const Real dx = px[i] - cx, dy = py[i] - cy, dz = pz[i] - cz;
960 const Real qx = dx * e1[0] + dy * e1[1] + dz * e1[2];
961 const Real qy = dx * e2[0] + dy * e2[1] + dz * e2[2];
962 const Real s = Kokkos::fabs(qx) + Kokkos::fabs(qy);
963 const Real tt = (s > Real(0)) ? qy / s : Real(0);
964 ang[i] = (qx < Real(0)) ? (Real(2) - tt) : (qy < Real(0) ? Real(4) + tt : tt);
966 for (
int i = 1; i < m; ++i) {
967 Real ka = ang[i], kx = px[i], ky = py[i], kz = pz[i];
969 while (j >= 0 && ang[j] > ka) {
971 px[j + 1] = px[j]; py[j + 1] = py[j]; pz[j + 1] = pz[j];
974 ang[j + 1] = ka; px[j + 1] = kx; py[j + 1] = ky; pz[j + 1] = kz;
981 KOKKOS_INLINE_FUNCTION Real
volume()
const {
984 for (
int k = 0; k <
np; ++k) {
990 const Real area = Kokkos::sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2]);
991 const Real support = Kokkos::sqrt(
nn[k]);
992 vol += support * area;
994 return vol * (Real(1) / Real(3));
1008 KOKKOS_INLINE_FUNCTION
void planeN(
int k, Real out[3])
const {
1013 KOKKOS_INLINE_FUNCTION
static void xprod(
const Real a[3],
const Real b[3], Real o[3]) {
1014 o[0] = a[1] * b[2] - a[2] * b[1];
1015 o[1] = a[2] * b[0] - a[0] * b[2];
1016 o[2] = a[0] * b[1] - a[1] * b[0];
1018 KOKKOS_INLINE_FUNCTION
static Real
dot3(
const Real a[3],
const Real b[3]) {
1019 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
1021 KOKKOS_INLINE_FUNCTION
static Real
det3(
const Real a[3],
const Real b[3],
const Real c[3]) {
1027 KOKKOS_INLINE_FUNCTION
static void edgeFoot(
const Real v[3],
const Real ck[3], Real f[3]) {
1028 const Real c2 =
dot3(ck, ck), s = (c2 > Real(0)) ?
dot3(v, ck) / c2 : Real(0);
1029 f[0] = v[0] - s * ck[0];
1030 f[1] = v[1] - s * ck[1];
1031 f[2] = v[2] - s * ck[2];
1038 for (
int t = 0; t <
nt; ++t) {
1041 Real n1[3], n2[3], n3[3];
1045 Real c1[3], c2[3], c3[3];
1049 Real D =
dot3(n1, c1);
1051 for (
int a = 0; a < 3; ++a) {
1059 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1060 Real f12[3], f23[3], f31[3];
1065 e[0] = n1[0] - n2[0];
1066 e[1] = n1[1] - n2[1];
1067 e[2] = n1[2] - n2[2];
1068 d +=
det3(e, f12, v);
1069 e[0] = n2[0] - n3[0];
1070 e[1] = n2[1] - n3[1];
1071 e[2] = n2[2] - n3[2];
1072 d +=
det3(e, f23, v);
1073 e[0] = n3[0] - n1[0];
1074 e[1] = n3[1] - n1[1];
1075 e[2] = n3[2] - n1[2];
1076 d +=
det3(e, f31, v);
1079 return vol * (Real(1) / Real(6));
1086 for (
int t = 0; t <
nt; ++t) {
1089 int k1 =
t0[t], k2 =
t1[t], k3 =
t2[t];
1090 Real n1[3], n2[3], n3[3];
1094 Real c1[3], c2[3], c3[3];
1098 Real D =
dot3(n1, c1);
1100 for (
int a = 0; a < 3; ++a) {
1112 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1113 Real f12[3], f23[3], f31[3];
1118 g[0] = f12[0] - f31[0];
1119 g[1] = f12[1] - f31[1];
1120 g[2] = f12[2] - f31[2];
1121 area[k1] +=
det3(n1, g, v) / (Real(2) * Kokkos::sqrt(
dot3(n1, n1)));
1122 g[0] = f23[0] - f12[0];
1123 g[1] = f23[1] - f12[1];
1124 g[2] = f23[2] - f12[2];
1125 area[k2] +=
det3(n2, g, v) / (Real(2) * Kokkos::sqrt(
dot3(n2, n2)));
1126 g[0] = f31[0] - f23[0];
1127 g[1] = f31[1] - f23[1];
1128 g[2] = f31[2] - f23[2];
1129 area[k3] +=
det3(n3, g, v) / (Real(2) * Kokkos::sqrt(
dot3(n3, n3)));
1137 const Real fl[3],
const Real v[3],
1138 Real* area, Real* mx, Real* my, Real* mz) {
1139 const Real inv2n = Real(0.5) / Kokkos::sqrt(
dot3(ni, ni));
1140 const Real sa =
det3(ni, ff, v) * inv2n;
1141 const Real sb = -
det3(ni, fl, v) * inv2n;
1142 area[ki] += sa + sb;
1143 mx[ki] += sa * (ni[0] + ff[0] + v[0]) / Real(3) + sb * (ni[0] + v[0] + fl[0]) / Real(3);
1144 my[ki] += sa * (ni[1] + ff[1] + v[1]) / Real(3) + sb * (ni[1] + v[1] + fl[1]) / Real(3);
1145 mz[ki] += sa * (ni[2] + ff[2] + v[2]) / Real(3) + sb * (ni[2] + v[2] + fl[2]) / Real(3);
1154 for (
int t = 0; t <
nt; ++t) {
1157 int k1 =
t0[t], k2 =
t1[t], k3 =
t2[t];
1158 Real n1[3], n2[3], n3[3];
1162 Real c1[3], c2[3], c3[3];
1166 if (
dot3(n1, c1) < Real(0)) {
1167 for (
int a = 0; a < 3; ++a) {
1179 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1180 Real f12[3], f23[3], f31[3];
1196 KOKKOS_INLINE_FUNCTION
static void scatterGradRaw(
int ki,
const Real ni[3],
const Real ff[3],
1197 const Real fl[3],
const Real v[3], Real* dgx,
1198 Real* dgy, Real* dgz) {
1199 const Real sa =
det3(ni, ff, v);
1200 const Real sb = -
det3(ni, fl, v);
1201 const Real da = sa + sb;
1202 const Real momx = sa * (ni[0] + ff[0] + v[0]) / Real(3) + sb * (ni[0] + v[0] + fl[0]) / Real(3);
1203 const Real momy = sa * (ni[1] + ff[1] + v[1]) / Real(3) + sb * (ni[1] + v[1] + fl[1]) / Real(3);
1204 const Real momz = sa * (ni[2] + ff[2] + v[2]) / Real(3) + sb * (ni[2] + v[2] + fl[2]) / Real(3);
1205 dgx[ki] += Real(2) * da * ni[0] - momx;
1206 dgy[ki] += Real(2) * da * ni[1] - momy;
1207 dgz[ki] += Real(2) * da * ni[2] - momz;
1218 KOKKOS_INLINE_FUNCTION
void geomVolumeGrad(Real& vol, Real* dgx, Real* dgy, Real* dgz)
const {
1220 for (
int t = 0; t <
nt; ++t) {
1223 int k1 =
t0[t], k2 =
t1[t], k3 =
t2[t];
1224 Real n1[3], n2[3], n3[3];
1228 Real c1[3], c2[3], c3[3];
1232 if (
dot3(n1, c1) < Real(0)) {
1233 for (
int a = 0; a < 3; ++a) {
1245 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1246 Real f12[3], f23[3], f31[3];
1251 e[0] = n1[0] - n2[0];
1252 e[1] = n1[1] - n2[1];
1253 e[2] = n1[2] - n2[2];
1254 V +=
det3(e, f12, v);
1255 e[0] = n2[0] - n3[0];
1256 e[1] = n2[1] - n3[1];
1257 e[2] = n2[2] - n3[2];
1258 V +=
det3(e, f23, v);
1259 e[0] = n3[0] - n1[0];
1260 e[1] = n3[1] - n1[1];
1261 e[2] = n3[2] - n1[2];
1262 V +=
det3(e, f31, v);
1267 for (
int k = 0; k <
np; ++k) {
1268 const Real inv = (
nn[k] > Real(0)) ? Real(1) / (Real(2) *
nn[k]) : Real(0);
1273 vol = V * (Real(1) / Real(6));
1281 const Real ff[3],
const Real fl[3],
1282 const Real v[3], Real* sa_acc, Real* smx,
1283 Real* smy, Real* smz) {
1284 const Real sa =
det3(ni, ff, v);
1285 const Real sb = -
det3(ni, fl, v);
1286 sa_acc[ki] += sa + sb;
1287 smx[ki] += sa * (ni[0] + ff[0] + v[0]) / Real(3) + sb * (ni[0] + v[0] + fl[0]) / Real(3);
1288 smy[ki] += sa * (ni[1] + ff[1] + v[1]) / Real(3) + sb * (ni[1] + v[1] + fl[1]) / Real(3);
1289 smz[ki] += sa * (ni[2] + ff[2] + v[2]) / Real(3) + sb * (ni[2] + v[2] + fl[2]) / Real(3);
1301 KOKKOS_INLINE_FUNCTION
void geomVolumeArea(Real& vol, Real* avx, Real* avy, Real* avz, Real* dgx,
1302 Real* dgy, Real* dgz)
const {
1304 for (
int t = 0; t <
nt; ++t) {
1307 int k1 =
t0[t], k2 =
t1[t], k3 =
t2[t];
1308 Real n1[3], n2[3], n3[3];
1312 Real c1[3], c2[3], c3[3];
1316 if (
dot3(n1, c1) < Real(0)) {
1317 for (
int a = 0; a < 3; ++a) {
1329 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1330 Real f12[3], f23[3], f31[3];
1335 e[0] = n1[0] - n2[0];
1336 e[1] = n1[1] - n2[1];
1337 e[2] = n1[2] - n2[2];
1338 V +=
det3(e, f12, v);
1339 e[0] = n2[0] - n3[0];
1340 e[1] = n2[1] - n3[1];
1341 e[2] = n2[2] - n3[2];
1342 V +=
det3(e, f23, v);
1343 e[0] = n3[0] - n1[0];
1344 e[1] = n3[1] - n1[1];
1345 e[2] = n3[2] - n1[2];
1346 V +=
det3(e, f31, v);
1352 for (
int k = 0; k <
np; ++k) {
1353 const Real inv = (
nn[k] > Real(0)) ? Real(1) / (Real(2) *
nn[k]) : Real(0);
1354 const Real sa = avx[k];
1355 const Real smx = dgx[k], smy = dgy[k], smz = dgz[k];
1356 dgx[k] = (Real(2) * sa *
n[k][0] - smx) * inv;
1357 dgy[k] = (Real(2) * sa *
n[k][1] - smy) * inv;
1358 dgz[k] = (Real(2) * sa *
n[k][2] - smz) * inv;
1359 avx[k] = sa *
n[k][0] * inv;
1360 avy[k] = sa *
n[k][1] * inv;
1361 avz[k] = sa *
n[k][2] * inv;
1363 vol = V * (Real(1) / Real(6));
1368 KOKKOS_INLINE_FUNCTION
static void edgeCrossAdj(
int j,
int p,
int q,
const Real Nn[3][3],
1369 const Real w[3], Real out[3]) {
1371 xprod(Nn[q], w, out);
1372 }
else if (j == q) {
1374 xprod(Nn[p], w, tm);
1379 out[0] = out[1] = out[2] = Real(0);
1395 Real grad[3][3][3])
const {
1399 int kk[3] = {
t0[t],
t1[t],
t2[t]};
1402 Nn[a][0] =
n[kk[a]][0];
1403 Nn[a][1] =
n[kk[a]][1];
1404 Nn[a][2] =
n[kk[a]][2];
1408 xprod(Nn[1], Nn[2], c01);
1409 if (
dot3(Nn[0], c01) < Real(0)) {
1412 Nn[1][d] = Nn[2][d];
1423 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1424 Real nn3[3], u[3][3];
1426 nn3[a] =
dot3(Nn[a], Nn[a]);
1427 VOR_UNROLL for (
int d = 0; d < 3; ++d) u[a][d] = Real(2) * Nn[a][d] - v[d];
1431 const int eP[3] = {0, 1, 2}, eQ[3] = {1, 2, 0};
1432 Real e[3][3], ecc[3], es[3], F[3][3];
1434 xprod(Nn[eP[m]], Nn[eQ[m]], e[m]);
1435 ecc[m] =
dot3(e[m], e[m]);
1436 const Real evc =
dot3(v, e[m]);
1437 es[m] = (ecc[m] > Real(0)) ? evc / ecc[m] : Real(0);
1438 VOR_UNROLL for (
int d = 0; d < 3; ++d) F[m][d] =
1439 v[d] - es[m] * e[m][d];
1441 const Real D =
dot3(Nn[0], e[1]);
1442 Real g[3][3], den[3];
1444 const int mb = (i + 2) % 3;
1445 VOR_UNROLL for (
int d = 0; d < 3; ++d) g[i][d] = F[i][d] - F[mb][d];
1446 const Real Ni =
det3(Nn[i], g[i], v);
1447 den[i] = Real(2) * Kokkos::sqrt(nn3[i]);
1448 contrib[i] = (den[i] > Real(0)) ? Ni / den[i] : Real(0);
1452 xprod(v, Nn[i], wi);
1454 xprod(Nn[i], g[i], nixg);
1455 const int mb = (i + 2) % 3;
1457 const Real* cj = e[(j + 1) % 3];
1458 Real gN[3] = {0, 0, 0};
1461 xprod(g[i], v, gxv);
1462 VOR_UNROLL for (
int d = 0; d < 3; ++d) gN[d] += gxv[d];
1464 const Real alpha =
dot3(nixg, cj) / D;
1465 VOR_UNROLL for (
int d = 0; d < 3; ++d) gN[d] += alpha * u[j][d];
1468 const int m = (s == 0) ? i : mb;
1469 const Real sgn = (s == 0) ? Real(1) : Real(-1);
1470 const int p = eP[m], q = eQ[m];
1471 const Real cjw =
dot3(cj, wi);
1472 const Real cje =
dot3(cj, e[m]);
1473 const Real emw =
dot3(e[m], wi);
1474 Real eaW[3], eaV[3], eaE[3];
1478 const Real inv_ecc = (ecc[m] > Real(0)) ? Real(1) / ecc[m] : Real(0);
1480 VOR_UNROLL for (
int d = 0; d < 3; ++d) dS[d] =
1481 ((cje / D) * u[j][d] + eaV[d]) * inv_ecc - (es[m] * inv_ecc) * Real(2) * eaE[d];
1483 VOR_UNROLL for (
int d = 0; d < 3; ++d) gN[d] +=
1484 sgn * ((cjw / D) * u[j][d] - emw * dS[d] - es[m] * eaW[d]);
1486 const Real invden = (den[i] > Real(0)) ? Real(1) / den[i] : Real(0);
1487 VOR_UNROLL for (
int d = 0; d < 3; ++d) grad[i][j][d] = gN[d] * invden;
1489 const Real f = (nn3[i] > Real(0)) ? contrib[i] / nn3[i] : Real(0);
1490 VOR_UNROLL for (
int d = 0; d < 3; ++d) grad[i][j][d] -= f * Nn[i][d];
1501 Real grad[3][3][3])
const {
1503 int k1 =
t0[t], k2 =
t1[t], k3 =
t2[t];
1504 Real rn1[3] = {
n[k1][0],
n[k1][1],
n[k1][2]};
1505 Real rn2[3] = {
n[k2][0],
n[k2][1],
n[k2][2]};
1506 Real rn3[3] = {
n[k3][0],
n[k3][1],
n[k3][2]};
1510 xprod(rn2, rn3, cc);
1511 if (
dot3(rn1, cc) < Real(0)) {
1512 for (
int a = 0; a < 3; ++a) {
1525 D n1[3], n2[3], n3[3];
1526 for (
int a = 0; a < 3; ++a) {
1533 D c1[3], c2[3], c3[3];
1539 for (
int a = 0; a < 3; ++a)
1540 v[a] = (nn1 * c1[a] + nn2 * c2[a] + nn3 * c3[a]) / Dd;
1541 D f12[3], f23[3], f31[3];
1547 for (
int a = 0; a < 3; ++a)
1548 g[a] = f12[a] - f31[a];
1550 for (
int a = 0; a < 3; ++a)
1551 g[a] = f23[a] - f12[a];
1553 for (
int a = 0; a < 3; ++a)
1554 g[a] = f31[a] - f23[a];
1556 for (
int i = 0; i < 3; ++i) {
1557 contrib[i] = aa[i].v;
1558 for (
int j = 0; j < 3; ++j)
1559 for (
int c = 0; c < 3; ++c)
1560 grad[i][j][c] = aa[i].d[3 * j + c];
1574 for (
int t = 0; t <
nt; ++t) {
1577 int k1 =
t0[t], k2 =
t1[t], k3 =
t2[t];
1578 Real n1[3], n2[3], n3[3];
1582 Real c1[3], c2[3], c3[3];
1586 if (
dot3(n1, c1) < Real(0)) {
1587 for (
int a = 0; a < 3; ++a) {
1599 const Real v[3] = {
vx[t],
vy[t],
vz[t]};
1600 Real f12[3], f23[3], f31[3];
1605 e[0] = n1[0] - n2[0];
1606 e[1] = n1[1] - n2[1];
1607 e[2] = n1[2] - n2[2];
1608 V +=
det3(e, f12, v);
1609 e[0] = n2[0] - n3[0];
1610 e[1] = n2[1] - n3[1];
1611 e[2] = n2[2] - n3[2];
1612 V +=
det3(e, f23, v);
1613 e[0] = n3[0] - n1[0];
1614 e[1] = n3[1] - n1[1];
1615 e[2] = n3[2] - n1[2];
1616 V +=
det3(e, f31, v);
1621 vol = V * (Real(1) / Real(6));
1634 Real conn[3])
const {
1641 const Real r[3] = {Real(2) *
n[k][0], Real(2) *
n[k][1],
1643 if (A[0] * r[0] + A[1] * r[1] + A[2] * r[2] < Real(0)) {
1648 const Real area = Kokkos::sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2]);
1650 Real cx = 0, cy = 0, cz = 0, asum = 0;
1651 for (
int i = 1; i + 1 < m; ++i) {
1652 const Real ux = fx[i] - fx[0], uy = fy[i] - fy[0], uz = fz[i] - fz[0];
1653 const Real wx = fx[i + 1] - fx[0], wy = fy[i + 1] - fy[0], wz = fz[i + 1] - fz[0];
1654 const Real tx = uy * wz - uz * wy, ty = uz * wx - ux * wz, tz = ux * wy - uy * wx;
1655 const Real at = Real(0.5) * Kokkos::sqrt(tx * tx + ty * ty + tz * tz);
1656 cx += at * (fx[0] + fx[i] + fx[i + 1]);
1657 cy += at * (fy[0] + fy[i] + fy[i + 1]);
1658 cz += at * (fz[0] + fz[i] + fz[i + 1]);
1661 const Real inv = asum > Real(0) ? Real(1) / (Real(3) * asum) : Real(0);
1665 const Real s = area / Kokkos::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]);
1669 dv[0] = s * (r[0] - cx);
1670 dv[1] = s * (r[1] - cy);
1671 dv[2] = s * (r[2] - cz);
1686template <
class Real,
int MAXP,
int MAXT,
bool TrackAdj,
class Policy = Voronoi>
1688 const Real L[3],
const Real* relx,
const Real* rely,
1689 const Real* relz,
const int* ids,
int nNbr,
1690 Real wSelf = Real(0),
const Real* weights =
nullptr) {
1692 for (
int i = 0; i < nNbr; ++i) {
1693 const Real n[3] = {relx[i], rely[i], relz[i]};
1694 Real wNbr = Real(0);
1695 if constexpr (Policy::kHasWeightDof) wNbr = weights[i];
1696 const Real off = Policy::template offsetFromRel<Real>(n, wSelf, wNbr);
1697 if constexpr (!Policy::kHasWeightDof) {
1701 c.
clip(n, off, ids[i]);
#define VOR_UNROLL
Definition convex_cell.hpp:37
KOKKOS_INLINE_FUNCTION Dual< Real, K > dnum(Real c)
Definition convex_cell.hpp:52
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:126
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:119
KOKKOS_INLINE_FUNCTION Dual< Real, K > operator-(const Dual< Real, K > &a, const Dual< Real, K > &b)
Definition convex_cell.hpp:74
KOKKOS_INLINE_FUNCTION Dual< Real, K > operator*(const Dual< Real, K > &a, const Dual< Real, K > &b)
Definition convex_cell.hpp:82
KOKKOS_INLINE_FUNCTION Dual< Real, K > operator+(const Dual< Real, K > &a, const Dual< Real, K > &b)
Definition convex_cell.hpp:66
KOKKOS_INLINE_FUNCTION Dual< Real, K > dsqrt(const Dual< Real, K > &a)
Definition convex_cell.hpp:99
KOKKOS_INLINE_FUNCTION Dual< Real, K > dseed(Real c, int s)
Definition convex_cell.hpp:60
KOKKOS_INLINE_FUNCTION Dual< Real, K > ddot(const Dual< Real, K > a[3], const Dual< Real, K > b[3])
Definition convex_cell.hpp:108
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:112
KOKKOS_INLINE_FUNCTION Dual< Real, K > operator/(const Dual< Real, K > &a, const Dual< Real, K > &b)
Definition convex_cell.hpp:90
Definition convex_cell.hpp:40
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:1687
Definition convex_cell.hpp:139
KOKKOS_INLINE_FUNCTION Real volumePerVertex() const
Definition convex_cell.hpp:1036
static constexpr int MAXFV
Definition convex_cell.hpp:795
KOKKOS_INLINE_FUNCTION int findSharing(int self, int x, int y) const
Definition convex_cell.hpp:508
Kokkos::Array< int,(TrackAdj ? MAXT :0) *3 > adj
Definition convex_cell.hpp:169
KOKKOS_INLINE_FUNCTION bool isLocallyConvexPartners(const unsigned char *poke4, Real tol, int *outPartners, int maxPartners, int &nPartners) const
Definition convex_cell.hpp:453
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:905
KOKKOS_INLINE_FUNCTION void facetMomentsPerVertex(Real *area, Real *mx, Real *my, Real *mz) const
Definition convex_cell.hpp:1152
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:1136
KOKKOS_INLINE_FUNCTION int oppositePlane(int s, int x, int y) const
Definition convex_cell.hpp:378
unsigned char t1[MAXT]
Definition convex_cell.hpp:150
KOKKOS_INLINE_FUNCTION void facetAreasPerVertex(Real *area) const
Definition convex_cell.hpp:1085
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:1027
static KOKKOS_INLINE_FUNCTION Real dot3(const Real a[3], const Real b[3])
Definition convex_cell.hpp:1018
KOKKOS_INLINE_FUNCTION void initBoxPlanes(Real L0, Real L1, Real L2)
Definition convex_cell.hpp:228
static constexpr bool kTrackAdj
lets templated consumers (store save/load) branch at compile time
Definition convex_cell.hpp:141
KOKKOS_INLINE_FUNCTION void initBox(Real L0, Real L1, Real L2)
Definition convex_cell.hpp:173
bool overflow
set if MAXP/MAXT exceeded -> cell invalid, caller falls back
Definition convex_cell.hpp:154
int nt
triangle high-water mark
Definition convex_cell.hpp:153
Real nn[MAXP]
cached n·n, i.e. the half-space offset (so the cull test is n·x <= nn)
Definition convex_cell.hpp:147
Real n[MAXP][3]
Definition convex_cell.hpp:144
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:881
KOKKOS_INLINE_FUNCTION bool isLocallyConvex(const unsigned char *poke4, Real tol) const
Definition convex_cell.hpp:429
KOKKOS_INLINE_FUNCTION void rebuildAdjacency()
Definition convex_cell.hpp:523
KOKKOS_INLINE_FUNCTION int faceOrdered(int k, Real fx[MAXFV], Real fy[MAXFV], Real fz[MAXFV]) const
Definition convex_cell.hpp:801
Real vy[MAXT]
Definition convex_cell.hpp:151
KOKKOS_INLINE_FUNCTION bool isSelfConsistentPartners(Real tol, int *outPartners, int maxPartners, int &nPartners) const
Definition convex_cell.hpp:342
KOKKOS_INLINE_FUNCTION void geomVolumeAreaGrad(int t, int pl[3], Real contrib[3], Real grad[3][3][3]) const
Definition convex_cell.hpp:1394
KOKKOS_INLINE_FUNCTION bool empty() const
Definition convex_cell.hpp:775
int pnbr[MAXP]
neighbour seed id per plane (<0 => bounding box)
Definition convex_cell.hpp:148
static constexpr int MAXSV
max vertices on a cross-section polygon
Definition convex_cell.hpp:895
KOKKOS_INLINE_FUNCTION void geomVolumeGrad(Real &vol, Real *dgx, Real *dgy, Real *dgz) const
Definition convex_cell.hpp:1218
KOKKOS_INLINE_FUNCTION Real maxVertexRsq() const
Largest squared dual-vertex radius over live triangles (drives the security radius).
Definition convex_cell.hpp:490
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:1368
KOKKOS_INLINE_FUNCTION bool isSelfConsistent(Real tol) const
Definition convex_cell.hpp:300
KOKKOS_INLINE_FUNCTION bool checkAdjacencyInvariant() const
Definition convex_cell.hpp:539
KOKKOS_INLINE_FUNCTION bool clip(const Real pdir[3], Real d, int nbr)
Definition convex_cell.hpp:584
Real vx[MAXT]
Definition convex_cell.hpp:151
KOKKOS_INLINE_FUNCTION void geometryPerVertex(Real &vol, Real *area, Real *mx, Real *my, Real *mz) const
Definition convex_cell.hpp:1571
KOKKOS_INLINE_FUNCTION int countFaces() const
Definition convex_cell.hpp:782
unsigned char t2[MAXT]
triangle = triple of plane indices
Definition convex_cell.hpp:150
KOKKOS_INLINE_FUNCTION void geomVolumeArea(Real &vol, Real *avx, Real *avy, Real *avz, Real *dgx, Real *dgy, Real *dgz) const
Definition convex_cell.hpp:1301
KOKKOS_INLINE_FUNCTION void computeVertex(int t)
Definition convex_cell.hpp:206
int np
number of planes
Definition convex_cell.hpp:149
KOKKOS_INLINE_FUNCTION Real volume() const
Definition convex_cell.hpp:981
KOKKOS_INLINE_FUNCTION void geomVolumeAreaGradAD(int t, int pl[3], Real contrib[3], Real grad[3][3][3]) const
Definition convex_cell.hpp:1500
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:1280
KOKKOS_INLINE_FUNCTION void planeN(int k, Real out[3]) const
Definition convex_cell.hpp:1008
unsigned char t0[MAXT]
Definition convex_cell.hpp:150
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:255
KOKKOS_INLINE_FUNCTION int allocTri()
Definition convex_cell.hpp:569
KOKKOS_INLINE_FUNCTION void computePoke4(unsigned char *out) const
Definition convex_cell.hpp:391
bool alive[MAXT]
triangle live flag
Definition convex_cell.hpp:152
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:1196
KOKKOS_INLINE_FUNCTION bool facetGeometry(int k, Real areaVec[3], Real dv[3], Real conn[3]) const
Definition convex_cell.hpp:1633
Real vz[MAXT]
cached dual-vertex position per triangle
Definition convex_cell.hpp:151
static KOKKOS_INLINE_FUNCTION Real det3(const Real a[3], const Real b[3], const Real c[3])
Definition convex_cell.hpp:1021
static KOKKOS_INLINE_FUNCTION void xprod(const Real a[3], const Real b[3], Real o[3])
Definition convex_cell.hpp:1013
Definition convex_cell.hpp:47
Real d[K]
Definition convex_cell.hpp:49
Real v
Definition convex_cell.hpp:48