Neko 1.99.2
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
bc_list.f90
Go to the documentation of this file.
1! Copyright (c) 2024-2025, 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!
34module bc_list
36 use num_types, only : rp
37 use field, only : field_t
39 use utils, only : neko_error
40 use, intrinsic :: iso_c_binding, only : c_ptr
41 use bc, only : bc_t, bc_ptr_t
42 use time_state, only : time_state_t
43 implicit none
44 private
45
48 type, public :: bc_list_t
49 ! The items of the list.
50 class(bc_ptr_t), allocatable, private :: items(:)
52 integer, private :: size_ = 0
55 integer, private :: capacity
56 contains
58 procedure, pass(this) :: init => bc_list_init
60 procedure, pass(this) :: free => bc_list_free
61
63 procedure, pass(this) :: append => bc_list_append
65 procedure, pass(this) :: get => bc_list_get
67 procedure, pass(this) :: get_by_name => bc_list_get_by_name
69 procedure, pass(this) :: get_by_zone_index => bc_list_get_by_zone_index
70
72 procedure, pass(this) :: is_empty => bc_list_is_empty
74 procedure, pass(this) :: strong => bc_list_strong
76 procedure :: size => bc_list_size
77
79 generic :: apply => apply_scalar, apply_vector, &
80 apply_scalar_device, apply_vector_device, &
81 apply_scalar_field, apply_vector_field
83 procedure, pass(this) :: apply_scalar => bc_list_apply_scalar_array
85 procedure, pass(this) :: apply_vector => bc_list_apply_vector_array
87 procedure, pass(this) :: apply_scalar_device => bc_list_apply_scalar_device
89 procedure, pass(this) :: apply_vector_device => bc_list_apply_vector_device
91 procedure, pass(this) :: apply_scalar_field => bc_list_apply_scalar_field
93 procedure, pass(this) :: apply_vector_field => bc_list_apply_vector_field
94 end type bc_list_t
95
96contains
97
100 subroutine bc_list_init(this, capacity)
101 class(bc_list_t), intent(inout), target :: this
102 integer, optional :: capacity
103 integer :: n
104
105 call this%free()
106
107 n = 1
108 if (present(capacity)) n = capacity
109
110 allocate(this%items(n))
111
112 this%size_ = 0
113 this%capacity = n
114
115 end subroutine bc_list_init
116
120 subroutine bc_list_free(this)
121 class(bc_list_t), intent(inout) :: this
122 integer :: i
123
124 if (allocated(this%items)) then
125 do i = 1, this%size_
126 this%items(i)%ptr => null()
127 end do
128
129 deallocate(this%items)
130 end if
131
132 this%size_ = 0
133 this%capacity = 0
134 end subroutine bc_list_free
135
139 subroutine bc_list_append(this, bc)
140 class(bc_list_t), intent(inout) :: this
141 class(bc_t), intent(inout), target :: bc
142 type(bc_ptr_t), allocatable :: tmp(:)
143
144 if (this%size_ .ge. this%capacity) then
145 this%capacity = this%capacity * 2
146 allocate(tmp(this%capacity))
147 tmp(1:this%size_) = this%items
148 call move_alloc(tmp, this%items)
149 end if
150
151 this%size_ = this%size_ + 1
152 this%items(this%size_)%ptr => bc
153
154 end subroutine bc_list_append
155
159 function bc_list_get(this, i) result(bc)
160 class(bc_list_t), intent(in) :: this
161 class(bc_t), pointer :: bc
162 integer, intent(in) :: i
163
164 if (i .lt. 1 .or. i .gt. this%size_) then
165 call neko_error("Index out of bounds in bc_list_get")
166 end if
167
168 bc => this%items(i)%ptr
169
170 end function bc_list_get
171
175 function bc_list_get_by_name(this, name) result(bc)
176 class(bc_list_t), intent(in) :: this
177 class(bc_t), pointer :: bc
178 character(len=*), intent(in) :: name
179 integer :: i
180
181 do i = 1, this%size_
182 if (this%items(i)%ptr%name .eq. trim(name)) then
183 bc => this%items(i)%ptr
184 return
185 end if
186 end do
187
188 ! If the function reaches this point, no item was found
189 call neko_error("Name not found in bc_list")
190
191 end function bc_list_get_by_name
192
196 function bc_list_get_by_zone_index(this, zone_index) result(bc)
197 class(bc_list_t), intent(in) :: this
198 class(bc_t), pointer :: bc
199 integer, intent(in) :: zone_index
200 integer :: i, j
201
202 do i = 1, this%size_
203 do j = 1, size(this%items(i)%ptr%zone_indices)
204 if (this%items(i)%ptr%zone_indices(j) == zone_index) then
205 bc => this%items(i)%ptr
206 return
207 end if
208 end do
209 end do
210
211 ! If the function reaches this point, no item was found
212 call neko_error("Zone index not found in bc_list")
213
214 end function bc_list_get_by_zone_index
215
223 subroutine bc_list_apply_scalar_array(this, x, n, time, strong, strm)
224 class(bc_list_t), intent(inout) :: this
225 integer, intent(in) :: n
226 real(kind=rp), intent(inout), dimension(n) :: x
227 type(time_state_t), intent(in), optional :: time
228 logical, intent(in), optional :: strong
229 type(c_ptr), intent(inout), optional :: strm
230 type(c_ptr) :: x_d
231 integer :: i
232
233 if (neko_bcknd_device .eq. 1) then
234
235 x_d = device_get_ptr(x)
236
237 call this%apply_scalar_device(x_d, time = time, &
238 strong = strong, strm = strm)
239 else
240 do i = 1, this%size_
241 call this%items(i)%ptr%apply_scalar(x, n, time = time, &
242 strong = strong)
243 end do
244 end if
245 end subroutine bc_list_apply_scalar_array
246
256 subroutine bc_list_apply_vector_array(this, x, y, z, n, time, strong, strm)
257 class(bc_list_t), intent(inout) :: this
258 integer, intent(in) :: n
259 real(kind=rp), intent(inout), dimension(n) :: x
260 real(kind=rp), intent(inout), dimension(n) :: y
261 real(kind=rp), intent(inout), dimension(n) :: z
262 type(time_state_t), intent(in), optional :: time
263 logical, intent(in), optional :: strong
264 type(c_ptr), intent(inout), optional :: strm
265 type(c_ptr) :: x_d
266 type(c_ptr) :: y_d
267 type(c_ptr) :: z_d
268 integer :: i
269
270 if (neko_bcknd_device .eq. 1) then
271
272 x_d = device_get_ptr(x)
273 y_d = device_get_ptr(y)
274 z_d = device_get_ptr(z)
275
276 call this%apply_vector_device(x_d, y_d, z_d, time = time, &
277 strong = strong, strm = strm)
278 else
279 do i = 1, this%size_
280 call this%items(i)%ptr%apply_vector(x, y, z, n, time = time, &
281 strong = strong)
282 end do
283 end if
284
285 end subroutine bc_list_apply_vector_array
286
293 subroutine bc_list_apply_scalar_device(this, x_d, time, strong, strm)
294 class(bc_list_t), intent(inout) :: this
295 type(c_ptr), intent(inout) :: x_d
296 type(time_state_t), intent(in), optional :: time
297 logical, intent(in), optional :: strong
298 type(c_ptr), intent(inout), optional :: strm
299 type(c_ptr) :: strm_
300 integer :: i
301
302 if (present(strm)) then
303 strm_ = strm
304 else
305 strm_ = glb_cmd_queue
306 end if
307
308 do i = 1, this%size_
309 call this%items(i)%ptr%apply_scalar_dev(x_d, time = time, &
310 strong = strong, strm = strm_)
311 end do
312
313 end subroutine bc_list_apply_scalar_device
314
323 subroutine bc_list_apply_vector_device(this, x_d, y_d, z_d, time, strong, &
324 strm)
325 class(bc_list_t), intent(inout) :: this
326 type(c_ptr), intent(inout) :: x_d
327 type(c_ptr), intent(inout) :: y_d
328 type(c_ptr), intent(inout) :: z_d
329 type(time_state_t), intent(in), optional :: time
330 logical, intent(in), optional :: strong
331 type(c_ptr), intent(inout), optional :: strm
332 type(c_ptr) :: strm_
333 integer :: i
334
335 if (present(strm)) then
336 strm_ = strm
337 else
338 strm_ = glb_cmd_queue
339 end if
340
341 do i = 1, this%size_
342 call this%items(i)%ptr%apply_vector_dev(x_d, y_d, z_d, time = time, &
343 strong = strong, strm = strm_)
344 end do
345
346 end subroutine bc_list_apply_vector_device
347
354 subroutine bc_list_apply_scalar_field(this, x, time, strong, strm)
355 class(bc_list_t), intent(inout) :: this
356 type(field_t), intent(inout) :: x
357 type(time_state_t), intent(in), optional :: time
358 logical, intent(in), optional :: strong
359 type(c_ptr), intent(inout), optional :: strm
360 integer :: i
361
362 do i = 1, this%size_
363 call this%items(i)%ptr%apply_scalar_generic(x, time = time, &
364 strong = strong, strm = strm)
365 end do
366
367 end subroutine bc_list_apply_scalar_field
368
377 subroutine bc_list_apply_vector_field(this, x, y, z, time, strong, strm)
378 class(bc_list_t), intent(inout) :: this
379 type(field_t), intent(inout) :: x
380 type(field_t), intent(inout) :: y
381 type(field_t), intent(inout) :: z
382 type(time_state_t), intent(in), optional :: time
383 logical, intent(in), optional :: strong
384 type(c_ptr), intent(inout), optional :: strm
385 integer :: i
386
387 do i = 1, this%size_
388 call this%items(i)%ptr%apply_vector_generic(x, y, z, time = time, &
389 strong = strong, strm = strm)
390 end do
391
392 end subroutine bc_list_apply_vector_field
393
395 pure function bc_list_strong(this, i) result(strong)
396 class(bc_list_t), intent(in), target :: this
397 integer, intent(in) :: i
398 logical :: strong
399
400 strong = this%items(i)%ptr%strong
401 end function bc_list_strong
402
404 function bc_list_is_empty(this) result(is_empty)
405 class(bc_list_t), intent(in), target :: this
406 logical :: is_empty
407 integer :: i
408
409 is_empty = .true.
410 do i = 1, this%size_
411
412 if (.not. allocated(this%items(i)%ptr%msk)) then
413 call neko_error("bc not finalized, error in bc_list%is_empty")
414 end if
415
416 if (this%items(i)%ptr%msk(0) > 0) is_empty = .false.
417
418 end do
419 end function bc_list_is_empty
420
422 pure function bc_list_size(this) result(size)
423 class(bc_list_t), intent(in), target :: this
424 integer :: size
425
426 size = this%size_
427 end function bc_list_size
428
429end module bc_list
Return the device pointer for an associated Fortran array.
Definition device.F90:101
Defines a list of bc_t.
Definition bc_list.f90:34
pure logical function bc_list_strong(this, i)
Return whether the bc is strong or not.
Definition bc_list.f90:396
subroutine bc_list_apply_vector_array(this, x, y, z, n, time, strong, strm)
Apply a list of boundary conditions to a vector field.
Definition bc_list.f90:257
subroutine bc_list_apply_vector_device(this, x_d, y_d, z_d, time, strong, strm)
Apply a list of boundary conditions to a vector field on the device.
Definition bc_list.f90:325
class(bc_t) function, pointer bc_list_get(this, i)
Get the item at the given index.
Definition bc_list.f90:160
subroutine bc_list_apply_scalar_array(this, x, n, time, strong, strm)
Apply a list of boundary conditions to a scalar field.
Definition bc_list.f90:224
subroutine bc_list_apply_scalar_device(this, x_d, time, strong, strm)
Apply a list of boundary conditions to a scalar field on the device.
Definition bc_list.f90:294
pure integer function bc_list_size(this)
Return the number of items in the list.
Definition bc_list.f90:423
subroutine bc_list_append(this, bc)
Append a condition to the end of the list.
Definition bc_list.f90:140
subroutine bc_list_init(this, capacity)
Constructor.
Definition bc_list.f90:101
class(bc_t) function, pointer bc_list_get_by_name(this, name)
Get the item from a given name.
Definition bc_list.f90:176
subroutine bc_list_apply_vector_field(this, x, y, z, time, strong, strm)
Apply a list of boundary conditions to a vector field.
Definition bc_list.f90:378
subroutine bc_list_free(this)
Destructor.
Definition bc_list.f90:121
class(bc_t) function, pointer bc_list_get_by_zone_index(this, zone_index)
Get the item from zone_index.
Definition bc_list.f90:197
subroutine bc_list_apply_scalar_field(this, x, time, strong, strm)
Apply a list of boundary conditions to a scalar field.
Definition bc_list.f90:355
logical function bc_list_is_empty(this)
Return whether the list is empty.
Definition bc_list.f90:405
Defines a boundary condition.
Definition bc.f90:34
Device abstraction, common interface for various accelerators.
Definition device.F90:34
type(c_ptr), bind(C), public glb_cmd_queue
Global command queue.
Definition device.F90:51
Defines a field.
Definition field.f90:34
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Module with things related to the simulation time.
Utilities.
Definition utils.f90:35
Pointer to a `bc_t`.
Definition bc.f90:133
Base type for a boundary condition.
Definition bc.f90:62
A list of allocatable `bc_t`. Follows the standard interface of lists.
Definition bc_list.f90:48
A struct that contains all info about the time, expand as needed.