flow 0.4.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
star_elimination.hpp
Go to the documentation of this file.
1
22#ifndef PECLET_FLOW_STAR_ELIMINATION_HPP
23#define PECLET_FLOW_STAR_ELIMINATION_HPP
24
25#include <Kokkos_Core.hpp>
26
27#include "mac_cutcell.hpp" // CCField/CCConst, C3, CCExec, CCMem
28
29namespace peclet::flow {
30
36 Kokkos::View<int*, CCMem> cell;
37 Kokkos::View<float*, CCMem> a; // [slot*6+k]
38};
39
41 StarOverlay ov;
42 ov.cell = Kokkos::View<int*, CCMem>("star_cell", n);
43 ov.a = Kokkos::View<float*, CCMem>("star_a", 6 * n);
44 return ov;
45}
46
48 v %= n;
49 return v < 0 ? v + n : v;
50}
51
57inline int buildStarOverlay(CCConst sdf, CCConst ox, CCConst oy, CCConst oz, C3 ext, int g, C3 nn,
58 const StarOverlay& ov, Kokkos::View<int, CCMem> counter) {
60 Kokkos::deep_copy(counter, 0);
61 const bool fill = ov.cell.extent(0) > 0;
62 using MD = Kokkos::MDRangePolicy<CCExec, Kokkos::Rank<3>>;
63 Kokkos::parallel_for(
64 "peclet::flow::star_build", MD(space, {0, 0, 0}, {nn.x, nn.y, nn.z}),
65 KOKKOS_LAMBDA(int x, int y, int z) {
66 const long sx = 1, sy = ext.x, sz = (long)ext.x * ext.y;
67 const long st[3] = {sx, sy, sz};
68 const long i = (long)(x + g) + (long)(y + g) * sy + (long)(z + g) * sz;
69 if (sdf(i) >= 0.0)
70 return; // fluid-centered: not eliminated
71 CCConst oa[3] = {ox, oy, oz};
72 float av[6];
73 double D = 0.0;
74 for (int a2 = 0; a2 < 3; ++a2) {
75 const double op = oa[a2](i + st[a2]), om = oa[a2](i); // +side face / -side face
76 const bool fp = sdf(i + st[a2]) >= 0.0, fm = sdf(i - st[a2]) >= 0.0;
77 av[2 * a2] = (fp && op > 0.0) ? (float)op : 0.0f;
78 av[2 * a2 + 1] = (fm && om > 0.0) ? (float)om : 0.0f;
79 D += av[2 * a2] + av[2 * a2 + 1];
80 }
81 if (D <= 0.0)
82 return; // no open fluid face: fully decoupled solid cell
83 const int slot = Kokkos::atomic_fetch_add(&counter(), 1);
84 if (fill) {
85 ov.cell(slot) = x + y * nn.x + z * nn.x * nn.y;
86 for (int k = 0; k < 6; ++k)
87 ov.a(slot * 6 + k) = av[k];
88 }
89 });
90 space.fence();
91 auto h = Kokkos::create_mirror_view(counter);
92 Kokkos::deep_copy(h, counter);
93 return h();
94}
95
99inline void starApplyDelta(CCField y, CCConst x, const StarOverlay& ov, int nOv, C3 nn, C3 extY,
100 int gY, C3 extX, int gX) {
101 if (nOv <= 0)
102 return;
104 Kokkos::parallel_for(
105 "peclet::flow::star_apply", Kokkos::RangePolicy<CCExec>(space, 0, nOv),
106 KOKKOS_LAMBDA(int s) {
107 const int inner = ov.cell(s);
108 const int ix = inner % nn.x, iy = (inner / nn.x) % nn.y, iz = inner / (nn.x * nn.y);
109 auto idx = [&](int cx, int cy, int cz, C3 ext, int gb) {
110 return (long)(starWrap(cx, nn.x) + gb) + (long)(starWrap(cy, nn.y) + gb) * ext.x +
111 (long)(starWrap(cz, nn.z) + gb) * (long)ext.x * ext.y;
112 };
113 const int nb[6][3] = {{ix + 1, iy, iz}, {ix - 1, iy, iz}, {ix, iy + 1, iz},
114 {ix, iy - 1, iz}, {ix, iy, iz + 1}, {ix, iy, iz - 1}};
115 double D = 0.0, num = 0.0;
116 double xv[6];
117 for (int k = 0; k < 6; ++k) {
118 const double a = ov.a(s * 6 + k);
119 if (a <= 0.0)
120 continue;
121 xv[k] = x(idx(nb[k][0], nb[k][1], nb[k][2], extX, gX));
122 D += a;
123 num += a * xv[k];
124 }
125 const double phibar = num / D;
126 for (int k = 0; k < 6; ++k) {
127 const double a = ov.a(s * 6 + k);
128 if (a <= 0.0)
129 continue;
130 Kokkos::atomic_add(&y(idx(nb[k][0], nb[k][1], nb[k][2], extY, gY)),
131 a * (xv[k] - phibar));
132 }
133 });
134}
135
143 const StarOverlay& ov, int nOv, C3 nn, C3 ext, int g, C3 extP,
144 int gP) {
145 if (nOv <= 0)
146 return;
148 Kokkos::parallel_for(
149 "peclet::flow::star_correct_faces", Kokkos::RangePolicy<CCExec>(space, 0, nOv),
150 KOKKOS_LAMBDA(int s) {
151 const int inner = ov.cell(s);
152 const int ix = inner % nn.x, iy = (inner / nn.x) % nn.y, iz = inner / (nn.x * nn.y);
153 auto idxP = [&](int cx, int cy, int cz) {
154 return (long)(starWrap(cx, nn.x) + gP) + (long)(starWrap(cy, nn.y) + gP) * extP.x +
155 (long)(starWrap(cz, nn.z) + gP) * (long)extP.x * extP.y;
156 };
157 auto idxF = [&](int cx, int cy, int cz) {
158 return (long)(starWrap(cx, nn.x) + g) + (long)(starWrap(cy, nn.y) + g) * ext.x +
159 (long)(starWrap(cz, nn.z) + g) * (long)ext.x * ext.y;
160 };
161 const int nb[6][3] = {{ix + 1, iy, iz}, {ix - 1, iy, iz}, {ix, iy + 1, iz},
162 {ix, iy - 1, iz}, {ix, iy, iz + 1}, {ix, iy, iz - 1}};
163 double D = 0.0, num = 0.0;
164 for (int k = 0; k < 6; ++k) {
165 const double a = ov.a(s * 6 + k);
166 if (a <= 0.0)
167 continue;
168 D += a;
169 num += a * phi(idxP(nb[k][0], nb[k][1], nb[k][2]));
170 }
171 const double phibar = num / D;
172 CCField fa[3] = {uf, vf, wf};
173 for (int k = 0; k < 6; ++k) {
174 if (ov.a(s * 6 + k) <= 0.0)
175 continue;
176 const int a2 = k / 2;
177 if ((k & 1) == 0) {
178 // + side: face is the LOW face of the + neighbour; s is the LOW cell -> += phibar
179 fa[a2](idxF(nb[k][0], nb[k][1], nb[k][2])) += phibar;
180 } else {
181 // - side: face is s's own LOW face; s is the HIGH cell -> -= phibar
182 fa[a2](idxF(ix, iy, iz)) -= phibar;
183 }
184 }
185 });
186}
187
188} // namespace peclet::flow
189
190#endif // PECLET_FLOW_STAR_ELIMINATION_HPP
flow — portable (Kokkos) cut-cell pressure-operator face openness from an SDF.
StarOverlay starMakeOverlay(long n)
int buildStarOverlay(CCConst sdf, CCConst ox, CCConst oy, CCConst oz, C3 ext, int g, C3 nn, const StarOverlay &ov, Kokkos::View< int, CCMem > counter)
Count + fill the star overlay from the cell-centered sdf and the ORIGINAL (unfiltered) apertures on t...
void starApplyDelta(CCField y, CCConst x, const StarOverlay &ov, int nOv, C3 nn, C3 extY, int gY, C3 extX, int gX)
y += S_star x over the inner cells of the (extY, gY) block, x read from the (extX,...
void starCorrectFaces(CCField uf, CCField vf, CCField wf, CCConst phi, const StarOverlay &ov, int nOv, C3 nn, C3 ext, int g, C3 extP, int gP)
Fix the face correction at fluid|solid faces: projectCorrect applied -(phi_hi - phi_lo) with the soli...
void ibmFillEntry(const OV &o, int list_idx, int c_idx, float sdf_c, const float sdf_n[6], int bc_type, const float *thEx)
Kokkos::View< double *, CCMem > CCField
int starWrap(int v, int n)
Kokkos::DefaultExecutionSpace CCExec
Kokkos::View< const double *, CCMem > CCConst
One entry per eliminated solid-centered cell: packed INNER flat index + the apertures of its (up to 6...
Kokkos::View< float *, CCMem > a
Kokkos::View< int *, CCMem > cell