Neko 1.99.6
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
lpt_wall_collision_kernel.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2026, The Neko Authors
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 * Redistributions in binary form must reproduce the above
13 copyright notice, this list of conditions and the following
14 disclaimer in the documentation and/or other materials provided
15 with the distribution.
16
17 * Neither the name of the authors nor the names of its
18 contributors may be used to endorse or promote products derived
19 from this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#ifndef __LPT_WALL_COLLISION_KERNEL_H__
36#define __LPT_WALL_COLLISION_KERNEL_H__
37
38#include <math.h>
40
41__device__ inline int lpt_wall_dof_idx(const int i,
42 const int j,
43 const int k,
44 const int e,
45 const int lx,
46 const int ly,
47 const int lz) {
48 return (i - 1) + lx * ((j - 1) + ly * ((k - 1) + lz * (e - 1)));
49}
50
51__device__ inline int lpt_wall_mask_idx(const int facet,
52 const int el,
53 const int n_facets) {
54 return (facet - 1) + n_facets * (el - 1);
55}
56
57__device__ inline int lpt_wall_imax(const int a, const int b) {
58 return a > b ? a : b;
59}
60
61template<typename T>
62__device__ inline T lpt_norm3(const T x, const T y, const T z) {
63 return sqrt(x * x + y * y + z * z);
64}
65
66template<typename T>
68 const T * __restrict__ dm_x,
69 const T * __restrict__ dm_y,
70 const T * __restrict__ dm_z,
71 const int lx,
72 const int ly,
73 const int lz,
74 const int el,
75 const int facet,
76 T &wall_x,
77 T &wall_y,
78 T &wall_z) {
79 const int ic = lpt_wall_imax(1, (lx + 1) / 2);
80 const int jc = lpt_wall_imax(1, (ly + 1) / 2);
81 const int kc = lpt_wall_imax(1, (lz + 1) / 2);
82 int idx = 0;
83
84 switch (facet) {
85 case 1:
86 idx = lpt_wall_dof_idx(1, jc, kc, el, lx, ly, lz);
87 break;
88 case 2:
89 idx = lpt_wall_dof_idx(lx, jc, kc, el, lx, ly, lz);
90 break;
91 case 3:
92 idx = lpt_wall_dof_idx(ic, 1, kc, el, lx, ly, lz);
93 break;
94 case 4:
95 idx = lpt_wall_dof_idx(ic, ly, kc, el, lx, ly, lz);
96 break;
97 case 5:
98 idx = lpt_wall_dof_idx(ic, jc, 1, el, lx, ly, lz);
99 break;
100 case 6:
101 idx = lpt_wall_dof_idx(ic, jc, lz, el, lx, ly, lz);
102 break;
103 default:
104 wall_x = 0.0;
105 wall_y = 0.0;
106 wall_z = 0.0;
107 return;
108 }
109
110 wall_x = dm_x[idx];
111 wall_y = dm_y[idx];
112 wall_z = dm_z[idx];
113}
114
115template<typename T>
117 const T * __restrict__ nx,
118 const T * __restrict__ ny,
119 const T * __restrict__ nz,
120 const int lx,
121 const int ly,
122 const int lz,
123 const int el,
124 const int facet,
125 T &normal_x,
126 T &normal_y,
127 T &normal_z) {
128 const int ic = lpt_wall_imax(1, (lx + 1) / 2);
129 const int jc = lpt_wall_imax(1, (ly + 1) / 2);
130 const int kc = lpt_wall_imax(1, (lz + 1) / 2);
131
132 switch (facet) {
133 case 1:
134 case 2:
135 coef_get_normal_device(nx, ny, nz, 1, jc, kc, el, facet, lx, normal_x,
137 break;
138 case 3:
139 case 4:
140 coef_get_normal_device(nx, ny, nz, ic, 1, kc, el, facet, lx, normal_x,
142 break;
143 case 5:
144 case 6:
145 coef_get_normal_device(nx, ny, nz, ic, jc, 1, el, facet, lx, normal_x,
147 break;
148 default:
149 normal_x = 0.0;
150 normal_y = 0.0;
151 normal_z = 0.0;
152 break;
153 }
154}
155
156template<typename T>
158 const T y,
159 const T z,
160 const T wall_x,
161 const T wall_y,
162 const T wall_z,
163 const T normal_x,
164 const T normal_y,
165 const T normal_z) {
166 const T eps = (T) 1.0e-12;
168 if (nmag <= eps) {
169 return -1.0e30;
170 }
171
172 return ((x - wall_x) * normal_x + (y - wall_y) * normal_y +
173 (z - wall_z) * normal_z) / nmag;
174}
175
176template<typename T>
178 const int * __restrict__ wall_facet_mask,
179 const T * __restrict__ dm_x,
180 const T * __restrict__ dm_y,
181 const T * __restrict__ dm_z,
182 const T * __restrict__ nx,
183 const T * __restrict__ ny,
184 const T * __restrict__ nz,
185 const int lx,
186 const int ly,
187 const int lz,
188 const int el,
189 const int facet,
190 const int gdim,
191 const T x_old,
192 const T y_old,
193 const T z_old,
194 const T x,
195 const T y,
196 const T z,
197 const T radius) {
198 const int n_facets = 2 * gdim;
199 const T tol = (T) 1.0e-8;
202
204 return false;
205 }
206 if (wall_facet_mask[lpt_wall_mask_idx(facet, el, n_facets)] == 0) {
207 return false;
208 }
209
210 lpt_wall_facet_normal(nx, ny, nz, lx, ly, lz, el, facet, normal_x,
212 if (lpt_norm3(normal_x, normal_y, normal_z) <= (T) 1.0e-12) {
213 return false;
214 }
215
216 lpt_wall_facet_center(dm_x, dm_y, dm_z, lx, ly, lz, el, facet, wall_x,
217 wall_y, wall_z);
223 normal_z);
224 const T penetration = dist_new + radius;
225
226 if (penetration <= tol) {
227 return false;
228 }
229 if (dist_new <= dist_old + tol) {
230 return false;
231 }
232
233 return true;
234}
235
236template<typename T>
238 T &y,
239 T &z,
240 const T wall_x,
241 const T wall_y,
242 const T wall_z,
243 const T normal_x,
244 const T normal_y,
245 const T normal_z,
246 const T radius) {
247 const T eps = (T) 1.0e-12;
249 if (nmag <= eps) {
250 return;
251 }
252
253 const T nhat_x = normal_x / nmag;
254 const T nhat_y = normal_y / nmag;
255 const T nhat_z = normal_z / nmag;
257 (x - wall_x) * nhat_x + (y - wall_y) * nhat_y +
258 (z - wall_z) * nhat_z + radius;
259
260 if (signed_contact_distance <= 0.0) {
261 return;
262 }
263
265 y -= 2.0 * signed_contact_distance * nhat_y;
266 z -= 2.0 * signed_contact_distance * nhat_z;
267}
268
269template<typename T>
271 T &y,
272 T &z,
273 const T normal_x,
274 const T normal_y,
275 const T normal_z) {
276 const T eps = (T) 1.0e-12;
278 if (nmag <= eps) {
279 return;
280 }
281
282 const T nhat_x = normal_x / nmag;
283 const T nhat_y = normal_y / nmag;
284 const T nhat_z = normal_z / nmag;
285 const T vn = x * nhat_x + y * nhat_y + z * nhat_z;
286
287 x -= 2.0 * vn * nhat_x;
288 y -= 2.0 * vn * nhat_y;
289 z -= 2.0 * vn * nhat_z;
290}
291
292template<typename T>
294 const int * __restrict__ wall_facet_mask,
295 const int * __restrict__ el_list,
296 const T * __restrict__ x_old,
297 const T * __restrict__ y_old,
298 const T * __restrict__ z_old,
299 T * __restrict__ x,
300 T * __restrict__ y,
301 T * __restrict__ z,
302 const T * __restrict__ d,
303 T * __restrict__ u,
304 T * __restrict__ v,
305 T * __restrict__ w,
306 T * __restrict__ u_lag,
307 T * __restrict__ v_lag,
308 T * __restrict__ w_lag,
309 T * __restrict__ u_laglag,
310 T * __restrict__ v_laglag,
311 T * __restrict__ w_laglag,
312 T * __restrict__ acc_xlag,
313 T * __restrict__ acc_ylag,
314 T * __restrict__ acc_zlag,
315 T * __restrict__ acc_xlaglag,
316 T * __restrict__ acc_ylaglag,
317 T * __restrict__ acc_zlaglag,
321 T * __restrict__ acc_x,
322 T * __restrict__ acc_y,
323 T * __restrict__ acc_z,
324 const T * __restrict__ dm_x,
325 const T * __restrict__ dm_y,
326 const T * __restrict__ dm_z,
327 const T * __restrict__ nx,
328 const T * __restrict__ ny,
329 const T * __restrict__ nz,
330 const int n,
331 const int gdim,
332 const int nelv,
333 const int lx,
334 const int ly,
335 const int lz,
336 const int lag_len) {
337 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
338 const int str = blockDim.x * gridDim.x;
339 const int n_facets = 2 * gdim;
340
341 for (int p = idx; p < n; p += str) {
342 const int el = el_list[p];
343 if (el < 0) {
344 continue;
345 }
346
347 const int el_mesh = el + 1;
348 if (el_mesh > nelv) {
349 continue;
350 }
351
352 const T radius = 0.5 * d[p];
353 int hit_facets[6];
354 int hit_count = 0;
355
356 for (int candidate = 1; candidate <= n_facets; candidate++) {
357 if (lpt_wall_facet_is_hit(wall_facet_mask, dm_x, dm_y, dm_z, nx, ny,
358 nz, lx, ly, lz, el_mesh, candidate, gdim,
359 x_old[p], y_old[p], z_old[p], x[p], y[p],
360 z[p], radius)) {
362 hit_count++;
363 }
364 }
365
366 if (hit_count == 0) {
367 continue;
368 }
369
370 T x_new = x[p];
371 T y_new = y[p];
372 T z_new = z[p];
373
374 for (int hit_idx = 0; hit_idx < hit_count; hit_idx++) {
375 const int facet = hit_facets[hit_idx];
378
379 lpt_wall_facet_normal(nx, ny, nz, lx, ly, lz, el_mesh, facet,
381 if (lpt_norm3(normal_x, normal_y, normal_z) <= (T) 1.0e-12) {
382 continue;
383 }
384
385 lpt_wall_facet_center(dm_x, dm_y, dm_z, lx, ly, lz, el_mesh, facet,
388 normal_x, normal_y, normal_z, radius);
390 normal_z);
393 lpt_reflect_vector_components(acc_x[p], acc_y[p], acc_z[p], normal_x,
395
396 if (lag_len >= 1) {
397 lpt_reflect_vector_components(u_lag[p], v_lag[p], w_lag[p],
399 lpt_reflect_vector_components(acc_xlag[p], acc_ylag[p], acc_zlag[p],
401 }
402
403 if (lag_len >= 2) {
404 lpt_reflect_vector_components(u_laglag[p], v_laglag[p], w_laglag[p],
406 lpt_reflect_vector_components(acc_xlaglag[p], acc_ylaglag[p],
407 acc_zlaglag[p], normal_x, normal_y,
408 normal_z);
409 }
410 }
411
412 x[p] = x_new;
413 y[p] = y_new;
414 z[p] = z_new;
415 }
416}
417
418#endif
__global__ void ale_add_kinematics_kernel(const int n, T *__restrict__ wx, T *__restrict__ wy, T *__restrict__ wz, const T *__restrict__ x_ref, const T *__restrict__ y_ref, const T *__restrict__ z_ref, const T *__restrict__ phi, const T *__restrict__ x, const T *__restrict__ y, const T *__restrict__ z, const kinematics_params_t kin_params)
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ w
const int i
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ u
const int e
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ v
const int j
__global__ void const T *__restrict__ x
__device__ void coef_get_normal_device(const T *__restrict__ nx, const T *__restrict__ ny, const T *__restrict__ nz, const int i, const int j, const int k, const int e, const int facet, const int lx, T &normal_x, T &normal_y, T &normal_z)
__device__ int lpt_wall_dof_idx(const int i, const int j, const int k, const int e, const int lx, const int ly, const int lz)
__device__ T lpt_signed_plane_distance(const T x, const T y, const T z, const T wall_x, const T wall_y, const T wall_z, const T normal_x, const T normal_y, const T normal_z)
__device__ int lpt_wall_imax(const int a, const int b)
__device__ void lpt_wall_facet_normal(const T *__restrict__ nx, const T *__restrict__ ny, const T *__restrict__ nz, const int lx, const int ly, const int lz, const int el, const int facet, T &normal_x, T &normal_y, T &normal_z)
__device__ void lpt_reflect_position(T &x, T &y, T &z, const T wall_x, const T wall_y, const T wall_z, const T normal_x, const T normal_y, const T normal_z, const T radius)
__device__ int lpt_wall_mask_idx(const int facet, const int el, const int n_facets)
__device__ void lpt_wall_facet_center(const T *__restrict__ dm_x, const T *__restrict__ dm_y, const T *__restrict__ dm_z, const int lx, const int ly, const int lz, const int el, const int facet, T &wall_x, T &wall_y, T &wall_z)
__device__ T lpt_norm3(const T x, const T y, const T z)
__device__ bool lpt_wall_facet_is_hit(const int *__restrict__ wall_facet_mask, const T *__restrict__ dm_x, const T *__restrict__ dm_y, const T *__restrict__ dm_z, const T *__restrict__ nx, const T *__restrict__ ny, const T *__restrict__ nz, const int lx, const int ly, const int lz, const int el, const int facet, const int gdim, const T x_old, const T y_old, const T z_old, const T x, const T y, const T z, const T radius)
__device__ void lpt_reflect_vector_components(T &x, T &y, T &z, const T normal_x, const T normal_y, const T normal_z)
__global__ void lpt_handle_elastic_wall_collisions_kernel(const int *__restrict__ wall_facet_mask, const int *__restrict__ el_list, const T *__restrict__ x_old, const T *__restrict__ y_old, const T *__restrict__ z_old, T *__restrict__ x, T *__restrict__ y, T *__restrict__ z, const T *__restrict__ d, T *__restrict__ u, T *__restrict__ v, T *__restrict__ w, T *__restrict__ u_lag, T *__restrict__ v_lag, T *__restrict__ w_lag, T *__restrict__ u_laglag, T *__restrict__ v_laglag, T *__restrict__ w_laglag, T *__restrict__ acc_xlag, T *__restrict__ acc_ylag, T *__restrict__ acc_zlag, T *__restrict__ acc_xlaglag, T *__restrict__ acc_ylaglag, T *__restrict__ acc_zlaglag, T *__restrict__ u_old, T *__restrict__ v_old, T *__restrict__ w_old, T *__restrict__ acc_x, T *__restrict__ acc_y, T *__restrict__ acc_z, const T *__restrict__ dm_x, const T *__restrict__ dm_y, const T *__restrict__ dm_z, const T *__restrict__ nx, const T *__restrict__ ny, const T *__restrict__ nz, const int n, const int gdim, const int nelv, const int lx, const int ly, const int lz, const int lag_len)