10#ifndef PECLET_FLOW_SDFLOW_HPP
11#define PECLET_FLOW_SDFLOW_HPP
13#include <Kokkos_Core.hpp>
25 using F = Kokkos::View<double*, SMem>;
26 static constexpr int G = 2;
28 FlowReference(
int n,
double nu,
double dt) : N_(n), nu_(nu), dt_(dt), mg_(n) {
29 e_ =
I3{N_ + 2 *
G, N_ + 2 *
G, N_ + 2 *
G};
30 ne_ = (std::size_t)e_.
x * e_.
y * e_.
z;
43 eMg_ =
I3{N_ + 2, N_ + 2, N_ + 2};
44 const std::size_t nm = (std::size_t)eMg_.
x * eMg_.
y * eMg_.
z;
46 phiMg_ =
F(
"phiMg", nm);
52 int N()
const {
return N_; }
77 Kokkos::deep_copy(us_, u_);
78 Kokkos::deep_copy(vs_, v_);
79 Kokkos::deep_copy(ws_, w_);
80 const double Ac =
idiag() + 6.0 * nu_;
81 for (
int it = 0; it < nDiff_; ++it) {
91 Kokkos::deep_copy(phi_, 0.0);
94 Kokkos::deep_copy(phiMg_, 0.0);
98 for (
int it = 0; it < nPois_; ++it) {
106 Kokkos::deep_copy(u_, us_);
107 Kokkos::deep_copy(v_, vs_);
108 Kokkos::deep_copy(w_, ws_);
114 return std::sqrt(s.
sum);
127 double idiag()
const {
return 1.0 / dt_; }
133 Kokkos::parallel_for(
134 "peclet::flow::copyInner", Kokkos::RangePolicy<SExec>(space, 0, (
long)
N *
N *
N),
135 KOKKOS_LAMBDA(
long c) {
136 const int ix = (int)(c %
N), iy = (int)((c /
N) %
N), iz = (
int)(c / ((long)
N *
N));
138 (long)(ix + dg) + (long)(iy + dg) * de.
x + (long)(iz + dg) * (long)de.
x * de.
y;
140 (long)(ix + sg) + (long)(iy + sg) * se.
x + (long)(iz + sg) * (long)se.
x * se.
y;
147 diffSmoothColor(x,
SConst(b), e_,
I3{0, 0, 0},
G, nu_, Ac, 0,
SConst());
149 diffSmoothColor(x,
SConst(b), e_,
I3{0, 0, 0},
G, nu_, Ac, 1,
SConst());
154 const double id =
idiag();
155 const bool adv = advect_;
156 const double fx = fx_, fy = fy_, fz = fz_;
158 F u = u_,
v = v_,
w = w_, bu = bu_, bv = bv_, bw = bw_;
159 using MD = Kokkos::MDRangePolicy<SExec, Kokkos::Rank<3>>;
160 Kokkos::parallel_for(
161 "peclet::flow::sdflow_rhs", MD(space, {
G,
G,
G}, {e.x -
G, e.y -
G, e.z -
G}),
162 KOKKOS_LAMBDA(
int x,
int y,
int z) {
163 const long i = (long)x + (
long)y * e.x + (long)z * (
long)e.x * e.y;
164 double au = 0, av = 0, aw = 0;
171 bu(i) =
id *
u(i) + fx - au;
172 bv(i) =
id *
v(i) + fy - av;
173 bw(i) =
id *
w(i) + fz - aw;
179 const double mean = s.
sum / ((double)N_ * N_ * N_);
182 Kokkos::parallel_for(
183 "peclet::flow::submean", Kokkos::RangePolicy<SExec>(space, 0, ne_),
184 KOKKOS_LAMBDA(std::size_t i) { f(i) -= mean; });
195 Kokkos::parallel_reduce(
196 "peclet::flow::sdflow_reduce", Kokkos::RangePolicy<SExec>(space, 0, (
long)
N *
N *
N),
197 KOKKOS_LAMBDA(
long c,
SumMax& acc) {
198 const int ix = (int)(c %
N), iy = (int)((c /
N) %
N), iz = (
int)(c / ((long)
N *
N));
199 const long i = (long)(ix +
G) + (long)(iy +
G) * e.x + (long)(iz +
G) * (long)e.x * e.y;
200 const double val = f(i);
201 acc.
sum += sq ? val * val : val;
202 const double a = Kokkos::fabs(val);
220 int dims[3] = {e.x, e.y, e.z};
221 long st[3] = {1, e.x, (long)e.x * e.y};
222 const int a = axis, b = (axis + 1) % 3, c = (axis + 2) % 3;
223 const long sa = st[a], sb = st[b], sc = st[c];
225 using MD = Kokkos::MDRangePolicy<SExec, Kokkos::Rank<2>>;
228 Kokkos::parallel_for(
229 "peclet::flow::pfill", MD(space, {0, 0}, {dims[b], dims[c]}),
230 KOKKOS_LAMBDA(
int p0,
int p1) {
231 const long base = (long)p0 * sb + (
long)p1 * sc;
232 for (
int gl = 0; gl <
G; ++gl) {
234 ff(base + (
long)gl * sa) = ff(base + (
long)(gl +
N) * sa);
235 ff(base + (
long)(
G +
N + gl) * sa) = ff(base + (
long)(
G + gl) * sa);
245 F u_, v_, w_, us_, vs_, ws_, bu_, bv_, bw_, phi_, div_;
249 double fx_ = 0, fy_ = 0, fz_ = 0;
250 bool advect_ =
true, useMg_ =
true;
251 int nDiff_ = 20, nPois_ = 50, nVcycles_ = 8;
SumMax localSumMax(SConst f)
SumMax localSumMaxSq(SConst f)
void fillAxis(F f, int axis)
FlowReference(int n, double nu, double dt)
void diffuseComp(F x, F b, double Ac)
Kokkos::View< double *, SMem > F
void copyInner(F dst, I3 de, int dg, SConst src, I3 se, int sg)
void setPressureMultigrid(bool useMg, int nVcycles)
void setBodyForce(double fx, double fy, double fz)
void setIterations(int nDiff, int nPois)
void setAdvection(bool on)
SumMax reduceInner(SConst f, bool sq)
void solve(SField phi, SConst d, int nVcycles, int nu1=2, int nu2=2)
flow — portable (Kokkos) geometric multigrid V-cycle for the periodic pressure Poisson.
flow — portable (Kokkos) global reductions over a MAC grid's inner (owned) cells.
flow — portable (Kokkos) MAC stencil operators: Red-Black Gauss-Seidel smoothers + divergence.
flow — portable (Kokkos) multigrid transfer operators + projection velocity correction.
void divergence(SConst u, SConst v, SConst w, SField d, I3 e, int g)
void correct(TField u, TField v, TField w, TConst phi, T3 e, int g)
void diffSmoothColor(SField c, SConst b, I3 e, I3 og, int g, double beta, double Ac, int color, SConst dcorr)
Kokkos::View< const double *, SMem > SConst
Kokkos::DefaultExecutionSpace SExec
void poisSweep(SField phi, SConst d, I3 e, I3 og, int g)
double advect(int comp, int x, int y, int z, A U, A V, A W, A PHI)
flow — portable (Kokkos) staggered MAC momentum advection (Koren TVD + FOU).
{sum, max|.|} reduction value.