15int main(
int argc,
char** argv) {
16 Kokkos::initialize(argc, argv);
20 const int nx = 4, nz = 4, ny = 48;
24 const double ylo = 6.5, yhi = ny - 6.5;
25 const double H = yhi - ylo;
26 const double rho = 1.0, mu = 0.1, dt = 50.0,
F = 0.01;
27 const double idiag = rho / dt, beta = mu;
28 C3 e{nx + 2 * g, ny + 2 * g, nz + 2 * g};
29 const std::size_t n = (std::size_t)e.x * e.y * e.z;
30 const Off3 offU{-0.5f, 0.0f, 0.0f};
36 auto h = Kokkos::create_mirror_view(sdf);
37 for (
int z = 0; z < e.z; ++z)
38 for (
int y = 0; y < e.y; ++y)
39 for (
int x = 0; x < e.x; ++x) {
41 double s = std::min((
double)iy - ylo, yhi - (
double)iy);
42 h((
long)x + (
long)y * e.x + (
long)z * (
long)e.x * e.y) = s;
44 Kokkos::deep_copy(sdf, h);
48 const int maxCut = (int)((
long)nx * ny * nz);
49 IbmOverlay ov{Kokkos::View<int*, CCMem>(
"ci", maxCut),
50 Kokkos::View<int*, CCMem>(
"nb", maxCut),
51 Kokkos::View<float*, CCMem>(
"dr", maxCut),
52 Kokkos::View<int*, CCMem>(
"dc", (std::size_t)maxCut * 6),
53 Kokkos::View<float*, CCMem>(
"K", (std::size_t)maxCut * 6),
54 Kokkos::View<float*, CCMem>(
"M", (std::size_t)maxCut * 6),
55 Kokkos::View<float*, CCMem>(
"X", (std::size_t)maxCut * 6),
56 Kokkos::View<float*, CCMem>(
"Nbc", (std::size_t)maxCut * 6),
57 Kokkos::View<float*, CCMem>(
"R", (std::size_t)maxCut * 6)};
58 Kokkos::View<int*, CCMem> idMap(
"idMap", n);
59 Kokkos::View<int, CCMem> counter(
"counter");
61 buildIbmOverlay<1>(
CCConst(sdf), e, g, offU, 0, ov, idMap, counter);
64 using FV = Kokkos::View<float*, CCMem>;
65 FV AC(
"AC", n), AW(
"AW", n), AE(
"AE", n), AS(
"AS", n), AN(
"AN", n), AB(
"AB", n), AT(
"AT", n);
66 Kokkos::View<double*, CCMem> inhom(
"inhom", n), rscale(
"rscale", n);
67 Kokkos::deep_copy(rscale, 1.0);
68 ibmBuildDiffusion(
AC, AW, AE, AS, AN, AB, AT, e.x, e.y, e.z, beta, idiag);
69 ibmModifyStencil(
AC, AW, AE, AS, AN, AB, AT, inhom, rscale, ov, nCut, 0.0f);
76 Kokkos::deep_copy(u, 0.0);
82 const int Nx = nx, Nz = nz;
84 "fx", Kokkos::MDRangePolicy<
CCExec, Kokkos::Rank<2>>(space, {0, 0}, {e.y, e.z}),
85 KOKKOS_LAMBDA(
int y,
int z) {
86 long base = (long)y * e.x + (
long)z * (long)e.x * e.y;
87 for (
int gl = 0; gl < g; ++gl) {
88 uu(base + gl) = uu(base + gl + Nx);
89 uu(base + g + Nx + gl) = uu(base + g + gl);
93 "fz", Kokkos::MDRangePolicy<
CCExec, Kokkos::Rank<2>>(space, {0, 0}, {e.x, e.y}),
94 KOKKOS_LAMBDA(
int x,
int y) {
95 long base = (long)x + (
long)y * e.x;
96 long sz = (long)e.x * e.y;
97 for (
int gl = 0; gl < g; ++gl) {
98 uu(base + (
long)gl * sz) = uu(base + (
long)(gl + Nz) * sz);
99 uu(base + (
long)(g + Nz + gl) * sz) = uu(base + (
long)(g + gl) * sz);
106 for (
int step = 0; step < 600; ++step) {
111 double id = idiag, ff =
F;
112 Kokkos::parallel_for(
113 "rhs", Kokkos::RangePolicy<CCExec>(space, 0, n),
114 KOKKOS_LAMBDA(std::size_t i) { bb(i) = rs(i) * (
id * uu(i) + ff); });
117 for (
int it = 0; it < 200; ++it) {
130 auto hu = Kokkos::create_mirror_view(u);
131 Kokkos::deep_copy(hu, u);
132 const double Uana =
F * H * H / (8.0 * mu);
133 double umax = 0, l2num = 0, l2den = 0;
134 for (
int iy = 0; iy < ny; ++iy) {
135 long i = (long)g + (
long)(iy + g) * e.x + (
long)g * (long)e.x * e.y;
137 umax = std::fmax(umax, un);
138 if (iy > ylo && iy < yhi) {
140 double ue = (
F / (2.0 * mu)) * (yy - ylo) * (yhi - yy);
141 l2num += (un - ue) * (un - ue);
145 const double l2err = std::sqrt(l2num / l2den);
146 const double umaxErr = std::fabs(umax - Uana) / Uana;
148 "[poiseuille_ibm] cut cells=%d; U_max=%.5f analytic=%.5f (err %.2e); profile L2 err=%.2e\n",
149 nCut, umax, Uana, umaxErr, l2err);
151 std::fprintf(stderr,
"FAIL: no cut cells found\n");
154 if (umaxErr > 3e-2) {
155 std::fprintf(stderr,
"FAIL: U_max off analytic\n");
159 std::fprintf(stderr,
"FAIL: profile not parabolic\n");
163 std::printf(
"[poiseuille_ibm] PASS: IBM cut-cell channel reproduces Poiseuille (exec %s)\n",
164 Kokkos::DefaultExecutionSpace::name());
void ibmBuildDiffusion(Kokkos::View< float *, IMem > AC, Kokkos::View< float *, IMem > AW, Kokkos::View< float *, IMem > AE, Kokkos::View< float *, IMem > AS, Kokkos::View< float *, IMem > AN, Kokkos::View< float *, IMem > AB, Kokkos::View< float *, IMem > AT, int ex, int ey, int ez, double beta, double idiag)
void ibmModifyStencil(Kokkos::View< float *, IMem > AC, Kokkos::View< float *, IMem > AW, Kokkos::View< float *, IMem > AE, Kokkos::View< float *, IMem > AS, Kokkos::View< float *, IMem > AN, Kokkos::View< float *, IMem > AB, Kokkos::View< float *, IMem > AT, Kokkos::View< double *, IMem > a_inhom, Kokkos::View< double *, IMem > rhs_scale, const IbmOverlay &ibm, int numActive, float u_bc_val)