17int main(
int argc,
char** argv) {
18 Kokkos::initialize(argc, argv);
21 const int N = 24, g = 1;
22 const double nu = 1.0, fx = 1.0;
23 I3 e{
N + 2 * g,
N + 2 * g,
N + 2 * g}, og{0, 0, 0};
24 const std::size_t n = (std::size_t)e.x * e.y * e.z;
26 const double Ac = 6.0 * nu;
28 SField u(
"u", n), b(
"b", n), dcorr(
"dcorr", n);
29 Kokkos::deep_copy(u, 0.0);
34 auto hb = Kokkos::create_mirror_view(b);
35 auto hd = Kokkos::create_mirror_view(dcorr);
36 Kokkos::deep_copy(hb, b);
37 Kokkos::deep_copy(hd, dcorr);
38 for (std::size_t i = 0; i < n; ++i) {
42 for (
int z = g; z < e.z - g; ++z)
43 for (
int y = g; y < e.y - g; ++y)
44 for (
int x = g; x < e.x - g; ++x) {
45 long i = (long)x + (
long)y * e.x + (long)z * (
long)e.x * e.y;
47 if (y == g || y == e.y - g - 1)
50 Kokkos::deep_copy(b, hb);
51 Kokkos::deep_copy(dcorr, hd);
61 "fx", Kokkos::MDRangePolicy<
SExec, Kokkos::Rank<2>>(space, {0, 0}, {e.y, e.z}),
62 KOKKOS_LAMBDA(
int y,
int z) {
63 long base = (long)y * e.x + (
long)z * (long)e.x * e.y;
64 for (
int gl = 0; gl < g; ++gl) {
65 uu(base + gl) = uu(base + gl +
N);
66 uu(base + g +
N + gl) = uu(base + g + gl);
71 "fz", Kokkos::MDRangePolicy<
SExec, Kokkos::Rank<2>>(space, {0, 0}, {e.x, e.y}),
72 KOKKOS_LAMBDA(
int x,
int y) {
73 long base = (long)x + (
long)y * e.x;
74 long sz = (long)e.x * e.y;
75 for (
int gl = 0; gl < g; ++gl) {
76 uu(base + (
long)gl * sz) = uu(base + (
long)(gl +
N) * sz);
77 uu(base + (
long)(g +
N + gl) * sz) = uu(base + (
long)(g + gl) * sz);
82 "fy", Kokkos::MDRangePolicy<
SExec, Kokkos::Rank<2>>(space, {0, 0}, {e.x, e.z}),
83 KOKKOS_LAMBDA(
int x,
int z) {
84 long base = (long)x + (
long)z * (long)e.x * e.y;
85 for (
int gl = 0; gl < g; ++gl) {
86 uu(base + (
long)gl * sy) = 0.0;
87 uu(base + (
long)(g +
N + gl) * sy) = 0.0;
94 for (
int it = 0; it < 6000; ++it) {
102 auto hu = Kokkos::create_mirror_view(u);
103 Kokkos::deep_copy(hu, u);
104 std::vector<double> prof(
N), exact(
N);
105 double umax = 0, usum = 0;
106 for (
int yc = 0; yc <
N; ++yc) {
107 long i = (long)(g) + (long)(yc + g) * e.x + (long)(g) * (long)e.x * e.y;
109 double yphys = yc + 0.5;
110 exact[yc] = (fx / (2.0 * nu)) * yphys * (
N - yphys);
111 umax = std::fmax(umax, prof[yc]);
114 const double umean = usum /
N;
115 const double ratio = umax / umean;
116 double num = 0, den = 0;
117 for (
int yc = 0; yc <
N; ++yc) {
118 num += (prof[yc] - exact[yc]) * (prof[yc] - exact[yc]);
119 den += exact[yc] * exact[yc];
121 const double l2err = std::sqrt(num / den);
124 "[poiseuille] u_max/U_mean=%.4f (target 1.5); profile L2 err vs parabola=%.3e "
127 if (std::fabs(ratio - 1.5) > 0.03) {
128 std::fprintf(stderr,
"FAIL: u_max/U_mean off 1.5\n");
132 std::fprintf(stderr,
"FAIL: profile not parabolic\n");
137 "[poiseuille] PASS: no-slip-wall diffusion gives the Poiseuille parabola (exec %s)\n",
138 Kokkos::DefaultExecutionSpace::name());