21#ifndef PECLET_FLOW_VOF_MARCHING_CUBES_FIELD_HPP
22#define PECLET_FLOW_VOF_MARCHING_CUBES_FIELD_HPP
24#include <Kokkos_Core.hpp>
49 void init(
int nx,
int ny,
int nz,
int ghost) {
51 throw std::invalid_argument(
"peclet::flow::vof::VofMcArea: ghost width must be >= 2");
52 if (nx < 1 || ny < 1 || nz < 1)
53 throw std::invalid_argument(
"peclet::flow::vof::VofMcArea: empty block");
56 e_ =
I3{nx + 2 * ghost, ny + 2 * ghost, nz + 2 * ghost};
57 len_ =
static_cast<long>(e_.
x) * e_.
y * e_.
z;
58 dist_ =
SField(
"vof::mc::d", len_);
59 nx_ =
SField(
"vof::mc::nx", len_);
60 ny_ =
SField(
"vof::mc::ny", len_);
61 nz_ =
SField(
"vof::mc::nz", len_);
62 area_ =
SField(
"vof::mc::A", len_);
65 bool ready()
const {
return area_.extent(0) != 0; }
78 throw std::runtime_error(
"peclet::flow::vof::VofMcArea::compute: init() not called");
80 throw std::runtime_error(
"peclet::flow::vof::VofMcArea::compute: mode out of range");
93 const I3 e = e_, n = n_;
95 const long sy = e_.
x, sz =
static_cast<long>(e_.
x) * e_.
y;
96 SField dd = dist_, mx = nx_, my = ny_, mz = nz_;
102 const long i =
L3(x, y, z, e);
110 for (
int kk = -1;
kk <= 1; ++
kk)
111 for (
int jj = -1;
jj <= 1; ++
jj)
112 for (
int ii = -1;
ii <= 1; ++
ii)
116 double un[3] = {0.0, 0.0, 0.0};
119 const double al = plicAlpha(m[0], m[1], m[2], c(i));
130 const I3 e = e_, n = n_;
132 SField dd = dist_, mx = nx_, my = ny_, mz = nz_,
ar = area_;
134 const VofMetric gm =
metric;
135 Kokkos::parallel_for(
138 const long i0 =
L3(x, y, z, e);
143 for (
int kk = -1;
kk <= 1; ++
kk)
144 for (
int jj = -1;
jj <= 1; ++
jj)
145 for (
int ii = -1;
ii <= 1; ++
ii) {
148 if (c(
L3(x +
ii, y +
jj, z +
kk, e)) > 0.5)
156 for (
int oz = -1; oz <= 0; ++oz)
157 for (
int oy = -1; oy <= 0; ++oy)
158 for (
int ox = -1; ox <= 0; ++ox) {
160 for (
int k = 0; k < 8; ++k) {
161 const int bx = k & 1,
by = (k >> 1) & 1,
bz = (k >> 2) & 1;
162 const long j =
L3(x + ox +
bx, y + oy +
by, z + oz +
bz, e);
163 const double cv = c(j);
172 const int lc = (-ox) | ((-oy) << 1) | ((-oz) << 2);
181 const I3 e = e_, n = n_;
186 Kokkos::parallel_reduce(
189 const long i =
L3(x, y, z, e);
190 const double a =
ar(i);
200 s.cells, s.orphanCells, s.area, s.orphanArea);
206 I3 n_{0, 0, 0}, e_{0, 0, 0};
209 SField dist_, nx_, ny_, nz_, area_;
flow — VoF rung V1: Weymouth & Yue (2010) directionally-split, exactly volume-conserving geometric ad...
Interfacial area per cell from the marching-tetrahedra surface of the C = 1/2 level set (or of the PL...
VofMetric metric
The interfacial predicate's wisp threshold — the phase-change driver passes ITS OWN (pcEffInterfaceEp...
Stats census(SField c) const
void planePass(SField c)
The gas-positive centre distance and unit normal of every cell's own PLIC plane, one layer beyond the...
void init(int nx, int ny, int nz, int ghost)
Stats compute(SField c, int mode)
mode is an InterfaceAreaMode in [kAreaMcColour, kAreaMcPlicSplit].
void areaPass(SField c, int src, int dep)
The gather: each inner cell walks the 8 dual cubes it is a corner of and keeps its share.
flow — VoF rung V3 (WO-O): the view-level driver for the curvature cascade.
flow — WO-P3c: the interfacial AREA taken from the CURVATURE cascade's geometry.
flow — portable (Kokkos) MAC stencil operators: Red-Black Gauss-Seidel smoothers + divergence.
flow — WO-P3d: a JOINED interfacial area, from marching tetrahedra on the cell-centre lattice.
double pcCentreDistance(double mx, double my, double mz, double alpha)
Signed distance (in cells) from the CELL CENTRE to the PLIC plane, measured along n and POSITIVE ON T...
bool vofIsInterface(double c, double eps)
wyIsMixed with a wisp threshold: the cell carries an interface only while eps < C < 1 - eps.
@ kMcDepositSplit
clipped to each cell's cube, each cell gets its own piece
@ kMcDepositCentroid
the whole triangle to the cell holding its centroid
@ kAreaMcPlicSplit
the PLIC signed-distance level set, clipped deposit
@ kAreaMcPlic
the PLIC signed-distance level set, centroid deposit
@ kAreaMcColour
the C = 1/2 level set, whole triangles to the centroid's cell
@ kMcSrcColour
the C = 1/2 level set (the WO's design)
@ kMcSrcPlic
the zero of the PLIC-reconstructed signed distance (the smooth variant)
double pcUnitNormal(double mx, double my, double mz, double n[3])
Unit (L2) interface normal from a PLIC normal of any scale.
double mcCubeCornerArea(const McVertex v[8], int lc, int src, int deposit, const VofMetric &g)
The interfacial area inside one dual cube that belongs to its local corner lc.
long L3(int x, int y, int z, I3 e)
Kokkos::DefaultExecutionSpace SExec
Kokkos::View< double *, SMem > SField
flow — VoF phase change (Part II, rungs P0/P1): the container-free kernel set.
flow — thin shim: the container-free VoF PLIC geometric toolbox (rung V0) now live in core.
flow — the multidimensional iteration policies: iteration order follows storage.
One dual-cube corner = one cell centre.
double orphanArea
... the part of it the phase-change consumer would drop
long orphanCells
... of which are NOT interfacial under interfaceEps
double area
the sum this rung exists to get right
long cells
inner cells that received area