25#include <Kokkos_Core.hpp>
38 std::size_t cells = 18 * 18 * 18;
46 std::vector<double>
hx(P.cells, 0.0),
hy(P.cells, 0.0),
hz(P.cells, 0.0),
hb(P.cells, 0.0);
47 const double k = 2.0 *
M_PI /
n;
49 for (
int z = 0;
z <
e.z; ++
z)
50 for (
int y = 0;
y <
e.y; ++
y)
51 for (
int x = 0;
x <
e.x; ++
x) {
53 (std::size_t)x + (std::size_t)
y *
e.x + (std::size_t)z * (std::size_t)
e.x *
e.y;
54 hx[
i] = 1.0 + 0.5 * std::sin(k * x) * std::cos(k * z);
55 hy[
i] = 1.0 + 0.5 * std::cos(k * y + 0.3);
56 hz[
i] = 1.0 + 0.5 * std::sin(k * (x + z));
58 hb[
i] = std::sin(k * x) + 0.3 * std::cos(2 * k * y) * std::sin(k * z) + 0.01 * (
x -
y);
63 for (
int z =
G;
z <
e.z -
G; ++
z)
64 for (
int y =
G;
y <
e.y -
G; ++
y)
65 for (
int x =
G;
x <
e.x -
G; ++
x)
66 hb[(std::size_t)
x + (std::size_t)y *
e.x + (std::size_t)
z * (std::size_t)
e.x *
e.y] -=
mean;
67 auto up = [&](
const std::vector<double>&
h,
const char* name) {
69 auto m = Kokkos::create_mirror_view(v);
70 for (std::size_t i = 0;
i < P.cells; ++
i)
72 Kokkos::deep_copy(v, m);
85 std::vector<double>
x;
90 mg.
init(P.n, P.n, P.n, 3);
93 CCField x(
"x", P.cells),
r(
"r", P.cells),
p(
"p", P.cells),
z(
"z", P.cells),
Ap(
"Ap", P.cells);
95 out.it = mg.
solvePCG(P.b, x, r, p, z,
Ap, maxit, 1e-30, 2, 2, 12);
97 auto h = Kokkos::create_mirror_view(x);
98 Kokkos::deep_copy(h, x);
99 out.x.assign(
h.data(),
h.data() + P.cells);
103bool sameBits(
const std::vector<double>& a,
const std::vector<double>& b) {
104 return a.size() ==
b.size() && std::memcmp(
a.data(),
b.data(),
a.size() *
sizeof(
double)) == 0;
109 std::printf(
" %-44s it %d (want %d) failed %d (want %d) x %s -> %s\n", what,
got.it,
wantIt,
111 ok ?
"PASS" :
"FAIL");
125 const C3 e{
n + 2 *
G,
n + 2 *
G,
n + 2 *
G};
126 const std::size_t cells = (std::size_t)
e.x *
e.y *
e.z;
128 Kokkos::deep_copy(one, 1.0);
135 for (
int k = 1;
k <= 64; ++
k) {
136 const double c = -std::ldexp(1.0 - (
double)k * 0x1p-52, -102);
137 auto hr = Kokkos::create_mirror_view(r);
138 for (std::size_t i = 0;
i < cells; ++
i)
143 hr((std::size_t)
xx + (std::size_t)
yy *
e.x + (std::size_t)
zz *
e.x *
e.y) =
c;
144 Kokkos::deep_copy(r,
hr);
146 auto hz = Kokkos::create_mirror_view(z);
147 Kokkos::deep_copy(
hz, z);
149 for (std::size_t i = 0;
i < cells; ++
i)
153 std::printf(
" constant bottom rhs %a: non-finite correction\n", c);
158 " round-off constant rhs on the agglomerated bottom: %d/64 corrections non-finite"
160 bad,
bad ?
"FAIL" :
"PASS");
167 Kokkos::initialize(
argc, argv);
170 std::printf(
"=== pcg_breakdown (A6 exits, doc/vof_step_performance_design.md §5.6) ===\n");
172 const int K = 3, M = 6;
173 const Result refK = solve(P, K, 0, -1),
refK1 = solve(P, K + 1, 0, -1);
175 std::printf(
" references: maxit %d -> it %d, maxit %d -> it %d, maxit %d -> it %d\n", K,
178 std::printf(
" FAIL: the reference solves must run to their caps unfailed\n");
181 fails += check(
"NaN pAp at iteration 3", solve(P, M, 1, K), K,
true,
refK);
182 fails += check(
"NaN r^T z at iteration 3", solve(P, M, 2, K), K,
true,
refK1);
184 check(
"NaN r^T z at the last iteration (maxit 4)", solve(P, K + 1, 2, K), K,
true,
refK1);
185 fails += check(
"NaN pAp at iteration 0", solve(P, M, 1, 0), 0,
true, solve(P, 0, 0, -1));
187 std::printf(
"%s\n",
fails ?
"pcg_breakdown: FAIL" :
"pcg_breakdown: PASS");
190 return fails ? 1 : 0;
void setDebugBreakdown(int which, int iter)
int solvePCG(CCField b, CCField x, CCField r, CCField p, CCField z, CCField Ap, int maxit, double rtol, int pre, int post, int bottom, const StarOverlay *star=nullptr, int nStar=0, C3 nnStar=C3{0, 0, 0})
void setOpenness(CCConst ox, CCConst oy, CCConst oz, double idx2, double idy2, double idz2)
void precondVcycle(CCField zz, CCField rr)
void setAgglomerationMode(int mode)
void init(int nx, int ny, int nz, int nLevels)
flow — portable (Kokkos) geometric multigrid for the cut-cell (variable-openness) pressure Poisson.
Kokkos::View< double *, CCMem > CCField
Kokkos::View< const double *, CCMem > CCConst
solve(N, kind, mu=0.1, F=1e-3, dt=80.0, warm_tol=1e-7, tail=40, max_steps=4000)
Kokkos::View< double *, Kokkos::HostSpace > x
static double mean(const std::vector< double > &a)