flow 1.3.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
colour_field.hpp
Go to the documentation of this file.
1
45#ifndef PECLET_FLOW_VOF_COLOUR_FIELD_HPP
46#define PECLET_FLOW_VOF_COLOUR_FIELD_HPP
47
48#include <Kokkos_Core.hpp>
49
50#include "mac_stencils.hpp" // peclet::flow::SExec, SField, I3, L3
51#include "policy.hpp"
52
53namespace peclet::flow::vof {
54
65inline void copyFaceVelocity(SField dst, I3 de, int dg, SField src, I3 se, int sg, int dir) {
66 const int s = dg - sg;
67 const int ox = s - (dir == 0 ? 1 : 0), oy = s - (dir == 1 ? 1 : 0), oz = s - (dir == 2 ? 1 : 0);
68 Kokkos::parallel_for(
69 "vof::copyFaceVelocity", MDRange3<SExec>(SExec(), {0, 0, 0}, {se.x, se.y, se.z}),
70 KOKKOS_LAMBDA(int x, int y, int z) {
71 dst(L3(x + ox, y + oy, z + oz, de)) = src(L3(x, y, z, se));
72 });
73}
74
87inline void copyAdvectedVelocity(SField dst, I3 de, int dg, SField src, I3 se, int sg, int dir,
88 I3 n) {
89 const int ox = sg - (dir == 0 ? 1 : 0), oy = sg - (dir == 1 ? 1 : 0),
90 oz = sg - (dir == 2 ? 1 : 0);
91 Kokkos::parallel_for(
92 "vof::copyAdvectedVelocity", MDRange3<SExec>(SExec(), {0, 0, 0}, {n.x, n.y, n.z}),
93 KOKKOS_LAMBDA(int x, int y, int z) {
94 dst(L3(x + dg, y + dg, z + dg, de)) = src(L3(x + ox, y + oy, z + oz, se));
95 });
96}
97
101inline void periodicFill(SField f, I3 e, int g, bool px, bool py, bool pz) {
102 const long st[3] = {1, e.x, static_cast<long>(e.x) * e.y};
103 const int dims[3] = {e.x, e.y, e.z};
104 const bool per[3] = {px, py, pz};
105 for (int a = 0; a < 3; ++a) {
106 if (!per[a])
107 continue;
108 const int b = (a + 1) % 3, c = (a + 2) % 3;
109 const long sa = st[a], sb = st[b], sc = st[c];
110 const int N = dims[a] - 2 * g;
111 Kokkos::parallel_for(
112 "vof::periodicFill", MDRange2<SExec>(SExec(), {0, 0}, {dims[b], dims[c]}),
113 KOKKOS_LAMBDA(int p0, int p1) {
114 const long base = static_cast<long>(p0) * sb + static_cast<long>(p1) * sc;
115 for (int gl = 0; gl < g; ++gl) {
116 f(base + static_cast<long>(gl) * sa) = f(base + static_cast<long>(gl + N) * sa);
117 f(base + static_cast<long>(g + N + gl) * sa) = f(base + static_cast<long>(g + gl) * sa);
118 }
119 });
120 }
121}
122
139inline void clampFill(SField f, I3 e, int g, I3 o, I3 gs, bool px, bool py, bool pz, int skip = 0) {
140 if (px && py && pz)
141 return;
142 const bool p0 = px, p1 = py, p2 = pz;
143 const int q0 = gs.x, q1 = gs.y, q2 = gs.z;
144 const int sk = skip;
145 Kokkos::parallel_for(
146 "vof::clampFill", MDRange3<SExec>(SExec(), {0, 0, 0}, {e.x, e.y, e.z}),
147 KOKKOS_LAMBDA(int x, int y, int z) {
148 const int gx = x - g + o.x, gy = y - g + o.y, gz = z - g + o.z;
149 if (sk) {
150 const int gi[3] = {gx, gy, gz}, qq[3] = {q0, q1, q2};
151 const bool pp[3] = {p0, p1, p2};
152 for (int a = 0; a < 3; ++a) {
153 if (pp[a])
154 continue;
155 if (gi[a] < 0 && (sk & (1 << (2 * a))))
156 return;
157 if (gi[a] >= qq[a] && (sk & (1 << (2 * a + 1))))
158 return;
159 }
160 }
161 const int cx = p0 ? gx : (gx < 0 ? 0 : (gx >= q0 ? q0 - 1 : gx));
162 const int cy = p1 ? gy : (gy < 0 ? 0 : (gy >= q1 ? q1 - 1 : gy));
163 const int cz = p2 ? gz : (gz < 0 ? 0 : (gz >= q2 ? q2 - 1 : gz));
164 if (cx != gx || cy != gy || cz != gz)
165 f(L3(x, y, z, e)) = f(L3(cx - o.x + g, cy - o.y + g, cz - o.z + g, e));
166 });
167}
168
169} // namespace peclet::flow::vof
170
171#endif // PECLET_FLOW_VOF_COLOUR_FIELD_HPP
flow — portable (Kokkos) MAC stencil operators: Red-Black Gauss-Seidel smoothers + divergence.
void copyAdvectedVelocity(SField dst, I3 de, int dg, SField src, I3 se, int sg, int dir, I3 n)
The INVERSE of copyFaceVelocity, restricted to the inner region: bring a face-indexed field back from...
void clampFill(SField f, I3 e, int g, I3 o, I3 gs, bool px, bool py, bool pz, int skip=0)
Zero-gradient (Neumann) fill of the ghost cells that lie OUTSIDE the global domain on a non-periodic ...
void copyFaceVelocity(SField dst, I3 de, int dg, SField src, I3 se, int sg, int dir)
Embed the ENTIRE source extended block (inner + its sg ghost layers) into a LARGER destination extend...
void periodicFill(SField f, I3 e, int g, bool px, bool py, bool pz)
Periodic wrap of a single-block extended field at ghost width g (the single-rank ghost path; under MP...
long L3(int x, int y, int z, I3 e)
Kokkos::DefaultExecutionSpace SExec
Kokkos::View< double *, SMem > SField
flow — the multidimensional iteration policies: iteration order follows storage.
static constexpr int N