15int main(
int argc,
char** argv) {
16 Kokkos::initialize(argc, argv);
22 T3 cext{cinner.
x + 2 * g, cinner.y + 2 * g, cinner.z + 2 * g};
23 T3 finner{ratio.
x * cinner.x, ratio.y * cinner.y, ratio.z * cinner.z};
24 T3 fext{finner.
x + 2 * g, finner.y + 2 * g, finner.z + 2 * g};
25 auto cn = (std::size_t)cext.x * cext.y * cext.z;
26 auto fn = (std::size_t)fext.x * fext.y * fext.z;
29 std::uniform_real_distribution<double> uf(-1.0, 1.0);
30 std::vector<double> hfine(fn), hcoarse(cn), hu(fn), hv(fn), hw(fn), hphi(fn);
31 for (
auto* vec : {&hfine, &hu, &hv, &hw, &hphi})
34 for (
auto& x : hcoarse)
37 auto upN = [&](
const char* nm, std::vector<double>& h, std::size_t n) {
39 auto m = Kokkos::create_mirror_view(v);
40 for (std::size_t i = 0; i < n; ++i)
42 Kokkos::deep_copy(v, m);
45 auto get = [&](
TField v, std::size_t n) {
46 std::vector<double> o(n);
47 auto m = Kokkos::create_mirror_view(v);
48 Kokkos::deep_copy(m, v);
49 for (std::size_t i = 0; i < n; ++i)
53 auto close = [](
double a,
double b) {
54 return std::fabs(a - b) <= 1e-10 * (1.0 + std::fabs(b));
56 long lc = [&](
int x,
int y,
int z) {
57 return (
long)x + (long)y * cext.x + (
long)z * (long)cext.x * cext.y;
60 auto CI = [&](
int x,
int y,
int z) {
61 return (std::size_t)x + (std::size_t)y * cext.x +
62 (std::size_t)z * (std::size_t)cext.x * cext.y;
64 auto FI = [&](
int x,
int y,
int z) {
65 return (std::size_t)x + (std::size_t)y * fext.x +
66 (std::size_t)z * (std::size_t)fext.x * fext.y;
71 TField fine = upN(
"fine", hfine, fn), coarse(
"coarse", cn);
72 restrict_(coarse, fine, cext, fext, g, cinner, ratio);
73 auto gco = get(coarse, cn);
74 for (
int icz = 0; icz < cinner.z; ++icz)
75 for (
int icy = 0; icy < cinner.y; ++icy)
76 for (
int icx = 0; icx < cinner.x; ++icx) {
78 for (
int dz = 0; dz < ratio.z; ++dz)
79 for (
int dy = 0; dy < ratio.y; ++dy)
80 for (
int dx = 0; dx < ratio.x; ++dx)
81 s += hfine[FI(ratio.x * icx + dx + g, ratio.y * icy + dy + g,
82 ratio.z * icz + dz + g)];
83 double r = s / (ratio.x * ratio.y * ratio.z);
84 if (!close(gco[CI(icx + g, icy + g, icz + g)], r))
89 TField coarse2 = upN(
"coarse2", hcoarse, cn), fine2 = upN(
"fine2", hfine, fn);
90 prolong(fine2, coarse2, fext, cext, g, finner, ratio);
91 auto gf = get(fine2, fn);
92 auto trilerp_h = [&](
double x,
double y,
double z) {
93 double fx = std::floor(x), fy = std::floor(y), fz = std::floor(z);
94 double wx = x - fx, wy = y - fy, wz = z - fz;
95 int x0 = (int)fx, y0 = (
int)fy, z0 = (int)fz;
96 auto F = [&](
int xx,
int yy,
int zz) {
return hcoarse[CI(xx, yy, zz)]; };
97 double c00 =
F(x0, y0, z0) * (1 - wx) +
F(x0 + 1, y0, z0) * wx,
98 c10 =
F(x0, y0 + 1, z0) * (1 - wx) +
F(x0 + 1, y0 + 1, z0) * wx;
99 double c01 =
F(x0, y0, z0 + 1) * (1 - wx) +
F(x0 + 1, y0, z0 + 1) * wx,
100 c11 =
F(x0, y0 + 1, z0 + 1) * (1 - wx) +
F(x0 + 1, y0 + 1, z0 + 1) * wx;
101 double c0 = c00 * (1 - wy) + c10 * wy, c1 = c01 * (1 - wy) + c11 * wy;
102 return c0 * (1 - wz) + c1 * wz;
104 for (
int ifz = 0; ifz < finner.z; ++ifz)
105 for (
int ify = 0; ify < finner.y; ++ify)
106 for (
int ifx = 0; ifx < finner.x; ++ifx) {
107 double cx = ratio.x == 2 ? 0.5 * ifx - 0.25 + g : (double)(ifx + g);
108 double cy = ratio.y == 2 ? 0.5 * ify - 0.25 + g : (double)(ify + g);
109 double cz = ratio.z == 2 ? 0.5 * ifz - 0.25 + g : (double)(ifz + g);
110 double r = hfine[FI(ifx + g, ify + g, ifz + g)] + trilerp_h(cx, cy, cz);
111 if (!close(gf[FI(ifx + g, ify + g, ifz + g)], r))
116 TField u = upN(
"u", hu, fn), v = upN(
"v", hv, fn), w = upN(
"w", hw, fn),
117 phi = upN(
"phi", hphi, fn);
118 correct(u, v, w, phi, fext, g);
119 auto gu = get(u, fn), gvv = get(v, fn), gw = get(w, fn);
120 for (
int z = g; z < fext.z - g; ++z)
121 for (
int y = g; y < fext.y - g; ++y)
122 for (
int x = g; x < fext.x - g; ++x) {
123 std::size_t i = FI(x, y, z);
124 long sx = 1, sy = fext.x, sz = (long)fext.x * fext.y;
125 if (!close(gu[i], hu[i] - (hphi[i] - hphi[i - sx])))
127 if (!close(gvv[i], hv[i] - (hphi[i] - hphi[i - sy])))
129 if (!close(gw[i], hw[i] - (hphi[i] - hphi[i - sz])))
133 std::fprintf(stderr,
"FAIL: %d transfer/correct cells differ\n", bad);
138 std::vector<double> ones(fn, 3.5);
139 TField cf = upN(
"cf", ones, fn), cc(
"cc", cn);
140 restrict_(cc, cf, cext, fext, g, cinner, ratio);
141 auto gcc = get(cc, cn);
142 for (
int icz = 0; icz < cinner.z; ++icz)
143 for (
int icy = 0; icy < cinner.y; ++icy)
144 for (
int icx = 0; icx < cinner.x; ++icx)
145 if (!close(gcc[CI(icx + g, icy + g, icz + g)], 3.5))
147 std::vector<double> cones(cn, 2.0), fzero(fn, 0.0);
148 TField cc2 = upN(
"cc2", cones, cn), ff = upN(
"ff", fzero, fn);
149 prolong(ff, cc2, fext, cext, g, finner, ratio);
150 auto gff = get(ff, fn);
151 for (
int ifz = 0; ifz < finner.z; ++ifz)
152 for (
int ify = 0; ify < finner.y; ++ify)
153 for (
int ifx = 0; ifx < finner.x; ++ifx)
154 if (!close(gff[FI(ifx + g, ify + g, ifz + g)], 2.0))
156 if (bad && !status) {
157 std::fprintf(stderr,
"FAIL: constant-field property\n");
163 "[mac_transfer] PASS: restrict/prolong/correct match host + constant properties (exec: "