Neko 1.99.6
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
lpt_wall_collision.f90
Go to the documentation of this file.
1! Copyright (c) 2026, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
34submodule(lpt) lpt_wall_collision
37 use lpt_wall_collision_device, only : &
41 use, intrinsic :: iso_c_binding, only : c_ptr, c_null_ptr, c_associated
43 implicit none
44
45contains
46
51 module subroutine lpt_init_wall_facet_mask(wall_facet_mask, msh, &
52 wall_zone_indices)
53 logical, allocatable, intent(inout) :: wall_facet_mask(:, :)
54 type(mesh_t), intent(in) :: msh
55 integer, intent(in) :: wall_zone_indices(:)
56 integer :: i
57 integer :: j
58 integer :: facet
59 integer :: el
60 integer :: zone_id
61
62 if (allocated(wall_facet_mask)) deallocate(wall_facet_mask)
63 allocate(wall_facet_mask(2 * msh%gdim, msh%nelv))
64 wall_facet_mask = .false.
65
66 do i = 1, size(wall_zone_indices)
67 zone_id = wall_zone_indices(i)
68 if (zone_id .lt. 1 .or. zone_id .gt. size(msh%labeled_zones)) then
69 call neko_error("lpt wall_zone_indices contains an invalid zone id")
70 end if
71
72 do j = 1, msh%labeled_zones(zone_id)%size
73 facet = msh%labeled_zones(zone_id)%facet_el(j)%x(1)
74 el = msh%labeled_zones(zone_id)%facet_el(j)%x(2)
75 wall_facet_mask(facet, el) = .true.
76 end do
77 end do
78 end subroutine lpt_init_wall_facet_mask
79
89 module subroutine lpt_handle_elastic_wall_collisions(this, x_old, y_old, &
90 z_old, u_old, v_old, w_old)
91 class(lpt_t), intent(inout) :: this
92 type(vector_t), intent(in) :: x_old, y_old, z_old
93 type(vector_t), intent(inout) :: u_old, v_old, w_old
94 type(matrix_t) :: rst_new
95 type(vector_t), pointer :: resx, resy, resz
96 integer, allocatable :: el_list(:)
97 integer, allocatable :: wall_facet_mask_i(:, :)
98 type(c_ptr) :: el_list_d
99 type(c_ptr) :: wall_facet_mask_d
100 integer :: i
101 integer :: n
102 integer :: ind(3)
103
104 associate(global_interp => this%global_interp, msh => this%msh, &
105 dm_xh => this%dm_Xh, coef => this%coef, &
106 wall_facet_mask => this%wall_facet_mask, &
107 x => this%particles%x, y => this%particles%y, &
108 z => this%particles%z, d => this%particles%d, &
109 u => this%particles%u, v => this%particles%v, &
110 w => this%particles%w, u_lag => this%particles%u_lag, &
111 v_lag => this%particles%v_lag, w_lag => this%particles%w_lag, &
112 u_laglag => this%particles%u_laglag, &
113 v_laglag => this%particles%v_laglag, &
114 w_laglag => this%particles%w_laglag, &
115 acc_x => this%particles%acc_x, acc_y => this%particles%acc_y, &
116 acc_z => this%particles%acc_z, &
117 acc_xlag => this%particles%acc_xlag, &
118 acc_ylag => this%particles%acc_ylag, &
119 acc_zlag => this%particles%acc_zlag, &
120 acc_xlaglag => this%particles%acc_xlaglag, &
121 acc_ylaglag => this%particles%acc_ylaglag, &
122 acc_zlaglag => this%particles%acc_zlaglag, lag_len => this%lag_len)
123
124 n = x%size()
125 if (n .eq. 0) return
126
127 el_list_d = c_null_ptr
128 wall_facet_mask_d = c_null_ptr
129
130 allocate(el_list(n))
131 call rst_new%init(3, n)
132 call neko_scratch_registry%request_vector(resx, ind(1), n, .false.)
133 call neko_scratch_registry%request_vector(resy, ind(2), n, .false.)
134 call neko_scratch_registry%request_vector(resz, ind(3), n, .false.)
135
136 if (neko_bcknd_device .eq. 1) then
137 call device_map(el_list, el_list_d, n)
138 end if
139
140 do i = 1, n
141 el_list(i) = global_interp%el_owner0_local(i)
142 end do
143 if (neko_bcknd_device .eq. 1) then
144 call device_memcpy(el_list, el_list_d, n, host_to_device, .true.)
145 end if
146
147 call global_interp%rst_finder%find(rst_new, x, y, z, el_list, n, &
148 resx, resy, resz)
149
150 if (neko_bcknd_device .eq. 1) then
151 allocate(wall_facet_mask_i(size(wall_facet_mask, 1), &
152 size(wall_facet_mask, 2)))
153 wall_facet_mask_i = merge(1, 0, wall_facet_mask)
154 call device_map(wall_facet_mask_i, wall_facet_mask_d, &
155 size(wall_facet_mask_i))
156 call device_memcpy(wall_facet_mask_i, wall_facet_mask_d, &
157 size(wall_facet_mask_i), host_to_device, .true.)
158
159 call lpt_handle_elastic_wall_collisions_device(msh, dm_xh, coef, &
160 wall_facet_mask_d, el_list_d, x_old, y_old, z_old, x, y, z, d, &
161 u, v, w, u_lag, v_lag, w_lag, u_laglag, v_laglag, w_laglag, &
162 acc_xlag, acc_ylag, acc_zlag, acc_xlaglag, acc_ylaglag, &
163 acc_zlaglag, u_old, v_old, w_old, acc_x, acc_y, acc_z, &
164 lag_len, n)
165
166 call lpt_wall_collision_sync_from_device(x, y, z, u, v, w, u_lag, &
167 v_lag, w_lag, u_laglag, v_laglag, w_laglag, acc_xlag, &
168 acc_ylag, acc_zlag, acc_xlaglag, acc_ylaglag, acc_zlaglag, &
169 u_old, v_old, w_old, acc_x, acc_y, acc_z)
170
171 call device_deassociate(wall_facet_mask_i)
172 call device_free(wall_facet_mask_d)
173 deallocate(wall_facet_mask_i)
174 else
175 call lpt_handle_elastic_wall_collisions_cpu(msh, dm_xh, coef, &
176 wall_facet_mask, el_list, x_old, y_old, z_old, x, y, z, d, u, &
177 v, w, u_lag, v_lag, w_lag, u_laglag, v_laglag, w_laglag, &
178 acc_xlag, acc_ylag, acc_zlag, acc_xlaglag, acc_ylaglag, &
179 acc_zlaglag, u_old, v_old, w_old, acc_x, acc_y, acc_z, &
180 lag_len, n)
181 end if
182
183 if (c_associated(el_list_d)) then
184 call device_deassociate(el_list)
185 call device_free(el_list_d)
186 end if
187
188 if (allocated(el_list)) deallocate(el_list)
189 call rst_new%free()
190 call neko_scratch_registry%relinquish(ind)
191
192 end associate
193 end subroutine lpt_handle_elastic_wall_collisions
194
196 subroutine lpt_wall_collision_sync_from_device(x, y, z, u, v, w, &
197 u_lag, v_lag, w_lag, u_laglag, v_laglag, w_laglag, acc_xlag, &
198 acc_ylag, acc_zlag, acc_xlaglag, acc_ylaglag, acc_zlaglag, u_old, &
199 v_old, w_old, acc_x, acc_y, acc_z)
200 type(vector_t), intent(inout) :: x, y, z
201 type(vector_t), intent(inout) :: u, v, w
202 type(vector_t), intent(inout) :: u_lag, v_lag, w_lag
203 type(vector_t), intent(inout) :: u_laglag, v_laglag, w_laglag
204 type(vector_t), intent(inout) :: acc_xlag, acc_ylag, acc_zlag
205 type(vector_t), intent(inout) :: acc_xlaglag, acc_ylaglag
206 type(vector_t), intent(inout) :: acc_zlaglag
207 type(vector_t), intent(inout) :: u_old, v_old, w_old
208 type(vector_t), intent(inout) :: acc_x, acc_y, acc_z
209
210 call x%copy_from(device_to_host, .false.)
211 call y%copy_from(device_to_host, .false.)
212 call z%copy_from(device_to_host, .false.)
213 call u%copy_from(device_to_host, .false.)
214 call v%copy_from(device_to_host, .false.)
215 call w%copy_from(device_to_host, .false.)
216 call u_lag%copy_from(device_to_host, .false.)
217 call v_lag%copy_from(device_to_host, .false.)
218 call w_lag%copy_from(device_to_host, .false.)
219 call u_laglag%copy_from(device_to_host, .false.)
220 call v_laglag%copy_from(device_to_host, .false.)
221 call w_laglag%copy_from(device_to_host, .false.)
222 call acc_xlag%copy_from(device_to_host, .false.)
223 call acc_ylag%copy_from(device_to_host, .false.)
224 call acc_zlag%copy_from(device_to_host, .false.)
225 call acc_xlaglag%copy_from(device_to_host, .false.)
226 call acc_ylaglag%copy_from(device_to_host, .false.)
227 call acc_zlaglag%copy_from(device_to_host, .false.)
228 call u_old%copy_from(device_to_host, .false.)
229 call v_old%copy_from(device_to_host, .false.)
230 call w_old%copy_from(device_to_host, .false.)
231 call acc_x%copy_from(device_to_host, .false.)
232 call acc_y%copy_from(device_to_host, .false.)
233 call acc_z%copy_from(device_to_host, .false.)
234 call device_sync()
235 end subroutine lpt_wall_collision_sync_from_device
236
237end submodule lpt_wall_collision
Deassociate a Fortran array from a device pointer.
Definition device.F90:107
Map a Fortran array to a device (allocate and associate)
Definition device.F90:83
Copy data between host and device (or device and device)
Definition device.F90:72
Synchronize a device or stream.
Definition device.F90:119
Device abstraction, common interface for various accelerators.
Definition device.F90:34
integer, parameter, public host_to_device
Definition device.F90:48
subroutine, public device_free(x_d)
Deallocate memory on the device.
Definition device.F90:243
integer, parameter, public device_to_host
Definition device.F90:48
CPU implementation for LPT wall-collision handling.
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.
Device dispatch for LPT elastic wall-collision handling.
subroutine, public lpt_handle_elastic_wall_collisions_device(msh, dm_xh, coef, wall_facet_mask_d, el_list_d, 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, strm)
Launch device kernel for elastic wall-collision reflection.
Implements lpt_t. (Lagrangian Particle Tracking)
Definition lpt.f90:34
Build configurations.
integer, parameter neko_bcknd_device
Defines a registry for storing and requesting temporary objects This can be used when you have a func...
type(scratch_registry_t), target, public neko_scratch_registry
Global scratch registry.