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
104 if (el_mesh .gt. msh%nelv) cycle
106 radius = 0.5_rp * d%x(i)
109 do candidate = 1, 2 * msh%gdim
112 x_old%x(i), y_old%x(i), z_old%x(i), x%x(i), y%x(i), &
113 z%x(i), radius, el_mesh, candidate, msh%gdim))
then
114 hit_count = hit_count + 1
115 hit_facets(hit_count) = candidate
118 if (hit_count .eq. 0) cycle
120 do hit_idx = 1, hit_count
121 facet = hit_facets(hit_idx)
123 if (norm2(normal) .le. epsilon(1.0_rp)) cycle
134 if (lag_len .ge. 1)
then
138 acc_zlag%x(i), normal)
140 if (lag_len .ge. 2)
then
142 w_laglag%x(i), normal)
144 acc_ylaglag%x(i), acc_zlaglag%x(i), normal)
152 lx, ly, lz, coef, x_old, y_old, z_old, x, y, z, radius, el, facet, &
154 logical,
intent(in) :: wall_facet_mask(:, :)
155 real(kind=
rp),
pointer,
dimension(:,:,:,:),
intent(in) :: dm_x
156 real(kind=
rp),
pointer,
dimension(:,:,:,:),
intent(in) :: dm_y
157 real(kind=
rp),
pointer,
dimension(:,:,:,:),
intent(in) :: dm_z
158 integer,
intent(in) :: lx
159 integer,
intent(in) :: ly
160 integer,
intent(in) :: lz
161 type(
coef_t),
intent(in) :: coef
162 real(kind=
rp),
intent(in) :: x_old
163 real(kind=
rp),
intent(in) :: y_old
164 real(kind=
rp),
intent(in) :: z_old
165 real(kind=
rp),
intent(in) :: x
166 real(kind=
rp),
intent(in) :: y
167 real(kind=
rp),
intent(in) :: z
168 real(kind=
rp),
intent(in) :: radius
169 integer,
intent(in) :: el
170 integer,
intent(in) :: facet
171 integer,
intent(in) :: gdim
172 real(kind=
rp),
parameter :: tol = 1.0e-8_rp
173 real(kind=
rp) :: normal(3)
174 real(kind=
rp) :: wall_point(3)
175 real(kind=
rp) :: dist_old
176 real(kind=
rp) :: dist_new
177 real(kind=
rp) :: penetration
181 if (facet .lt. 1 .or. facet .gt. 2 * gdim)
return
182 if (.not. wall_facet_mask(facet, el))
return
185 if (norm2(normal) .le. epsilon(1.0_rp))
return
189 penetration = dist_new + radius
191 if (penetration .le. tol)
return
192 if (dist_new .le. dist_old + tol)
return
200 type(
coef_t),
intent(in) :: coef
201 integer,
intent(in) :: lx
202 integer,
intent(in) :: ly
203 integer,
intent(in) :: lz
204 integer,
intent(in) :: el
205 integer,
intent(in) :: facet
206 real(kind=
rp),
intent(out) :: normal(3)
211 ic =
max(1, (lx + 1) / 2)
212 jc =
max(1, (ly + 1) / 2)
213 kc =
max(1, (lz + 1) / 2)
217 normal = coef%get_normal(1, jc, kc, el, facet)
219 normal = coef%get_normal(ic, 1, kc, el, facet)
221 normal = coef%get_normal(ic, jc, 1, el, facet)
231 real(kind=
rp),
pointer,
dimension(:,:,:,:),
intent(in) :: dm_x, dm_y, dm_z
232 integer,
intent(in) :: lx, ly, lz
233 integer,
intent(in) :: el
234 integer,
intent(in) :: facet
235 real(kind=
rp),
intent(out) :: wall_point(3)
240 ic =
max(1, (lx + 1) / 2)
241 jc =
max(1, (ly + 1) / 2)
242 kc =
max(1, (lz + 1) / 2)
246 wall_point = [dm_x(1, jc, kc, el), dm_y(1, jc, kc, el), &
249 wall_point = [dm_x(lx, jc, kc, el), &
250 dm_y(lx, jc, kc, el), &
251 dm_z(lx, jc, kc, el)]
253 wall_point = [dm_x(ic, 1, kc, el), dm_y(ic, 1, kc, el), &
256 wall_point = [dm_x(ic, ly, kc, el), &
257 dm_y(ic, ly, kc, el), &
258 dm_z(ic, ly, kc, el)]
260 wall_point = [dm_x(ic, jc, 1, el), dm_y(ic, jc, 1, el), &
263 wall_point = [dm_x(ic, jc, lz, el), &
264 dm_y(ic, jc, lz, el), &
265 dm_z(ic, jc, lz, el)]
280 real(kind=
rp),
intent(inout) :: x, y, z
281 real(kind=
rp),
intent(in) :: wall_point(3)
282 real(kind=
rp),
intent(in) :: normal(3)
283 real(kind=
rp),
intent(in) :: radius
284 real(kind=
rp) :: nhat(3)
285 real(kind=
rp) :: nmag
286 real(kind=
rp) :: signed_contact_distance
289 if (nmag .le. epsilon(1.0_rp))
return
292 signed_contact_distance = dot_product([x, y, z] - wall_point, nhat) + &
294 if (signed_contact_distance .le. 0.0_rp)
return
296 x = x - 2.0_rp * signed_contact_distance * nhat(1)
297 y = y - 2.0_rp * signed_contact_distance * nhat(2)
298 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.