11#ifndef PECLET_FLOW_MAC_IBM_HPP
12#define PECLET_FLOW_MAC_IBM_HPP
14#include <Kokkos_Core.hpp>
30using MConst = Kokkos::View<const float*, CCMem>;
49 for (
int k = 0; k < 6; ++k)
89 Kokkos::View<int*, CCMem> idMap, Kokkos::View<int, CCMem> counter,
92 Kokkos::View<int, CCMem> sandwichSkipped = Kokkos::View<int, CCMem>(),
95 Kokkos::deep_copy(space, counter, 0);
96 Kokkos::deep_copy(space, idMap, -1);
97 const bool hasEx = tx.size() > 0;
98 const bool hasSlip = (slipLambda >
mreal(0)) && (comp >= 0) && (SCHEME == 0);
99 const mreal lamBase = slipLambda;
100 const int slipComp = comp;
101 int* skipPtr = sandwichSkipped.data();
102 if (sandwichSkipped.data() !=
nullptr)
103 Kokkos::deep_copy(space, sandwichSkipped, 0);
104 using MD = MDRange3<CCExec>;
105 Kokkos::parallel_for(
106 "peclet::flow::ibm_build_overlay", MD(space, {g, g, g}, {ext.
x - g, ext.
y - g, ext.
z - g}),
107 KOKKOS_LAMBDA(
int lx,
int ly,
int lz) {
108 const long idx = (long)lx + (
long)ly * ext.
x + (long)lz * (
long)ext.
x * ext.
y;
112 const int d[6][3] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}};
114 for (
int k = 0;
k < 6; ++
k)
116 lz + d[k][2] +
off.z);
119 const int slot = Kokkos::atomic_fetch_add(&counter(), 1);
127 const int ix = lx -
g, iy = ly -
g, iz = lz -
g;
128 auto wrap = [](
int v,
int n) {
130 return v < 0 ?
v +
n :
v;
133 for (
int a = 0;
a < 3; ++
a) {
134 const long ip = (long)ix + (
long)iy * nn.x + (long)iz * (
long)nn.x * nn.y;
135 const int mx =
a == 0 ? wrap(ix - 1, nn.x) : ix;
136 const int my =
a == 1 ? wrap(iy - 1, nn.y) : iy;
137 const int mz =
a == 2 ? wrap(iz - 1, nn.z) : iz;
138 const long im = (long)mx + (
long)my * nn.x + (long)mz * (
long)nn.x * nn.y;
139 thEx[2 *
a] = (
mreal)(*ta[a])(ip);
143 const mreal hpv[3] = {hpx, hpy, hpz};
148 const mreal gx =
mreal(0.5) * (sn[0] - sn[1]) / hpv[0],
149 gy =
mreal(0.5) * (sn[2] - sn[3]) / hpv[1],
150 gz =
mreal(0.5) * (sn[4] - sn[5]) / hpv[2];
151 mreal gm = Kokkos::sqrt(gx * gx + gy * gy + gz * gz);
152 if (gm <
mreal(1e-6))
154 const mreal nrm[3] = {gx / gm, gy / gm, gz / gm};
155 mreal tang =
mreal(1) - nrm[slipComp] * nrm[slipComp];
158 const mreal lamEff = lamBase * tang;
159 for (
int a = 0;
a < 3; ++
a) {
160 mreal na = Kokkos::fabs(nrm[a]);
161 if (na <
mreal(1e-3))
163 lamAxis[
a] = lamEff / (hpv[
a] *
na);
166 ibmFillEntry<SCHEME>(ov, slot, (
int)idx, sc, sn, bc_type, hasEx ? thEx : nullptr,
167 hasSlip ? lamAxis : nullptr, skipPtr);
171 Kokkos::deep_copy(cnt, counter);
189 double hpx = 1.0,
double hpy = 1.0,
double hpz = 1.0,
double wx = 1.0,
190 double wy = 1.0,
double wz = 1.0) {
194 Kokkos::parallel_for(
195 "peclet::flow::ibm_volfrac",
MD(
space, {0, 0, 0}, {ext.
x, ext.
y, ext.
z}),
199 const double t = 0.5 +
sd;
200 theta(i) = t < 0.0 ? 0.0 : (t > 1.0 ? 1.0 : t);
204 Kokkos::parallel_for(
205 "peclet::flow::ibm_volfrac_aniso",
MD(
space, {0, 0, 0}, {ext.
x, ext.
y, ext.
z}),
208 const double px =
lx + off.x, py =
ly + off.y, pz =
lz + off.z;
223 const double gm = Kokkos::sqrt(
gx *
gx +
gy *
gy +
gz *
gz);
226 const double nx =
gx / gm, ny =
gy / gm, nz =
gz / gm;
227 mm = Kokkos::sqrt(nx * nx *
wx + ny * ny *
wy + nz * nz *
wz);
229 const double t = 0.5 +
sd *
mm;
230 theta(i) = t < 0.0 ? 0.0 : (t > 1.0 ? 1.0 : t);
252 Kokkos::parallel_for(
253 "peclet::flow::ibm_solid",
MD(
space, {0, 0, 0}, {ext.
x, ext.
y, ext.
z}),
257 mask(i) = (
sd <= 0.0) ? 1.0 : 0.0;
265 Kokkos::parallel_for(
266 "peclet::flow::ibm_clean",
MD(
space, {0, 0, 0}, {ext.
x, ext.
y, ext.
z}),
270 const int d[6][3] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}};
272 for (
int k = 0; k < 6; ++k)
274 lz + d[k][2] + off.z);
275 const bool solid = (sc <=
mreal(0));
276 m(i) = (solid ||
ibmIsCut(sc,
sn)) ? 0.0 : 1.0;
291 if constexpr (std::is_same_v<typename CCExec::memory_space, Kokkos::HostSpace>) {
292 const int nyi = ext.
y - 2 * g,
nzi = ext.
z - 2 * g;
293 Kokkos::parallel_for(
294 "peclet::flow::ibm_rbgs", Kokkos::RangePolicy<CCExec>(
space, 0, (
long)
nyi *
nzi),
296 const int ly = g + (int)(t %
nyi),
lz = g + (int)(t /
nyi);
297 const long sx = 1, sy = ext.
x, sz = (
long)ext.
x * ext.
y;
298 const int P = (
color + og.x + og.y +
ly + og.z +
lz) & 1;
299 for (
int lx = g + ((P ^ (g & 1)) & 1);
lx < ext.
x - g;
lx += 2) {
305 const double ac =
AC(i);
306 if (Kokkos::fabs(
ac) < 1e-30)
311 x(i) = (b(i) - s) /
ac;
317 Kokkos::parallel_for(
318 "peclet::flow::ibm_rbgs",
MD(
space, {g, g, g}, {ext.
x - g, ext.
y - g, ext.
z - g}),
320 if (((og.x +
lx + og.y +
ly + og.z +
lz) & 1) !=
color)
322 const long sx = 1, sy = ext.
x, sz = (
long)ext.
x * ext.
y;
328 const double ac =
AC(i);
329 if (Kokkos::fabs(
ac) < 1e-30)
334 x(i) = (b(i) - s) /
ac;
347 if constexpr (std::is_same_v<typename CCExec::memory_space, Kokkos::HostSpace>) {
348 const int nyi = ext.
y - 2 * g,
nzi = ext.
z - 2 * g;
349 Kokkos::parallel_reduce(
350 "peclet::flow::ibm_rbgs_du", Kokkos::RangePolicy<CCExec>(
space, 0, (
long)
nyi *
nzi),
352 const int ly = g + (int)(t %
nyi),
lz = g + (int)(t /
nyi);
353 const long sx = 1, sy = ext.
x, sz = (
long)ext.
x * ext.
y;
354 const int P = (
color + og.x + og.y +
ly + og.z +
lz) & 1;
355 for (
int lx = g + ((P ^ (g & 1)) & 1);
lx < ext.
x - g;
lx += 2) {
361 const double ac =
AC(i);
362 if (Kokkos::fabs(
ac) < 1e-30)
367 const double xn = (b(i) - s) /
ac;
368 const double d = Kokkos::fabs(
xn - x(i));
374 Kokkos::Max<double>(du));
378 Kokkos::parallel_reduce(
379 "peclet::flow::ibm_rbgs_du",
MD(
space, {g, g, g}, {ext.
x - g, ext.
y - g, ext.
z - g}),
381 if (((og.x +
lx + og.y +
ly + og.z +
lz) & 1) !=
color)
383 const long sx = 1, sy = ext.
x, sz = (
long)ext.
x * ext.
y;
389 const double ac =
AC(i);
390 if (Kokkos::fabs(
ac) < 1e-30)
395 const double xn = (b(i) - s) /
ac;
396 const double d = Kokkos::fabs(
xn - x(i));
401 Kokkos::Max<double>(du));
418 Kokkos::parallel_for(
423 if (((og.x +
lx + og.y +
ly + og.z +
lz) & 1) !=
color)
425 const long sx = 1, sy = ext.
x, sz = (
long)ext.
x * ext.
y;
431 const double ac =
AC(i);
432 if (Kokkos::fabs(
ac) < 1e-30)
437 x(i) = (b(i) - s) /
ac;
455 Kokkos::parallel_reduce(
460 if (((og.x +
lx + og.y +
ly + og.z +
lz) & 1) !=
color)
462 const long sx = 1, sy = ext.
x, sz = (
long)ext.
x * ext.
y;
468 const double ac =
AC(i);
469 if (Kokkos::fabs(
ac) < 1e-30)
474 const double xn = (b(i) - s) /
ac;
475 const double d = Kokkos::fabs(
xn - x(i));
480 Kokkos::Max<double>(du));
486 ibmRbgsStencilColor(x, b,
AC, AW, AE, AS, AN, AB, AT,
solidmask, ext, og, g, 0);
487 ibmRbgsStencilColor(x, b,
AC, AW, AE, AS, AN, AB, AT,
solidmask, ext, og, g, 1);
flow — portable (Kokkos) Robust-Scaled cut-cell IBM primitives + per-cut-cell overlay build.
flow — portable (Kokkos) cut-cell pressure-operator face openness from an SDF.
flow — portable (Kokkos) geometric multigrid for the cut-cell (variable-openness) pressure Poisson.
Slot slot(const Kokkos::View< double *, CCMem > &ks, int k)
void ibmSolidMask(CCField mask, CCConst sdf, C3 ext, Off3 off)
void ibmCleanFluidMask(CCField m, CCConst sdf, C3 ext, Off3 off)
void ibmVolfrac(CCField theta, CCConst sdf, C3 ext, Off3 off, bool aniso=false, double hpx=1.0, double hpy=1.0, double hpz=1.0, double wx=1.0, double wy=1.0, double wz=1.0)
void ibmRbgsSweep(CCField x, CCConst b, MConst AC, MConst AW, MConst AE, MConst AS, MConst AN, MConst AB, MConst AT, CCConst solidmask, C3 ext, C3 og, int g)
Kokkos::View< double *, CCMem > CCField
bool ibmIsCut(Real sc, const Real sn[6])
void ibmRbgsStencilColorBox(CCField x, CCConst b, MC AC, MC AW, MC AE, MC AS, MC AN, MC AB, MC AT, CCConst solidmask, C3 ext, C3 og, int color, C3 rlo, C3 rhi, C3 slo, C3 shi)
Kokkos::DefaultExecutionSpace CCExec
int buildIbmOverlay(CCConst sdf, C3 ext, int g, Off3 off, int bc_type, const IbmOverlay &ov, Kokkos::View< int *, CCMem > idMap, Kokkos::View< int, CCMem > counter, CCConst tx=CCConst(), CCConst ty=CCConst(), CCConst tz=CCConst(), C3 nn=C3{0, 0, 0}, mreal slipLambda=mreal(0), int comp=-1, Kokkos::View< int, CCMem > sandwichSkipped=Kokkos::View< int, CCMem >(), mreal hpx=mreal(1), mreal hpy=mreal(1), mreal hpz=mreal(1))
slipLambda (WO-V6b, in CELLS, 0 = the validated no-slip closure) + comp (which velocity component thi...
double ibmRbgsStencilColorDuBox(CCField x, CCConst b, MC AC, MC AW, MC AE, MC AS, MC AN, MC AB, MC AT, CCConst solidmask, C3 ext, C3 og, int color, C3 rlo, C3 rhi, C3 slo, C3 shi)
Kokkos::View< const float *, CCMem > MConst
double ccSampleExt(CCConst sdf, C3 ext, double x, double y, double z)
double ibmRbgsStencilColorDu(CCField x, CCConst b, MC AC, MC AW, MC AE, MC AS, MC AN, MC AB, MC AT, CCConst solidmask, C3 ext, C3 og, int g, int color)
void ibmRbgsStencilColor(CCField x, CCConst b, MC AC, MC AW, MC AE, MC AS, MC AN, MC AB, MC AT, CCConst solidmask, C3 ext, C3 og, int g, int color)
Kokkos::View< const double *, CCMem > CCConst
flow — the multidimensional iteration policies: iteration order follows storage.
static constexpr double AC