9#ifndef PECLET_FLOW_MAC_MG_HPP
10#define PECLET_FLOW_MAC_MG_HPP
12#include <Kokkos_Core.hpp>
23 int dims[3] = {e.x, e.y, e.z};
24 long st[3] = {1, e.x, (
long)e.x * e.y};
25 for (
int axis = 0; axis < 3; ++axis) {
26 const int b = (axis + 1) % 3, c = (axis + 2) % 3;
27 const long sa = st[axis],
sb = st[b], sc = st[c];
29 using MD = Kokkos::MDRangePolicy<SExec, Kokkos::Rank<2>>;
33 const long base = (
long)p0 *
sb + (
long)
p1 * sc;
34 for (
int gl = 0;
gl < g; ++
gl) {
36 ff(base + (
long)(g +
N +
gl) *
sa) =
ff(base + (
long)(g +
gl) *
sa);
52 L.e =
I3{n + 2 *
G, n + 2 *
G, n + 2 *
G};
53 const std::size_t
ne = (std::size_t)
L.e.x *
L.e.y *
L.e.z;
58 if (n % 2 != 0 || n / 2 <
minN)
73 "peclet::flow::mg_negd", Kokkos::RangePolicy<SExec>(
space, 0,
f0.extent(0)),
76 Kokkos::deep_copy(
lv_[0].phi, phi);
81 Kokkos::deep_copy(phi,
lv_[0].phi);
92 static constexpr int G = 1;
99 std::vector<Level>
lv_;
105 const double h2 =
L.h2;
107 using MD = Kokkos::MDRangePolicy<SExec, Kokkos::Rank<3>>;
108 Kokkos::parallel_for(
109 "peclet::flow::mg_smooth",
MD(
space, {
G,
G,
G}, {e.x -
G, e.y -
G, e.z -
G}),
111 if (((x + y + z) & 1) !=
color)
113 const long i =
L3(x, y, z, e),
sx = 1,
sy = e.x,
sz = (
long)e.x * e.y;
116 phi(
i) = (s + h2 * f(
i)) / 6.0;
132 const double h2 =
L.h2;
134 using MD = Kokkos::MDRangePolicy<SExec, Kokkos::Rank<3>>;
135 Kokkos::parallel_for(
136 "peclet::flow::mg_resid",
MD(
space, {
G,
G,
G}, {e.x -
G, e.y -
G, e.z -
G}),
138 const long i =
L3(x, y, z, e),
sx = 1,
sy = e.x,
sz = (
long)e.x * e.y;
141 r(
i) = f(
i) - (6.0 * phi(
i) - s) / h2;
146 if (
l == (
int)
lv_.size() - 1) {
154 Kokkos::deep_copy(C.
phi, 0.0);
156 T3{C.N, C.N, C.N},
T3{2, 2, 2});
161 T3{L.N, L.N, L.N},
T3{2, 2, 2});
169 Kokkos::parallel_reduce(
170 "peclet::flow::mg_mean", Kokkos::RangePolicy<SExec>(
space, 0, (
long)
N *
N *
N),
172 const int ix = (int)(c %
N),
iy = (int)((c /
N) %
N),
iz = (
int)(c / ((
long)
N *
N));
177 Kokkos::parallel_for(
178 "peclet::flow::mg_submean", Kokkos::RangePolicy<SExec>(
space, 0, f.extent(0)),
186 Kokkos::parallel_reduce(
187 "peclet::flow::mg_maxabs", Kokkos::RangePolicy<SExec>(
space, 0, (
long)
N *
N *
N),
189 const int ix = (int)(c %
N),
iy = (int)((c /
N) %
N),
iz = (
int)(c / ((
long)
N *
N));
190 double v = Kokkos::fabs(f(
L3(
ix +
G,
iy +
G,
iz +
G, e)));
194 Kokkos::Max<double>(m));
double finestResidualMax()
double maxAbsInner(SField f, Level &L)
MgPoisson(int N, int minN=4)
void smoothColor(Level &L, int color)
void vcycle(int l, int nu1, int nu2)
void removeMean(SField f, Level &L)
void computeResidual(int l)
void smooth(Level &L, int sweeps)
void solve(SField phi, SConst d, int nVcycles, int nu1=2, int nu2=2)
flow — portable (Kokkos) MAC stencil operators: Red-Black Gauss-Seidel smoothers + divergence.
flow — portable (Kokkos) multigrid transfer operators + projection velocity correction.
long L3(int x, int y, int z, I3 e)
void restrict_(TField coarse, TConst fine, T3 cext, T3 fext, int g, T3 cinner, T3 ratio)
void prolong(TField fine, TConst coarse, T3 fext, T3 cext, int g, T3 finner, T3 ratio)
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< const double *, SMem > SConst
void mgPeriodicFill(SField f, I3 e, int N, int g)
Kokkos::DefaultExecutionSpace SExec
Kokkos::View< double *, SMem > SField