flow 1.3.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
scalar_cutcell_geometry.hpp
Go to the documentation of this file.
1// Scalar cut-cell geometry: the block kernels that build the per-cell record and the facet overlay
2// of doc/scalar_ibm_design.md §2 / §3 (WO-2) on flow's G = 2 extended block.
3//
4// The geometry itself is core's container-free `peclet::core::scheme` (WO-1): the fan-tetrahedron
5// PL model (`cutCellGeometryFanTet`, `fanFaceAperture`, `snapAperture`) and the probe ladder
6// (`buildProbe`). This header only gathers the 15 PL samples from the cell-centred SDF, runs
7// those kernels over the block and stores the results; the Solver side (ghost exchange, scene
8// body ids, MPI census reduction, lazy build) is `flow_ibm_scalars_cutcell.hpp`.
9//
10// Conventions (§2.2, §3.5):
11// * a corner sample is the mean of its 8 surrounding cell-centred SDF values, summed in a FIXED
12// order keyed to the corner's lowest cell — ((s000+s100)+(s010+s110)) + ((s001+s101)+(s011+
13// s111)), times 0.125 — and a face-centre sample is 0.5 (s_lo + s_hi), so a shared corner or
14// face is the same bits from both cells and on every rank;
15// * the scalar apertures sax/say/saz are SNAPPED (both ends, 1e-3), UNGATED, and one value per
16// face: sa_a(i) is the -a face of cell i, computed from the SDF for every inner cell AND for
17// the high-side face at ghost index ext - G (never exchanged — SCALING_ISSUES #3);
18// * a fluid unknown is kappa > 1e-14 with a snapped aperture sum > 0; a sealed cell is kappa > 0
19// with every snapped aperture 0 (§2.4);
20// * the operator area vector of a facet is the snapped one, A^snap = sum_a A_a (sa_a+ - sa_a-)
21// e_a
22// (single facet; none if |A^snap| < 1e-14 max A_a), or the two PL group vectors with the snap
23// residual A^snap - areaPL added to the larger (two facets) (§2.3); the centroid is the PL one;
24// * facets are compacted in x-fastest inner-cell order (an exclusive scan), so the list is the
25// same on every backend and thread count.
26//
27// The ONLY inputs are the SDF (both ghost layers valid, §2.5) and the internal cell size h'. None
28// of the pressure openness (ox_/oy_/oz_), `cs_` or `cutOwner_` is read or written here.
29#ifndef PECLET_FLOW_SCALAR_CUTCELL_GEOMETRY_HPP
30#define PECLET_FLOW_SCALAR_CUTCELL_GEOMETRY_HPP
31
32#include <cstdint>
33#include <Kokkos_Core.hpp>
34
35#include "mac_cutcell.hpp" // CCField, CCConst, CCExec, CCMem, C3
36#include "peclet/core/scheme/cut_cell_geometry.hpp"
37#include "peclet/core/scheme/probe_flux.hpp"
38#include "policy.hpp"
39
41
42namespace cs = peclet::core::scheme;
43
45inline constexpr double kKappaUnknown = 1e-14;
47inline constexpr double kFacetAreaRel = 1e-14;
48
51 long n = 0;
52 Kokkos::View<long*, CCMem> cell;
53 Kokkos::View<double*, CCMem> alpha;
54 Kokkos::View<double* [3], Kokkos::LayoutLeft, CCMem> normal;
55 Kokkos::View<double* [3], Kokkos::LayoutLeft, CCMem> centroid;
56 Kokkos::View<int*, CCMem> body;
57 Kokkos::View<double*, CCMem> sF;
58 Kokkos::View<int* [8], Kokkos::LayoutLeft, CCMem> offF;
59 Kokkos::View<double* [8], Kokkos::LayoutLeft, CCMem> wF;
60 Kokkos::View<std::uint8_t*, CCMem> rungF;
61 long nCut = 0;
62 Kokkos::View<long*, CCMem> cutCell;
63 Kokkos::View<int*, CCMem> cellFacetStart;
64};
65
71 double sealedVolume = 0.0;
72 long rungs[4] = {0, 0, 0, 0};
75 double fluidVolume = 0.0;
76};
77
86
89template <class V>
90KOKKOS_INLINE_FUNCTION double cornerSample(const V& s, long i0, long sy, long sz) {
91 return (((s(i0) + s(i0 + 1)) + (s(i0 + sy) + s(i0 + 1 + sy))) +
92 ((s(i0 + sz) + s(i0 + 1 + sz)) + (s(i0 + sy + sz) + s(i0 + 1 + sy + sz)))) *
93 0.125;
94}
95
98template <class V>
99KOKKOS_INLINE_FUNCTION void cellSamples(const V& s, long i, long sy, long sz, double corner[8],
100 double face[6], double& centre) {
101 for (int c = 0; c < 8; ++c) {
102 const long i0 =
103 i + (long)((c & 1) - 1) + (long)(((c >> 1) & 1) - 1) * sy + (long)(((c >> 2) & 1) - 1) * sz;
104 corner[c] = cornerSample(s, i0, sy, sz);
105 }
106 const long st[3] = {1, sy, sz};
107 for (int a = 0; a < 3; ++a) {
108 face[2 * a] = 0.5 * (s(i - st[a]) + s(i));
109 face[2 * a + 1] = 0.5 * (s(i) + s(i + st[a]));
110 }
111 centre = s(i);
112}
113
116KOKKOS_INLINE_FUNCTION double lowFaceAperture(const CCConst& s, long i, int a, long sy, long sz) {
117 const long st[3] = {1, sy, sz};
118 const int t1 = (a == 0) ? 1 : 0, t2 = (a == 2) ? 1 : 2;
119 // corner (u on t1, w on t2) of the -a face: lowest cell i - e_a + (u - 1) e_t1 + (w - 1) e_t2
120 auto corner = [&](int u, int w) {
121 return cornerSample(s, i - st[a] + (long)(u - 1) * st[t1] + (long)(w - 1) * st[t2], sy, sz);
122 };
123 const double cc = 0.5 * (s(i - st[a]) + s(i));
124 return cs::snapAperture(
125 cs::fanFaceAperture(corner(0, 0), corner(1, 0), corner(1, 1), corner(0, 1), cc));
126}
127
130inline void buildApertures(CCField sax, CCField say, CCField saz, CCConst sdf, C3 e, int g) {
132 const long sy = e.x, sz = (long)e.x * e.y;
133 const int hx = e.x - g, hy = e.y - g, hz = e.z - g; // the high-face ghost index per axis
134 Kokkos::parallel_for(
135 "peclet::flow::scg_apertures", MDRange3<CCExec>(space, {g, g, g}, {hx + 1, hy + 1, hz + 1}),
136 KOKKOS_LAMBDA(int x, int y, int z) {
137 const long i = (long)x + (long)y * sy + (long)z * sz;
138 if (y < hy && z < hz)
139 sax(i) = lowFaceAperture(sdf, i, 0, sy, sz);
140 if (x < hx && z < hz)
141 say(i) = lowFaceAperture(sdf, i, 1, sy, sz);
142 if (x < hx && y < hy)
143 saz(i) = lowFaceAperture(sdf, i, 2, sy, sz);
144 });
145 space.fence();
146}
147
149template <class V>
150KOKKOS_INLINE_FUNCTION void cellSnapped(const V& sax, const V& say, const V& saz, long i, long sy,
151 long sz, double ap[6]) {
152 ap[0] = sax(i);
153 ap[1] = sax(i + 1);
154 ap[2] = say(i);
155 ap[3] = say(i + sy);
156 ap[4] = saz(i);
157 ap[5] = saz(i + sz);
158}
159
162KOKKOS_INLINE_FUNCTION int cellFacets(const cs::CutCellGeometry& g, const double ap[6],
163 const double h[3], double area[2][3], double cen[2][3]) {
164 double aSnap[3];
165 cs::facetAreaVector(ap, h, aSnap);
166 if (g.nFacet == 1) {
167 double maxA = cs::cutCellFaceArea(0, h);
168 maxA = cs::cutCellFaceArea(1, h) > maxA ? cs::cutCellFaceArea(1, h) : maxA;
169 maxA = cs::cutCellFaceArea(2, h) > maxA ? cs::cutCellFaceArea(2, h) : maxA;
170 const double mag =
171 Kokkos::sqrt(aSnap[0] * aSnap[0] + aSnap[1] * aSnap[1] + aSnap[2] * aSnap[2]);
172 if (mag < kFacetAreaRel * maxA)
173 return 0;
174 for (int d = 0; d < 3; ++d) {
175 area[0][d] = aSnap[d];
176 cen[0][d] = g.facetCentroid[0][d];
177 }
178 return 1;
179 }
180 if (g.nFacet == 2) {
181 double m[2];
182 for (int k = 0; k < 2; ++k)
183 m[k] = g.facetArea[k][0] * g.facetArea[k][0] + g.facetArea[k][1] * g.facetArea[k][1] +
184 g.facetArea[k][2] * g.facetArea[k][2];
185 const int big = m[1] > m[0] ? 1 : 0;
186 for (int k = 0; k < 2; ++k)
187 for (int d = 0; d < 3; ++d) {
188 area[k][d] = g.facetArea[k][d] + (k == big ? aSnap[d] - g.areaPL[d] : 0.0);
189 cen[k][d] = g.facetCentroid[k][d];
190 }
191 return 2;
192 }
193 return 0;
194}
195
197struct CellPass {
198 Kokkos::View<std::int8_t*, CCMem> nfac;
199 Kokkos::View<std::int8_t*, CCMem> kind;
200};
201
205inline void buildCells(CCField kappa, CCField unknown, const CellPass& cp, CCConst sdf, CCConst sax,
206 CCConst say, CCConst saz, C3 e, int g, const double hp[3]) {
208 const long sy = e.x, sz = (long)e.x * e.y;
209 const int nx = e.x - 2 * g, ny = e.y - 2 * g;
210 const double h0 = hp[0], h1 = hp[1], h2 = hp[2];
211 auto nfac = cp.nfac;
212 auto kind = cp.kind;
213 Kokkos::parallel_for(
214 "peclet::flow::scg_cells", MDRange3<CCExec>(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
215 KOKKOS_LAMBDA(int x, int y, int z) {
216 const long i = (long)x + (long)y * sy + (long)z * sz;
217 const long ii = (long)(x - g) + (long)(y - g) * nx + (long)(z - g) * (long)nx * ny;
218 const double h[3] = {h0, h1, h2};
219 double corner[8], face[6], centre;
220 cellSamples(sdf, i, sy, sz, corner, face, centre);
221 const cs::CutCellGeometry gg = cs::cutCellGeometryFanTet(corner, face, centre, h);
222 double ap[6];
223 cellSnapped(sax, say, saz, i, sy, sz, ap);
224 const double apSum = ((ap[0] + ap[1]) + (ap[2] + ap[3])) + (ap[4] + ap[5]);
225 kappa(i) = gg.kappa;
226 unknown(i) = (gg.kappa > kKappaUnknown && apSum > 0.0) ? 1.0 : 0.0;
227 double area[2][3], cen[2][3];
228 nfac(ii) = (std::int8_t)cellFacets(gg, ap, h, area, cen);
229 kind(ii) = (std::int8_t)gg.kind;
230 });
231 space.fence();
232}
233
237 CCConst say, CCConst saz, C3 e, int g, const double hp[3]) {
238 const long nx = e.x - 2 * g, ny = e.y - 2 * g, nz = e.z - 2 * g;
239 const long nInner = nx * ny * nz;
240 auto nfac = cp.nfac;
241 Kokkos::View<long*, CCMem> fStart("peclet::flow::scg_fstart", nInner);
242 Kokkos::View<long*, CCMem> cStart("peclet::flow::scg_cstart", nInner);
243 long totF = 0, totC = 0;
244 Kokkos::parallel_scan(
245 "peclet::flow::scg_scan_facets", Kokkos::RangePolicy<CCExec>(0, nInner),
246 KOKKOS_LAMBDA(const long ii, long& acc, const bool fin) {
247 if (fin)
248 fStart(ii) = acc;
249 acc += (long)nfac(ii);
250 },
251 totF);
252 Kokkos::parallel_scan(
253 "peclet::flow::scg_scan_cut", Kokkos::RangePolicy<CCExec>(0, nInner),
254 KOKKOS_LAMBDA(const long ii, long& acc, const bool fin) {
255 if (fin)
256 cStart(ii) = acc;
257 acc += nfac(ii) > 0 ? 1 : 0;
258 },
259 totC);
260 fo.n = totF;
261 fo.nCut = totC;
262 fo.cell = Kokkos::View<long*, CCMem>("peclet::flow::scg_cell", totF);
263 fo.alpha = Kokkos::View<double*, CCMem>("peclet::flow::scg_alpha", totF);
264 fo.normal = decltype(fo.normal)("peclet::flow::scg_normal", totF);
265 fo.centroid = decltype(fo.centroid)("peclet::flow::scg_centroid", totF);
266 fo.body = Kokkos::View<int*, CCMem>("peclet::flow::scg_body", totF);
267 fo.sF = Kokkos::View<double*, CCMem>("peclet::flow::scg_sF", totF);
268 fo.offF = decltype(fo.offF)("peclet::flow::scg_offF", totF);
269 fo.wF = decltype(fo.wF)("peclet::flow::scg_wF", totF);
270 fo.rungF = Kokkos::View<std::uint8_t*, CCMem>("peclet::flow::scg_rungF", totF);
271 fo.cutCell = Kokkos::View<long*, CCMem>("peclet::flow::scg_cutCell", totC);
272 fo.cellFacetStart = Kokkos::View<int*, CCMem>("peclet::flow::scg_cellFacetStart", totC + 1);
273
275 const long sy = e.x, sz = (long)e.x * e.y;
276 const double h0 = hp[0], h1 = hp[1], h2 = hp[2];
277 const double vol = h0 * h1 * h2;
278 auto fcell = fo.cell;
279 auto falpha = fo.alpha;
280 auto fnormal = fo.normal;
281 auto fcen = fo.centroid;
282 auto cutCell = fo.cutCell;
283 auto cfs = fo.cellFacetStart;
284 Kokkos::parallel_for(
285 "peclet::flow::scg_facets", Kokkos::RangePolicy<CCExec>(space, 0, nInner),
286 KOKKOS_LAMBDA(const long ii) {
287 if (nfac(ii) == 0)
288 return;
289 const long x = ii % nx, y = (ii / nx) % ny, z = ii / (nx * ny);
290 const long i = (x + g) + (y + g) * sy + (z + g) * sz;
291 const double h[3] = {h0, h1, h2};
292 double corner[8], face[6], centre;
293 cellSamples(sdf, i, sy, sz, corner, face, centre);
294 const cs::CutCellGeometry gg = cs::cutCellGeometryFanTet(corner, face, centre, h);
295 double ap[6];
296 cellSnapped(sax, say, saz, i, sy, sz, ap);
297 double area[2][3], cen[2][3];
298 const int nf = cellFacets(gg, ap, h, area, cen);
299 const long f0 = fStart(ii);
300 for (int k = 0; k < nf; ++k) {
301 const long f = f0 + k;
302 const double mag = Kokkos::sqrt(area[k][0] * area[k][0] + area[k][1] * area[k][1] +
303 area[k][2] * area[k][2]);
304 fcell(f) = i;
305 falpha(f) = mag / vol;
306 for (int d = 0; d < 3; ++d) {
307 fnormal(f, d) = area[k][d] / mag;
308 fcen(f, d) = cen[k][d];
309 }
310 }
311 cutCell(cStart(ii)) = i;
312 cfs(cStart(ii)) = (int)f0;
313 });
314 Kokkos::deep_copy(space, Kokkos::subview(cfs, totC), (int)totF);
315 space.fence();
316}
317
322 long base, sy, sz;
323 double sign;
324 KOKKOS_INLINE_FUNCTION bool unknown(int dx, int dy, int dz) const {
325 return unk(base + (long)dx + (long)dy * sy + (long)dz * sz) > 0.5;
326 }
327 KOKKOS_INLINE_FUNCTION double phi(const double xi[3]) const {
328 int b[3];
329 double w[8];
330 cs::trilinearStencil(xi, b, w);
331 double v = 0.0;
332 for (int k = 0; k < 8; ++k)
333 v += w[k] * sdf(base + (long)(b[0] + (k & 1)) + (long)(b[1] + ((k >> 1) & 1)) * sy +
334 (long)(b[2] + (k >> 2)) * sz);
335 return sign * v;
336 }
337};
338
342 const double hp[3]) {
344 const long sy = e.x, sz = (long)e.x * e.y;
345 const double h0 = hp[0], h1 = hp[1], h2 = hp[2];
346 auto fcell = fo.cell;
347 auto fnormal = fo.normal;
348 auto fcen = fo.centroid;
349 auto sF = fo.sF;
350 auto offF = fo.offF;
351 auto wF = fo.wF;
352 auto rungF = fo.rungF;
353 Kokkos::parallel_for(
354 "peclet::flow::scg_fluid_probes", Kokkos::RangePolicy<CCExec>(space, 0, fo.n),
355 KOKKOS_LAMBDA(const long f) {
356 const double h[3] = {h0, h1, h2};
357 const double xw[3] = {fcen(f, 0), fcen(f, 1), fcen(f, 2)};
358 const double n[3] = {fnormal(f, 0), fnormal(f, 1), fnormal(f, 2)};
359 const BlockLookup L{sdf, unknown, fcell(f), sy, sz, 1.0};
360 const cs::ProbeResult r = cs::buildProbe(xw, n, h, L);
361 sF(f) = r.s;
362 rungF(f) = (std::uint8_t)r.rung;
363 for (int k = 0; k < 8; ++k) {
364 const bool used = k < r.n;
365 offF(f, k) =
366 used ? (int)((long)r.off[k][0] + (long)r.off[k][1] * sy + (long)r.off[k][2] * sz) : 0;
367 wF(f, k) = used ? r.w[k] : 0.0;
368 }
369 });
370 space.fence();
371}
372
375inline void zeroGhostSlab(CCField f, C3 e, int g, int face) {
377 const int a = face / 2, s = face % 2;
378 const int ext[3] = {e.x, e.y, e.z};
379 int lo[3] = {0, 0, 0}, hi[3] = {e.x, e.y, e.z};
380 lo[a] = s ? ext[a] - g : 0;
381 hi[a] = s ? ext[a] : g;
382 const long sy = e.x, sz = (long)e.x * e.y;
383 Kokkos::parallel_for(
384 "peclet::flow::scg_zero_ghost",
385 MDRange3<CCExec>(space, {lo[0], lo[1], lo[2]}, {hi[0], hi[1], hi[2]}),
386 KOKKOS_LAMBDA(int x, int y, int z) { f((long)x + (long)y * sy + (long)z * sz) = 0.0; });
387 space.fence();
388}
389
393 CCConst unknown, CCConst sax, CCConst say, CCConst saz, C3 e,
394 int g, double vol) {
397 const long sy = e.x, sz = (long)e.x * e.y;
398 const int nx = e.x - 2 * g, ny = e.y - 2 * g;
399 auto nfac = cp.nfac;
400 auto kind = cp.kind;
401 long nU = 0, nTwo = 0, nThin = 0, nSealed = 0;
402 double vSealed = 0.0;
403 Kokkos::parallel_reduce(
404 "peclet::flow::scg_census_cells",
405 MDRange3<CCExec>(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
406 KOKKOS_LAMBDA(int x, int y, int z, long& u, long& two, long& thin, long& sealed, double& vs) {
407 const long i = (long)x + (long)y * sy + (long)z * sz;
408 const long ii = (long)(x - g) + (long)(y - g) * nx + (long)(z - g) * (long)nx * ny;
409 u += unknown(i) > 0.5 ? 1 : 0;
410 two += nfac(ii) == 2 ? 1 : 0;
411 thin += (nfac(ii) == 2 && kind(ii) == (std::int8_t)cs::CutCellKind::thinSolid) ? 1 : 0;
412 double ap[6];
413 cellSnapped(sax, say, saz, i, sy, sz, ap);
414 const double apSum = ((ap[0] + ap[1]) + (ap[2] + ap[3])) + (ap[4] + ap[5]);
415 if (kappa(i) > 0.0 && apSum == 0.0) {
416 ++sealed;
417 vs += kappa(i) * vol;
418 }
419 },
421 long r[4] = {0, 0, 0, 0};
422 auto rungF = fo.rungF;
423 for (int k = 0; k < 4; ++k) {
424 long cnt = 0;
425 Kokkos::parallel_reduce(
426 "peclet::flow::scg_census_rungs", Kokkos::RangePolicy<CCExec>(space, 0, fo.n),
427 KOKKOS_LAMBDA(const long f, long& acc) { acc += (int)rungF(f) == k ? 1 : 0; }, cnt);
428 r[k] = cnt;
429 }
430 c.numUnknowns = nU;
431 c.numCutCells = fo.nCut;
432 c.numFacets = fo.n;
433 c.numTwoSided = nTwo;
434 c.numThinSolid = nThin;
435 c.numSealed = nSealed;
436 c.sealedVolume = vSealed;
437 for (int k = 0; k < 4; ++k)
438 c.rungs[k] = r[k];
439 // WO-8: the fluid volume, for the §9 sealed-volume warning (its own reduction: the counts
440 // above are untouched)
441 double vFluid = 0.0;
442 Kokkos::parallel_reduce(
443 "peclet::flow::scg_census_volume",
444 MDRange3<CCExec>(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
445 KOKKOS_LAMBDA(int x, int y, int z, double& v) {
446 v += kappa((long)x + (long)y * sy + (long)z * sz) * vol;
447 },
448 vFluid);
449 c.fluidVolume = vFluid;
450 return c;
451}
452
453} // namespace peclet::flow::scg
454
455#endif // PECLET_FLOW_SCALAR_CUTCELL_GEOMETRY_HPP
flow — portable (Kokkos) cut-cell pressure-operator face openness from an SDF.
void cellSamples(const V &s, long i, long sy, long sz, double corner[8], double face[6], double &centre)
The 15 PL samples of the cell at extended linear index i (corner index bx + 2 by + 4 bz,...
double lowFaceAperture(const CCConst &s, long i, int a, long sy, long sz)
The snapped aperture of the -a face of the cell at extended index i (the fan of cs::fanFaceAperture: ...
void cellSnapped(const V &sax, const V &say, const V &saz, long i, long sy, long sz, double ap[6])
The snapped apertures of cell i in face order -x,+x,-y,+y,-z,+z.
void buildFacets(ScalarFacetOverlay &fo, const CellPass &cp, CCConst sdf, CCConst sax, CCConst say, CCConst saz, C3 e, int g, const double hp[3])
Kernel 3 (§2.5): exclusive scans of the facet counts and of the cut-cell indicator in x-fastest inner...
constexpr double kFacetAreaRel
|A^snap| below this times max_a A_a: no facet (§2.3).
void buildFluidProbes(ScalarFacetOverlay &fo, CCConst sdf, CCConst unknown, C3 e, const double hp[3])
Kernel 5 (§2.5, §3.3): the fluid probe ladder of every facet.
int cellFacets(const cs::CutCellGeometry &g, const double ap[6], const double h[3], double area[2][3], double cen[2][3])
The operator facets of one cell (§2.3) from its PL record and snapped apertures: returns the count (0...
double cornerSample(const V &s, long i0, long sy, long sz)
Corner sample: the 8 cells whose lowest is i0, in the fixed order of §2.2.
constexpr double kKappaUnknown
kappa above which a cell with an open face is a fluid unknown (§2.4).
void zeroGhostSlab(CCField f, C3 e, int g, int face)
Zero f on every ghost layer beyond face face (0..5 = -x,+x,-y,+y,-z,+z), full transverse extent: the ...
void buildCells(CCField kappa, CCField unknown, const CellPass &cp, CCConst sdf, CCConst sax, CCConst say, CCConst saz, C3 e, int g, const double hp[3])
Kernel 2 (§2.5): kappa, the unknown flag and the per-cell facet count/kind on the inner cells.
void buildApertures(CCField sax, CCField say, CCField saz, CCConst sdf, C3 e, int g)
Kernel 1 (§2.5): the snapped scalar apertures of every face of every inner cell, including the high-s...
ScalarCutCensus localCensus(const ScalarFacetOverlay &fo, const CellPass &cp, CCConst kappa, CCConst unknown, CCConst sax, CCConst say, CCConst saz, C3 e, int g, double vol)
The census of the record on this rank (not yet summed over ranks); sealedVolume in internal volume un...
Kokkos::View< double *, CCMem > CCField
Kokkos::DefaultExecutionSpace CCExec
Kokkos::View< const double *, CCMem > CCConst
flow — the multidimensional iteration policies: iteration order follows storage.
The block Lookup of cs::buildProbe for one facet's cell: unknown flags (haloed) at lattice offsets,...
bool unknown(int dx, int dy, int dz) const
double phi(const double xi[3]) const
Per-cell flags of the record pass, on the INNER grid (x fastest).
Kokkos::View< std::int8_t *, CCMem > nfac
facets of the cell (0, 1, 2)
Kokkos::View< std::int8_t *, CCMem > kind
cs::CutCellKind of the PL record
The geometry part of diagnostics.scalar_census (§8.2).
double fluidVolume
Sum kappa V over the inner cells (physical after ensureScalarCutGeometry): the reference of the §9 se...
The whole record: per-cell fields on the extended block (kappa and unknown haloed; the apertures comp...
long version
the Solver's geometry version this record was built for
The facet overlay (§3.5): SoA, facet index fastest. Offsets are LINEAR offsets on the block.
Kokkos::View< int *[8], Kokkos::LayoutLeft, CCMem > offF
fluid probe stencil offsets
Kokkos::View< double *[3], Kokkos::LayoutLeft, CCMem > centroid
x_phi - cell centre
Kokkos::View< long *, CCMem > cell
extended-block linear index
Kokkos::View< std::uint8_t *, CCMem > rungF
ladder rung (cs::kProbeR*)
Kokkos::View< int *, CCMem > cellFacetStart
CSR, nCut + 1 entries.
Kokkos::View< double *, CCMem > sF
fluid probe distance
Kokkos::View< int *, CCMem > body
scene instance (0: raw SDF)
Kokkos::View< double *, CCMem > alpha
|A_phi| / V
Kokkos::View< long *, CCMem > cutCell
their extended linear index
Kokkos::View< double *[3], Kokkos::LayoutLeft, CCMem > normal
n_phi (into the fluid)
Kokkos::View< double *[8], Kokkos::LayoutLeft, CCMem > wF
fluid probe weights (0: unused)