flow
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
mac_cutcell.hpp
Go to the documentation of this file.
1
9#ifndef PECLET_FLOW_MAC_CUTCELL_HPP
10#define PECLET_FLOW_MAC_CUTCELL_HPP
11
12#include <Kokkos_Core.hpp>
13#include <Kokkos_MathematicalFunctions.hpp>
14
15namespace peclet::flow {
16
17using CCExec = Kokkos::DefaultExecutionSpace;
18using CCMem = CCExec::memory_space;
19using CCField = Kokkos::View<double*, CCMem>;
20using CCConst = Kokkos::View<const double*, CCMem>;
21
22struct C3 {
23 int x, y, z;
24};
25
26// Masked fluid fraction of a face from its SDF samples (centre + 6 axis neighbours). type 1/2/3 =
27// x/y/z face. (sd<=0 => closed.) Verbatim from cc_fraction_core.
28KOKKOS_INLINE_FUNCTION double ccFractionCore(double sd, double sxp, double sxm, double syp,
29 double sym, double szp, double szm, int type,
30 double dx, double dy, double dz) {
31 if (sd <= 0.0)
32 return 0.0;
33 const double gx = (sxp - sxm) / (2.0 * dx), gy = (syp - sym) / (2.0 * dy),
34 gz = (szp - szm) / (2.0 * dz);
35 double gmag = Kokkos::sqrt(gx * gx + gy * gy + gz * gz);
36 if (gmag < 1e-6)
37 gmag = 1e-6;
38 const double nx = gx / gmag, ny = gy / gmag, nz = gz / gmag;
39 double denom = (type == 1) ? (Kokkos::fabs(ny) * dy + Kokkos::fabs(nz) * dz)
40 : (type == 2) ? (Kokkos::fabs(nx) * dx + Kokkos::fabs(nz) * dz)
41 : (Kokkos::fabs(nx) * dx + Kokkos::fabs(ny) * dy);
42 if (denom < 1e-9)
43 denom = 1e-9;
44 double frac = 0.5 + sd / denom;
45 if (frac < 0.0)
46 frac = 0.0;
47 if (frac > 1.0)
48 frac = 1.0;
49 return frac;
50}
51
52KOKKOS_INLINE_FUNCTION double ccSampleExt(CCConst sdf, C3 ext, double x, double y, double z) {
53 const double fx = Kokkos::floor(x), fy = Kokkos::floor(y), fz = Kokkos::floor(z);
54 const double wx = x - fx, wy = y - fy, wz = z - fz;
55 int x0 = (int)fx, y0 = (int)fy, z0 = (int)fz;
56 auto cl = [](int v, int n) { return v < 0 ? 0 : (v >= n ? n - 1 : v); };
57 const int x1 = cl(x0 + 1, ext.x), y1 = cl(y0 + 1, ext.y), z1 = cl(z0 + 1, ext.z);
58 x0 = cl(x0, ext.x);
59 y0 = cl(y0, ext.y);
60 z0 = cl(z0, ext.z);
61 const long sy = ext.x, sz = static_cast<long>(ext.x) * ext.y;
62 auto F = [&](int xx, int yy, int zz) {
63 return sdf(static_cast<long>(xx) + static_cast<long>(yy) * sy + static_cast<long>(zz) * sz);
64 };
65 const double c00 = F(x0, y0, z0) * (1 - wx) + F(x1, y0, z0) * wx;
66 const double c10 = F(x0, y1, z0) * (1 - wx) + F(x1, y1, z0) * wx;
67 const double c01 = F(x0, y0, z1) * (1 - wx) + F(x1, y0, z1) * wx;
68 const double c11 = F(x0, y1, z1) * (1 - wx) + F(x1, y1, z1) * wx;
69 const double c0 = c00 * (1 - wy) + c10 * wy, c1 = c01 * (1 - wy) + c11 * wy;
70 return c0 * (1 - wz) + c1 * wz;
71}
72
73KOKKOS_INLINE_FUNCTION double ccFaceOpen(CCConst sdf, C3 ext, double fx, double fy, double fz,
74 int type, double dx, double dy, double dz) {
75 const double sd = ccSampleExt(sdf, ext, fx, fy, fz);
76 if (sd <= 0.0)
77 return 0.0;
78 const double e = 1.0;
79 return ccFractionCore(
80 sd, ccSampleExt(sdf, ext, fx + e, fy, fz), ccSampleExt(sdf, ext, fx - e, fy, fz),
81 ccSampleExt(sdf, ext, fx, fy + e, fz), ccSampleExt(sdf, ext, fx, fy - e, fz),
82 ccSampleExt(sdf, ext, fx, fy, fz + e), ccSampleExt(sdf, ext, fx, fy, fz - e), type, dx, dy,
83 dz);
84}
85
86// Fill staggered face openness over the whole extended block (ox[i] = -x face of cell i, etc.).
87inline void buildOpenness(CCField ox, CCField oy, CCField oz, CCConst sdf, C3 ext, double dx,
88 double dy, double dz) {
89 CCExec space;
90 using MD = Kokkos::MDRangePolicy<CCExec, Kokkos::Rank<3>>;
91 Kokkos::parallel_for(
92 "peclet::flow::cc_open", MD(space, {0, 0, 0}, {ext.x, ext.y, ext.z}),
93 KOKKOS_LAMBDA(int lx, int ly, int lz) {
94 const long i = static_cast<long>(lx) + static_cast<long>(ly) * ext.x +
95 static_cast<long>(lz) * static_cast<long>(ext.x) * ext.y;
96 ox(i) = ccFaceOpen(sdf, ext, lx - 0.5, ly, lz, 1, dx, dy, dz);
97 oy(i) = ccFaceOpen(sdf, ext, lx, ly - 0.5, lz, 2, dx, dy, dz);
98 oz(i) = ccFaceOpen(sdf, ext, lx, ly, lz - 0.5, 3, dx, dy, dz);
99 });
100}
101
102} // namespace peclet::flow
103
104#endif // PECLET_FLOW_MAC_CUTCELL_HPP
void buildOpenness(CCField ox, CCField oy, CCField oz, CCConst sdf, C3 ext, double dx, double dy, double dz)
CCExec::memory_space CCMem
double ccFaceOpen(CCConst sdf, C3 ext, double fx, double fy, double fz, int type, double dx, double dy, double dz)
double ccFractionCore(double sd, double sxp, double sxm, double syp, double sym, double szp, double szm, int type, double dx, double dy, double dz)
Kokkos::View< double *, CCMem > CCField
Kokkos::DefaultExecutionSpace CCExec
double ccSampleExt(CCConst sdf, C3 ext, double x, double y, double z)
Kokkos::View< const double *, CCMem > CCConst
static constexpr double F