18#ifndef PECLET_FLOW_MAC_VELOCITY_MG_HPP
19#define PECLET_FLOW_MAC_VELOCITY_MG_HPP
22#include <Kokkos_Core.hpp>
38 const bool hasPin = (pin.extent(0) != 0);
40 "peclet::flow::vmg_resid",
C3{g, g, g},
C3{e.x - g, e.y - g, e.z - g},
42 const long sx = 1, sy = e.x, sz = (
long)e.x * e.y;
44 if (
hasPin && pin(i) > 0.5) {
70 const double cx = (ratio.x == 2) ? 0.5 *
ifx - 0.25 + g :
ifx + g;
71 const double cy = (ratio.y == 2) ? 0.5 *
ify - 0.25 + g :
ify + g;
72 const double cz = (ratio.z == 2) ? 0.5 *
ifz - 0.25 + g :
ifz + g;
73 const double fxw = Kokkos::floor(cx),
fyw = Kokkos::floor(cy),
fzw = Kokkos::floor(cz);
75 const int x0 = (int)
fxw, y0 = (
int)
fyw,
z0 = (int)
fzw;
77 auto C = [&](
int xx,
int yy,
int zz) {
80 const double c00 = C(x0, y0,
z0) * (1 -
wx) + C(x0 + 1, y0,
z0) *
wx;
81 const double c10 = C(x0, y0 + 1,
z0) * (1 -
wx) + C(x0 + 1, y0 + 1,
z0) *
wx;
82 const double c01 = C(x0, y0,
z0 + 1) * (1 -
wx) + C(x0 + 1, y0,
z0 + 1) *
wx;
83 const double c11 = C(x0, y0 + 1,
z0 + 1) * (1 -
wx) + C(x0 + 1, y0 + 1,
z0 + 1) *
wx;
94 double thresh,
double idiag) {
98 "peclet::flow::vmg_staircase",
MD(
space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
100 const long i = (
long)
lx + (
long)
ly * e.x + (
long)
lz * (
long)e.x * e.y;
104 AW(i) = AE(i) = AS(i) = AN(i) = AB(i) = AT(i) = (
MReal)0.0;
123 Kokkos::parallel_for(
124 "peclet::flow::vmg_pin_rows",
MD(
space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
126 const long i = (
long)
lx + (
long)
ly * e.x + (
long)
lz * (
long)e.x * e.y;
129 AW(i) = AE(i) = AS(i) = AN(i) = AB(i) = AT(i) = (
MReal)0.0;
141 double bz,
double fouw,
double sx,
double sy,
double sz,
double idiag) {
144 Kokkos::parallel_for(
145 "peclet::flow::vmg_adv_coarse",
MD(
space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
147 const long i = (
long)x + (
long)y * e.x + (
long)z * (
long)e.x * e.y;
151 sadv::fou_operator_aniso(comp, x, y, z,
Ua,
Va,
Wa,
fouw,
sx, sy, sz,
cC,
cxm,
cxp,
cym,
167 double by,
double bz,
double idiag) {
169 const std::size_t n = (std::size_t)e.x * e.y * e.z;
172 Kokkos::parallel_for(
173 "peclet::flow::vmg_const_aniso", Kokkos::RangePolicy<CCExec>(
space, 0, n),
191 int dims[3] = {e.x, e.y, e.z};
192 long st[3] = {1, e.x, (
long)e.x * e.y};
193 const int b = (a + 1) % 3, c = (a + 2) % 3;
194 const long sa = st[a],
sb = st[b], sc = st[c];
195 const int bic = (s == 0) ? g : (
dims[a] - g - 1);
196 Kokkos::parallel_for(
209 int dims[3] = {e.x, e.y, e.z};
210 long st[3] = {1, e.x, (
long)e.x * e.y};
211 const int b = (a + 1) % 3, c = (a + 2) % 3;
212 const long sa = st[a],
sb = st[b], sc = st[c];
213 const int na =
dims[a];
214 Kokkos::parallel_for(
217 const long base = (
long)p0 *
sb + (
long)
p1 * sc;
219 const double v =
dirichlet ? 0.0 : x(base + (
long)g *
sa);
220 for (
int ia = 0;
ia < g; ++
ia)
221 x(base + (
long)
ia *
sa) = v;
223 const double v =
dirichlet ? 0.0 : x(base + (
long)(na - g - 1) *
sa);
224 for (
int ia = na - g;
ia < na; ++
ia)
225 x(base + (
long)
ia *
sa) = v;
234 int dims[3] = {e.x, e.y, e.z};
235 long st[3] = {1, e.x, (
long)e.x * e.y};
236 const int b = (axis + 1) % 3, c = (axis + 2) % 3;
237 const long sa = st[axis],
sb = st[b], sc = st[c];
238 Kokkos::parallel_for(
246 std::size_t n = m.extent(0);
249 Kokkos::parallel_for(
250 "peclet::flow::vmg_threshold", Kokkos::RangePolicy<CCExec>(
space, 0, n),
258 Kokkos::parallel_reduce(
259 "peclet::flow::vmg_maxabs",
MD(
space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
261 const long i = (
long)x + (
long)y * e.x + (
long)z * (
long)e.x * e.y;
262 const double d = Kokkos::fabs(a(i));
266 Kokkos::Max<double>(m));
274 Kokkos::parallel_reduce(
275 "peclet::flow::vmg_maxabsdiff",
MD(
space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
277 const long i = (
long)x + (
long)y * e.x + (
long)z * (
long)e.x * e.y;
278 const double d = Kokkos::fabs(a(i) - b(i));
282 Kokkos::Max<double>(m));
287 std::size_t n = r.extent(0);
290 Kokkos::parallel_for(
291 "peclet::flow::vmg_mulmask", Kokkos::RangePolicy<CCExec>(
space, 0, n),
299 static constexpr int G = 2;
300#ifdef PECLET_FLOW_MPI
317#ifdef PECLET_FLOW_MPI
318 std::shared_ptr<GridHaloTopology<3>> halo;
319 std::shared_ptr<GridHalo<double>> dev;
330 for (
int a = 0; a < 3; ++a) {
334 aniso_ = !(hp_[0] == 1.0 && hp_[1] == 1.0 && hp_[2] == 1.0);
340 r.reserve(lv_.size());
341 for (
const auto& v : lv_)
342 r.push_back(v.ratio);
349 C3 inner{nx, ny, nz}, cf{1, 1, 1};
350 for (
int L = 0; L <
nLevels; ++L) {
354 v.ext =
C3{inner.x + 2 *
G, inner.y + 2 *
G, inner.z + 2 *
G};
356 v.n = (std::size_t)v.ext.x * v.ext.y * v.ext.z;
357 auto can = [&](
int d) {
return (d % 2 == 0) && (d / 2 >= 2); };
363 const bool canA[3] = {can(inner.x), can(inner.y), can(inner.z)};
364 const double H[3] = {hp_[0] * (
double)cf.x, hp_[1] * (
double)cf.y, hp_[2] * (
double)cf.z};
367 next.
x = inner.x / 2;
369 next.
y = inner.y / 2;
371 next.
z = inner.z / 2;
375 v.rhs =
CCField(
"vmg_rhs", v.n);
376 v.res =
CCField(
"vmg_res", v.n);
377 v.theta =
CCField(
"vmg_th", v.n);
378 v.pin =
CCField(
"vmg_pin", v.n);
380 v.advU =
CCField(
"vmg_au", v.n);
381 v.advV =
CCField(
"vmg_av", v.n);
382 v.advW =
CCField(
"vmg_aw", v.n);
384 for (
FPV* p : {&v.AC, &v.AW, &v.AE, &v.AS, &v.AN, &v.AB, &v.AT})
385 *p =
FPV(
"vmg_A", v.n);
387 if (next.
x == inner.x && next.
y == inner.y && next.
z == inner.z)
390 cf =
C3{cf.x * ratio.x, cf.y * ratio.y, cf.z * ratio.z};
393 CCField(
"vmg_resmask0", lv_[0].n);
395#ifdef PECLET_FLOW_MPI
403 initMpi(peclet::core::decomp::BlockDecomposer<3>(
static_cast<std::size_t
>(size),
413 void initMpi(
const peclet::core::decomp::BlockDecomposer<3>& dec0,
int nLevels, MPI_Comm comm,
414 bool inPlace =
true) {
417 int rank = 0, size = 1;
418 MPI_Comm_rank(comm, &rank);
419 MPI_Comm_size(comm, &size);
420 std::array<bool, 3> per{
true,
true,
true};
421 const auto& g0 = dec0.globalSize();
422 C3
gs{(
int)g0[0], (
int)g0[1], (
int)g0[2]},
cf{1, 1, 1};
423 auto can = [&](
int d) {
return (d % 2 == 0) && (
d / 2 >= 2); };
424 auto evenOn = [](
const peclet::core::decomp::BlockDecomposer<3>&
d,
int ax) {
425 for (std::size_t b = 0;
b <
d.numBlocks(); ++
b) {
426 const auto blk =
d.block(b);
427 if (blk.origin[ax] % 2 != 0 || blk.size[ax] % 2 != 0)
432 peclet::core::decomp::BlockDecomposer<3> dec = dec0;
435 v.halo = std::make_shared<GridHaloTopology<3>>();
436 if (!inPlace && L > 0)
437 dec = peclet::core::decomp::BlockDecomposer<3>(
static_cast<std::size_t
>(size),
438 peclet::core::IVec<3>{
gs.x,
gs.y,
gs.z});
439 v.halo->buildTopology(dec, rank,
G, per, comm);
440 v.dev = std::make_shared<GridHalo<double>>();
441 v.dev->init(*
v.halo);
442 v.dev->setLabel(
"vmg L" + std::to_string(L));
443 const auto& idx =
v.halo->indexer();
444 const auto eg = idx.sizeInclGhost(), ino = idx.sizeInner(), oig = idx.originInclGhost();
445 v.ext = {(
int)eg[0], (
int)
eg[1], (
int)eg[2]};
446 v.inner = {(
int)ino[0], (
int)ino[1], (
int)ino[2]};
447 v.og = {(
int)oig[0] +
G, (
int)oig[1] +
G, (
int)oig[2] +
G};
450 v.n = idx.numCellsInclGhost();
455 const bool canA[3] = {can(
gs.x) && (!inPlace || evenOn(dec, 0)),
456 can(
gs.y) && (!inPlace || evenOn(dec, 1)),
457 can(
gs.z) && (!inPlace || evenOn(dec, 2))};
458 const double H[3] = {hp_[0] * (double)
cf.x, hp_[1] * (
double)
cf.y, hp_[2] * (double)
cf.z};
478 for (
FPV* p : {&
v.AC, &
v.AW, &
v.AE, &
v.AS, &
v.AN, &
v.AB, &
v.AT})
479 *p =
FPV(
"vmg_A",
v.n);
481 if (next.x ==
gs.x && next.y ==
gs.y && next.z ==
gs.z)
488 lv_[0].resMask =
CCField(
"vmg_resmask0", lv_[0].n);
496 const int o = (a == 0) ? lv.og.x : (a == 1) ? lv.og.y : lv.og.z;
497 const int n = (a == 0) ? lv.inner.x : (a == 1) ? lv.inner.y : lv.inner.z;
498 const int gn = (a == 0) ? lv.gdim.x : (a == 1) ? lv.gdim.y : lv.gdim.z;
499 return (f % 2 == 0) ? (o == 0) : (o + n == gn);
501 int nLevels()
const {
return (
int)lv_.size(); }
505 int levels()
const {
return (
int)lv_.size(); }
510 Kokkos::deep_copy(f.AC,
AC);
511 Kokkos::deep_copy(f.AW, AW);
512 Kokkos::deep_copy(f.AE, AE);
513 Kokkos::deep_copy(f.AS, AS);
514 Kokkos::deep_copy(f.AN, AN);
515 Kokkos::deep_copy(f.AB, AB);
516 Kokkos::deep_copy(f.AT, AT);
527 Kokkos::deep_copy(f.theta,
theta0);
528 Kokkos::deep_copy(f.pin,
solid0);
529 Kokkos::deep_copy(f.resMask,
resmask0);
530 for (
int L = 1; L < (int)lv_.size(); ++L) {
536 const double bx =
nu_dt * w_[0] / (
double)(c.cfac.x * c.cfac.x),
539 buildVelocityStaircase(c.AC, c.AW, c.AE, c.AS, c.AN, c.AB, c.AT,
CCConst(c.theta), c.ext,
G,
559 for (
int L = 1; L < (int)lv_.size(); ++L) {
561 const double bx =
nu_dt * w_[0] / (
double)(c.cfac.x * c.cfac.x),
566 1.0 / c.cfac.y, 1.0 / c.cfac.z, idiag);
567 pinSolidRows(c.AC, c.AW, c.AE, c.AS, c.AN, c.AB, c.AT,
CCConst(c.theta), c.ext,
G,
thresh);
571 const int t = bc_[2 * comp];
572 if ((t == 1 || t == 2 || t == 4) &&
touches(f, 2 * comp))
575 for (
int L = 1; L < (int)lv_.size(); ++L) {
577 const double bx =
nu_dt * w_[0] / (
double)(c.cfac.x * c.cfac.x),
580 for (
int ff = 0;
ff < 6; ++
ff) {
581 const int a =
ff / 2,
sd =
ff % 2;
582 const double ba = (a == 0) ?
bx : (a == 1) ?
by :
bz;
586 else if ((bc_[
ff] == 1 || bc_[
ff] == 2) && a != comp)
603 for (
int L = 1; L < (int)lv_.size(); ++L) {
623 for (
int L = 1; L < (int)lv_.size(); ++L) {
625 const double bx =
nu_dt * w_[0] / (
double)(c.cfac.x * c.cfac.x),
628 const double sx = 1.0 / (
double)c.cfac.x, sy = 1.0 / (
double)c.cfac.y,
629 sz = 1.0 / (
double)c.cfac.z;
631 CCConst(c.advW), comp, c.ext,
G,
bx,
by,
bz,
fouw,
sx, sy, sz, idiag);
641 for (
int i = 0; i < 6; ++i) {
679 Kokkos::deep_copy(f.resMask, 1.0);
681 for (
int s = 0; s < 1;
683 const int t = bc_[2 * comp + s];
684 if (t == 1 || t == 2 || t == 4) {
690 for (
int L = 0; L < (int)lv_.size(); ++L) {
692 const double bx =
nu_dt * w_[0] / (
double)(c.cfac.x * c.cfac.x),
695 buildConstAniso(c.AC, c.AW, c.AE, c.AS, c.AN, c.AB, c.AT, c.ext,
bx,
by,
bz, idiag);
696 for (
int f = 0; f < 6; ++f) {
697 const int a = f / 2, s = f % 2;
698 const double ba = (a == 0) ?
bx : (a == 1) ?
by :
bz;
702 else if ((bc_[f] == 1 || bc_[f] == 2) && a != comp)
704 else if (bc_[f] == 4 && a != comp && L == 0)
740 Kokkos::deep_copy(
l0.rhs, b);
741 Kokkos::deep_copy(
l0.x, x);
742 auto gmax = [&](
double v) {
743#ifdef PECLET_FLOW_MPI
757 for (
Level& lv : lv_) {
758 double lo = 0.0, hi = 0.0;
760 FPC(lv.AB),
FPC(lv.AT), usePin_ ?
CCConst(lv.pin) : empty_, lv.ext,
762 lv.chebHi =
gmax(hi);
764 auto residual = [&]() {
773 if (bcMode_ && heldComp_ >= 0) {
774 const int t = bc_[2 * heldComp_];
775 if ((t == 1 || t == 2 || t == 4) &&
touches(
l0, 2 * heldComp_))
785 if (
useDu && prev_.extent(0) !=
l0.n)
789 lastResRatio_ = -1.0;
791 const double r0 = residual();
794 lastResRatio_ =
bnorm > 0.0 ? r0 /
bnorm : 0.0;
797 for (
int v = 0; v <
nvc; ++v) {
799 Kokkos::deep_copy(prev_,
l0.x);
802 const double r = residual();
803 lastResRatio_ =
bnorm > 0.0 ? r /
bnorm : 0.0;
821 Kokkos::deep_copy(x,
l0.x);
829 const bool l0 = (L == 0);
830 if (L + 1 == (
int)lv_.size()) {
836 if (
l0 && bcApplyL0_)
840 usePin_ ?
CCConst(lv.pin) : empty_, lv.ext,
G);
842 useResMask_ && (lv.resMask.extent(0) == lv.n);
845 Level& cs = lv_[L + 1];
847 Kokkos::deep_copy(cs.x, 0.0);
862 if (chebSmooth_ && lv.chebHi > 0.0) {
863 chebSmooth(lv, chebDegree_ > 0 ? chebDegree_ : sweeps,
isL0, pin);
866 for (
int k = 0; k < sweeps; ++k)
868#ifdef PECLET_FLOW_MPI
869 if (distributed_ && !bcMode_) {
873 const C3 lo{
G + 1,
G + 1,
G + 1};
874 const C3 hi{lv.ext.x -
G - 1, lv.ext.y -
G - 1, lv.ext.z -
G - 1};
875 lv.dev->exchangeBegin(lv.x);
877 FPC(lv.AS),
FPC(lv.AN),
FPC(lv.AB),
FPC(lv.AT), pin, lv.ext, og,
878 color, lo, hi,
C3{0, 0, 0},
C3{0, 0, 0});
879 lv.dev->exchangeEnd(lv.x);
881 FPC(lv.AS),
FPC(lv.AN),
FPC(lv.AB),
FPC(lv.AT), pin, lv.ext, og,
882 color,
C3{G, G, G},
C3{lv.ext.x - G, lv.ext.y - G, lv.ext.z - G},
888 if (
isL0 && bcApplyL0_)
903 if (lv.cd.extent(0) != lv.n)
904 lv.cd =
CCField(
"vmg_cd", lv.n);
905 Kokkos::deep_copy(lv.cd, 0.0);
906 ChebCoeffs cb(lv.chebHi / chebEigRatio_, lv.chebHi);
907 for (
int k = 0; k <
degree; ++k) {
909 if (
isL0 && bcApplyL0_)
912 FPC(lv.AS),
FPC(lv.AN),
FPC(lv.AB),
FPC(lv.AT), pin, lv.ext,
G);
913 double alpha = 0.0, beta = 0.0;
914 cb.
next(k, alpha, beta);
923#ifdef PECLET_FLOW_MPI
931 for (
int a = 0; a < 3; ++a)
932 if (!bcMode_ || (bc_[2 * a] == 0 && bc_[2 * a + 1] == 0))
939 for (
int a = 0; a < 3; ++a)
940 for (
int s = 0; s < 2; ++s)
941 if (bc_[2 * a + s] != 0 &&
touches(lv, 2 * a + s))
949 for (
int a = 0; a < 3; ++a)
950 for (
int s = 0; s < 2; ++s) {
951 const int t = bc_[2 * a + s];
952 if (t == 0 || !
touches(lv, 2 * a + s))
960 int N3[3] = {lv.inner.x, lv.inner.y, lv.inner.z};
961 int dims[3] = {e.x, e.y, e.z};
962 long st[3] = {1, e.x, (
long)e.x * e.y};
963 const int a = axis, b = (axis + 1) % 3, c = (axis + 2) % 3;
964 const long sa = st[a],
sb = st[b], sc = st[c];
967 Kokkos::parallel_for(
970 const long base = (
long)p0 *
sb + (
long)
p1 * sc;
971 for (
int gl = 0;
gl <
G; ++
gl) {
979 std::vector<Level> lv_;
980 double w_[3] = {1.0, 1.0, 1.0};
981 double hp_[3] = {1.0, 1.0, 1.0};
983 double aspectTheta_ = 2.0;
984 int pre_ = 2, post_ = 2, bottom_ = 8;
985 bool chebSmooth_ =
false;
987 double chebEigRatio_ = 10.0;
990 bool bcMode_ =
false;
991 int bc_[6] = {0, 0, 0, 0, 0, 0};
992 std::function<void(
CCField)> bcApplyL0_;
994 bool distributed_ =
false;
996 double lastResRatio_ = -1.0;
static C3 mgChooseRatio(const double H[3], const bool canA[3], bool aniso, double theta)
bool chebyshevSmoother() const
void setFineStencil(FPC AC, FPC AW, FPC AE, FPC AS, FPC AN, FPC AB, FPC AT)
void fillProlongBcGhosts(Level &lv)
void buildUpwindCoarse(int comp, double nu_dt, double idiag, double fouw)
void zeroBcGhosts(Level &lv, CCField f)
void setChebyshevSmoother(bool on, int degree=0, double eigRatio=10.0)
bool touches(const Level &lv, int f) const
void setStaircaseBc(int comp, CCConst theta0, CCConst solid0, CCConst resmask0, double nu_dt, double idiag, double thresh, bool upwind=false, double fouw=0.0)
int solve(CCConst b, CCField x, int nvc, int pre, int post, int bottom, double tol=0.0, Comm comm=nullComm(), double resTol=0.0)
void fillAxis(Level &lv, CCField f, int axis)
void setBcApplyL0(std::function< void(CCField)> fn)
void setDomainBcOp(int comp, double nu_dt, double idiag)
void smooth(Level &lv, int sweeps, bool isL0)
void chebSmooth(Level &lv, int degree, bool isL0, CCConst pin)
void restrictAdvVelocities(CCConst u0, CCConst v0, CCConst w0)
void fill(Level &lv, CCField f)
void setAspectThreshold(double theta)
Anisotropic-coarsening aspect threshold theta (doc/anisotropic_metric.md §5.1).
void setStaircase(CCConst theta0, CCConst solid0, CCConst resmask0, double nu_dt, double idiag, double thresh)
void setBC(const int bc[6])
void init(int nx, int ny, int nz, int nLevels)
double lastResidualRatio() const
std::vector< C3 > levelRatios() const
The per-level coarsening ratio actually chosen (the level table of §5; the two hierarchies share one ...
void setMetric(const double w[3], const double hp[3])
Per-axis metric of the physical domain (doc/anisotropic_metric.md §1.1): the weights w_a = 1/h_a'^2,...
flow — Chebyshev semi-iteration as a standalone momentum (implicit-diffusion) solver,...
flow — portable (Kokkos) geometric multigrid for the cut-cell (variable-openness) pressure Poisson.
flow — portable (Kokkos) IBM geometric fields + variable-coefficient RB-GS smoother.
void zeroPlane(CCField m, C3 e, int axis, int idx)
void buildConstAniso(FPV AC, FPV AW, FPV AE, FPV AS, FPV AN, FPV AB, FPV AT, C3 e, double bx, double by, double bz, double idiag)
void buildVelocityStaircase(FPV AC, FPV AW, FPV AE, FPV AS, FPV AN, FPV AB, FPV AT, CCConst theta, C3 e, int g, double bx, double by, double bz, double thresh, double idiag)
void thresholdMask(CCField m, CCConst theta, double thresh)
void ibmChebUpdate(CCField x, CCField d, CCConst r, FPC AC, CCConst solidmask, C3 e, int g, double alpha, double beta)
One Chebyshev update on the Jacobi-preconditioned system: d <- beta*d + alpha*r/AC ; x += d.
Kokkos::View< const MReal *, CCMem > FPC
void prolongAdd(CCField fine, CCConst coarse, C3 fext, C3 cext, int gf, int gc, C3 finner, C3 ratio)
void ibmStencilJacobiBounds(MC AC, MC AW, MC AE, MC AS, MC AN, MC AB, MC AT, CCConst solidmask, C3 e, int g, double &lo, double &hi)
Gershgorin bounds [lo, hi] on the spectrum of the Jacobi-preconditioned cut-cell Helmholtz diag(AC)^-...
void residualVarPin(CCField r, CCConst x, CCConst b, FPC AC, FPC AW, FPC AE, FPC AS, FPC AN, FPC AB, FPC AT, CCConst pin, C3 e, int g)
void boundaryFold(FPV AC, C3 e, int g, int a, int s, double beta)
void fillBcGhost(CCField x, C3 e, int g, int a, int s, int dirichlet)
double maxAbsInner(CCConst a, C3 e, int g)
void ccFor3(const char *name, C3 lo, C3 hi, F f)
Kokkos::View< double *, CCMem > CCField
void restrictAvg(CCField coarse, CCConst fine, C3 cext, C3 fext, int gc, int gf, C3 cinner, C3 ratio)
Kokkos::View< MReal *, CCMem > FPV
double maxAbsDiffInner(CCConst a, CCConst b, C3 e, int g)
void ibmRbgsStencilColorBox(CCField x, CCConst b, MC AC, MC AW, MC AE, MC AS, MC AN, MC AB, MC AT, CCConst solidmask, C3 ext, C3 og, int color, C3 rlo, C3 rhi, C3 slo, C3 shi)
void mulMask(CCField r, CCConst m)
Kokkos::DefaultExecutionSpace CCExec
void pinSolidRows(FPV AC, FPV AW, FPV AE, FPV AS, FPV AN, FPV AB, FPV AT, CCConst theta, C3 e, int g, double thresh)
void prolongMasked(CCField fine, CCConst coarse, CCConst mask, C3 fext, C3 cext, int g, C3 finner, C3 ratio, double eps)
void ibmRbgsStencilColor(CCField x, CCConst b, MC AC, MC AW, MC AE, MC AS, MC AN, MC AB, MC AT, CCConst solidmask, C3 ext, C3 og, int g, int color)
void buildAdvCoarse(FPV AC, FPV AW, FPV AE, FPV AS, FPV AN, FPV AB, FPV AT, CCConst U, CCConst V, CCConst W, int comp, C3 e, int g, double bx, double by, double bz, double fouw, double sx, double sy, double sz, double idiag)
Kokkos::View< const double *, CCMem > CCConst
void fou_operator_aniso(int comp, int x, int y, int z, A U, A V, A W, double dt, double sx, double sy, double sz, double &cC, double &cxm, double &cxp, double &cym, double &cyp, double &czm, double &czp)
flow — the multidimensional iteration policies: iteration order follows storage.
flow — portable (Kokkos) staggered MAC momentum advection (Koren TVD + FOU).
The Chebyshev coefficient recurrence (Golub-Varga; the form multigrid Chebyshev smoothers use).
void next(int it, double &alpha, double &beta)
Coefficients for iteration it (0-based). Advances the recurrence.
static constexpr double AC
static constexpr double U