55 wall_facet_mask, el_list, x_old, y_old, z_old, x, y, z, d, u, v, w, &
56 u_lag, v_lag, w_lag, u_laglag, v_laglag, w_laglag, acc_xlag, &
57 acc_ylag, acc_zlag, acc_xlaglag, acc_ylaglag, acc_zlaglag, u_old, &
58 v_old, w_old, acc_x, acc_y, acc_z, lag_len, n)
59 type(
mesh_t),
intent(in) :: msh
60 type(
dofmap_t),
target,
intent(in) :: dm_xh
61 type(
coef_t),
intent(in) :: coef
62 logical,
intent(in) :: wall_facet_mask(:, :)
63 integer,
intent(in) :: el_list(:)
64 type(
vector_t),
intent(in) :: x_old, y_old, z_old
65 type(
vector_t),
intent(inout) :: x, y, z
67 type(
vector_t),
intent(inout) :: u, v, w
68 type(
vector_t),
intent(inout) :: u_lag, v_lag, w_lag
69 type(
vector_t),
intent(inout) :: u_laglag, v_laglag, w_laglag
70 type(
vector_t),
intent(inout) :: acc_xlag, acc_ylag, acc_zlag
71 type(
vector_t),
intent(inout) :: acc_xlaglag, acc_ylaglag
72 type(
vector_t),
intent(inout) :: acc_zlaglag
73 type(
vector_t),
intent(inout) :: u_old, v_old, w_old
74 type(
vector_t),
intent(inout) :: acc_x, acc_y, acc_z
75 integer,
intent(in) :: lag_len
76 integer,
intent(in) :: n
84 integer :: hit_facets(6)
85 real(kind=
rp) :: normal(3)
86 real(kind=
rp) :: wall_point(3)
87 real(kind=
rp) :: radius
88 real(kind=
rp),
pointer,
dimension(:,:,:,:) :: dm_x, dm_y, dm_z
95 call coef%require_facets(
'lpt wall collisions')
108 if (el_mesh .gt. msh%nelv) cycle
110 radius = 0.5_rp * d%x(i)
113 do candidate = 1, 2 * msh%gdim
116 x_old%x(i), y_old%x(i), z_old%x(i), x%x(i), y%x(i), &
117 z%x(i), radius, el_mesh, candidate, msh%gdim))
then
118 hit_count = hit_count + 1
119 hit_facets(hit_count) = candidate
122 if (hit_count .eq. 0) cycle
124 do hit_idx = 1, hit_count
125 facet = hit_facets(hit_idx)
127 if (norm2(normal) .le. epsilon(1.0_rp)) cycle
138 if (lag_len .ge. 1)
then
142 acc_zlag%x(i), normal)
144 if (lag_len .ge. 2)
then
146 w_laglag%x(i), normal)
148 acc_ylaglag%x(i), acc_zlaglag%x(i), normal)
156 lx, ly, lz, coef, x_old, y_old, z_old, x, y, z, radius, el, facet, &
158 logical,
intent(in) :: wall_facet_mask(:, :)
159 real(kind=
rp),
pointer,
dimension(:,:,:,:),
intent(in) :: dm_x
160 real(kind=
rp),
pointer,
dimension(:,:,:,:),
intent(in) :: dm_y
161 real(kind=
rp),
pointer,
dimension(:,:,:,:),
intent(in) :: dm_z
162 integer,
intent(in) :: lx
163 integer,
intent(in) :: ly
164 integer,
intent(in) :: lz
165 type(
coef_t),
intent(in) :: coef
166 real(kind=
rp),
intent(in) :: x_old
167 real(kind=
rp),
intent(in) :: y_old
168 real(kind=
rp),
intent(in) :: z_old
169 real(kind=
rp),
intent(in) :: x
170 real(kind=
rp),
intent(in) :: y
171 real(kind=
rp),
intent(in) :: z
172 real(kind=
rp),
intent(in) :: radius
173 integer,
intent(in) :: el
174 integer,
intent(in) :: facet
175 integer,
intent(in) :: gdim
176 real(kind=
rp),
parameter :: tol = 1.0e-8_rp
177 real(kind=
rp) :: normal(3)
178 real(kind=
rp) :: wall_point(3)
179 real(kind=
rp) :: dist_old
180 real(kind=
rp) :: dist_new
181 real(kind=
rp) :: penetration
185 if (facet .lt. 1 .or. facet .gt. 2 * gdim)
return
186 if (.not. wall_facet_mask(facet, el))
return
189 if (norm2(normal) .le. epsilon(1.0_rp))
return
193 penetration = dist_new + radius
195 if (penetration .le. tol)
return
196 if (dist_new .le. dist_old + tol)
return
204 type(
coef_t),
intent(in) :: coef
205 integer,
intent(in) :: lx
206 integer,
intent(in) :: ly
207 integer,
intent(in) :: lz
208 integer,
intent(in) :: el
209 integer,
intent(in) :: facet
210 real(kind=
rp),
intent(out) :: normal(3)
215 ic =
max(1, (lx + 1) / 2)
216 jc =
max(1, (ly + 1) / 2)
217 kc =
max(1, (lz + 1) / 2)
221 normal = coef%get_normal(1, jc, kc, el, facet)
223 normal = coef%get_normal(ic, 1, kc, el, facet)
225 normal = coef%get_normal(ic, jc, 1, el, facet)
235 real(kind=
rp),
pointer,
dimension(:,:,:,:),
intent(in) :: dm_x, dm_y, dm_z
236 integer,
intent(in) :: lx, ly, lz
237 integer,
intent(in) :: el
238 integer,
intent(in) :: facet
239 real(kind=
rp),
intent(out) :: wall_point(3)
244 ic =
max(1, (lx + 1) / 2)
245 jc =
max(1, (ly + 1) / 2)
246 kc =
max(1, (lz + 1) / 2)
250 wall_point = [dm_x(1, jc, kc, el), dm_y(1, jc, kc, el), &
253 wall_point = [dm_x(lx, jc, kc, el), &
254 dm_y(lx, jc, kc, el), &
255 dm_z(lx, jc, kc, el)]
257 wall_point = [dm_x(ic, 1, kc, el), dm_y(ic, 1, kc, el), &
260 wall_point = [dm_x(ic, ly, kc, el), &
261 dm_y(ic, ly, kc, el), &
262 dm_z(ic, ly, kc, el)]
264 wall_point = [dm_x(ic, jc, 1, el), dm_y(ic, jc, 1, el), &
267 wall_point = [dm_x(ic, jc, lz, el), &
268 dm_y(ic, jc, lz, el), &
269 dm_z(ic, jc, lz, el)]
284 real(kind=
rp),
intent(inout) :: x, y, z
285 real(kind=
rp),
intent(in) :: wall_point(3)
286 real(kind=
rp),
intent(in) :: normal(3)
287 real(kind=
rp),
intent(in) :: radius
288 real(kind=
rp) :: nhat(3)
289 real(kind=
rp) :: nmag
290 real(kind=
rp) :: signed_contact_distance
293 if (nmag .le. epsilon(1.0_rp))
return
296 signed_contact_distance = dot_product([x, y, z] - wall_point, nhat) + &
298 if (signed_contact_distance .le. 0.0_rp)
return
300 x = x - 2.0_rp * signed_contact_distance * nhat(1)
301 y = y - 2.0_rp * signed_contact_distance * nhat(2)
302 z = z - 2.0_rp * signed_contact_distance * nhat(3)
logical function wall_facet_is_hit(wall_facet_mask, dm_x, dm_y, dm_z, lx, ly, lz, coef, x_old, y_old, z_old, x, y, z, radius, el, facet, gdim)
Return true if the particle surface reaches a given wall facet.
subroutine, public lpt_handle_elastic_wall_collisions_cpu(msh, dm_xh, coef, wall_facet_mask, el_list, x_old, y_old, z_old, x, y, z, d, u, v, w, u_lag, v_lag, w_lag, u_laglag, v_laglag, w_laglag, acc_xlag, acc_ylag, acc_zlag, acc_xlaglag, acc_ylaglag, acc_zlaglag, u_old, v_old, w_old, acc_x, acc_y, acc_z, lag_len, n)
Reflect inertial particles that hit configured wall facets on the CPU.