// On-site D2Q9 Zou-He velocity closure, paired lattice ordering. // Input is poststream f at the arrival time. Only unknown populations change; // the caller owns collision/store. No force, shifting or off-lattice walls. #ifndef CELERIS_BOUNDARY_PLANAR_VELOCITY_CUH #define CELERIS_BOUNDARY_PLANAR_VELOCITY_CUH __device__ __forceinline__ float bottom_wall_normal_velocity(unsigned int x) { #if WALL_SLOT_WIDTH > 0 && WALL_SLOT_WIDTH < NX // C1 compact profile centered at (NX-1)/2; amplitude is its continuous peak. const float s = (2.0f*(float)x-(float)(NX-1))/(float)WALL_SLOT_WIDTH; const float w = fmaxf(0.0f, 1.0f-s*s); return WALL_NORMAL_VELOCITY*w*w; #else return WALL_NORMAL_VELOCITY; // Disabled or explicitly uniform full width. #endif } __device__ __forceinline__ void reconstruct_bottom_velocity(float* f, float u, float v) { const float rho = (f[0] + f[1] + f[2] + 2.0f*(f[4] + f[6] + f[7])) / (1.0f-v); f[3] = f[4] + (2.0f/3.0f)*rho*v; f[5] = f[6] + 0.5f*(f[2]-f[1]) + 0.5f*rho*u + (1.0f/6.0f)*rho*v; f[8] = f[7] + 0.5f*(f[1]-f[2]) - 0.5f*rho*u + (1.0f/6.0f)*rho*v; } __device__ __forceinline__ void reconstruct_top_velocity(float* f, float u, float v) { const float rho = (f[0] + f[1] + f[2] + 2.0f*(f[3] + f[5] + f[8])) / (1.0f+v); f[4] = f[3] - (2.0f/3.0f)*rho*v; f[6] = f[5] + 0.5f*(f[1]-f[2]) - 0.5f*rho*u - (1.0f/6.0f)*rho*v; f[7] = f[8] + 0.5f*(f[2]-f[1]) + 0.5f*rho*u - (1.0f/6.0f)*rho*v; } // Fixed top density and tangential u=0; positive Cartesian v exits upward. // J_y=rho*v follows from known poststream populations (ordinary D2Q9). __device__ __forceinline__ void reconstruct_top_reservoir(float* f, float rho) { const float jy = f[0]+f[1]+f[2]+2.0f*(f[3]+f[5]+f[8])-rho; f[4] = f[3] - (2.0f/3.0f)*jy; f[6] = f[5] + 0.5f*(f[1]-f[2]) - (1.0f/6.0f)*jy; f[7] = f[8] + 0.5f*(f[2]-f[1]) - (1.0f/6.0f)*jy; } #endif