39 use iso_c_binding,
only : c_associated
55 use,
intrinsic :: iso_c_binding, only : c_ptr, c_null_ptr
56 use json_module,
only : json_file
73 type,
public,
abstract ::
bc_t
75 integer,
allocatable :: msk(:)
77 integer,
allocatable :: facet_node_msk(:)
79 integer,
allocatable :: facet(:)
83 type(
coef_t),
pointer :: coef => null()
85 type(
mesh_t),
pointer :: msh => null()
91 type(c_ptr) :: msk_d = c_null_ptr
93 type(c_ptr) :: facet_node_msk_d = c_null_ptr
95 type(c_ptr) :: facet_d = c_null_ptr
97 integer :: bc_type = -1
100 logical :: updated = .false.
102 character(len=:),
allocatable :: name
104 integer,
allocatable :: zone_indices(:)
137 generic :: restart => restart_scalar, restart_vector
156 class(
bc_t),
pointer :: ptr => null()
161 class(
bc_t),
allocatable :: obj
169 class(
bc_t),
intent(inout),
target :: this
170 type(
coef_t),
target,
intent(in) :: coef
171 type(json_file),
intent(inout) :: json
179 class(
bc_t),
intent(inout),
target :: this
187 class(
bc_t),
intent(inout),
target :: this
200 class(
bc_t),
intent(inout) :: this
201 integer,
intent(in) :: n
202 real(kind=
rp),
intent(inout),
dimension(n) :: x
204 logical,
intent(in),
optional :: strong
220 class(
bc_t),
intent(inout) :: this
221 integer,
intent(in) :: n
222 real(kind=
rp),
intent(inout),
dimension(n) :: x
223 real(kind=
rp),
intent(inout),
dimension(n) :: y
224 real(kind=
rp),
intent(inout),
dimension(n) :: z
226 logical,
intent(in),
optional :: strong
240 class(
bc_t),
intent(inout),
target :: this
241 type(c_ptr),
intent(inout) :: x_d
243 logical,
intent(in),
optional :: strong
244 type(c_ptr),
intent(inout) :: strm
259 class(
bc_t),
intent(inout),
target :: this
260 type(c_ptr),
intent(inout) :: x_d
261 type(c_ptr),
intent(inout) :: y_d
262 type(c_ptr),
intent(inout) :: z_d
264 logical,
intent(in),
optional :: strong
265 type(c_ptr),
intent(inout) :: strm
275 class(
bc_t),
intent(inout) :: this
282 class(
bc_t),
intent(inout) :: this
283 type(
field_t),
intent(in) :: u, v, w
290 class(
bc_t),
intent(inout) :: this
291 type(
coef_t),
target,
intent(in) :: coef
297 this%Xh => this%dof%Xh
298 this%msh => this%dof%msh
300 call this%marked_facet%init()
306 class(
bc_t),
intent(inout) :: this
308 call this%marked_facet%free()
315 if (
allocated(this%msk))
then
322 if (
allocated(this%facet_node_msk))
then
324 call device_unmap(this%facet_node_msk, this%facet_node_msk_d)
326 deallocate(this%facet_node_msk)
329 if (
allocated(this%facet))
then
333 deallocate(this%facet)
336 if (
allocated(this%name))
then
337 deallocate(this%name)
340 if (
allocated(this%zone_indices))
then
341 deallocate(this%zone_indices)
347 this%updated = .false.
360 class(
bc_t),
intent(inout) :: this
361 type(
field_t),
intent(inout) :: x
362 type(
field_t),
intent(inout) :: y
363 type(
field_t),
intent(inout) :: z
365 logical,
intent(in),
optional :: strong
366 type(c_ptr),
intent(inout),
optional :: strm
369 character(len=256) :: msg
375 if (y%size() .ne. n .or. z%size() .ne. n)
then
376 msg =
"Fields x, y, z must have the same size in " // &
377 "bc_list_apply_vector_field"
383 if (
present(strm))
then
389 call this%apply_vector_dev(x%x_d, y%x_d, z%x_d, time = time, &
390 strong = strong, strm = strm_)
392 call this%apply_vector(x%x, y%x, z%x, n, time = time, strong = strong)
404 class(
bc_t),
intent(inout) :: this
405 type(
field_t),
intent(inout) :: x
407 logical,
intent(in),
optional :: strong
408 type(c_ptr),
intent(inout),
optional :: strm
417 if (
present(strm))
then
423 call this%apply_scalar_dev(x%x_d, time = time, strong = strong, &
426 call this%apply_scalar(x%x, n, time = time)
435 class(
bc_t),
intent(inout) :: this
436 integer,
intent(in) :: facet
437 integer,
intent(in) :: el
441 call this%marked_facet%push(t)
448 class(
bc_t),
intent(inout) :: this
453 fp => facet_list%array()
454 do i = 1, facet_list%size()
455 call this%marked_facet%push(fp(i))
463 class(
bc_t),
intent(inout) :: this
466 do i = 1, bc_zone%size
467 call this%marked_facet%push(bc_zone%facet_el(i))
474 class(
bc_t),
intent(inout) :: this
475 integer,
intent(in) :: zone_index
476 integer,
allocatable :: tmp(:)
478 character(len=LOG_SIZE) :: log_buf
480 if (
allocated(this%zone_indices))
then
481 do i = 1,
size(this%zone_indices)
482 if (this%zone_indices(i) .eq. zone_index)
then
483 write(log_buf,
'(A,I0,A)')
'Zone index ', zone_index, &
484 ' already marked for this boundary condition'
490 allocate(tmp(
size(this%zone_indices) + 1))
491 tmp(1:
size(this%zone_indices)) = this%zone_indices
492 tmp(
size(tmp)) = zone_index
493 call move_alloc(tmp, this%zone_indices)
495 allocate(this%zone_indices(1))
496 this%zone_indices(1) = zone_index
499 call this%mark_zone(this%msh%labeled_zones(zone_index))
505 class(
bc_t),
intent(inout) :: this
506 integer,
intent(in) :: zone_indices(:)
509 do i = 1,
size(zone_indices)
510 call this%mark_labeled_zone(zone_indices(i))
519 class(
bc_t),
target,
intent(inout) :: this
523 integer :: facet_size, facet, el
524 integer :: i, j, k, l, msk_c
525 integer :: lx, ly, lz, n
526 character(len=LOG_SIZE) :: log_buf
534 n = facet_size * this%marked_facet%size()
535 allocate(this%facet_node_msk(0:n))
536 allocate(this%facet(0:n))
539 call device_map(this%facet_node_msk, this%facet_node_msk_d, n + 1)
540 call device_map(this%facet, this%facet_d, n + 1)
544 bfp => this%marked_facet%array()
550 do i = 1, this%marked_facet%size()
552 facet = bc_facet%x(1)
559 this%facet_node_msk(msk_c) = &
561 this%facet(msk_c) = 1
568 this%facet_node_msk(msk_c) = &
570 this%facet(msk_c) = 2
577 this%facet_node_msk(msk_c) = &
579 this%facet(msk_c) = 3
586 this%facet_node_msk(msk_c) = &
588 this%facet(msk_c) = 4
595 this%facet_node_msk(msk_c) = &
597 this%facet(msk_c) = 5
604 this%facet_node_msk(msk_c) = &
606 this%facet(msk_c) = 6
611 this%facet_node_msk(0) = msk_c
612 this%facet(0) = msk_c
616 call device_memcpy(this%facet_node_msk, this%facet_node_msk_d, n, &
623 call test_field%init(this%dof)
625 n = test_field%size()
626 test_field%x = 0.0_rp
628 do i = 1, this%facet_node_msk(0)
629 test_field%x(this%facet_node_msk(i),1,1,1) = 1.0
636 call this%coef%gs_h%op(test_field,
gs_op_add)
642 do i = 1, this%dof%size()
643 if (test_field%x(i,1,1,1) .gt. 0.5)
then
648 allocate(this%msk(0:msk_c))
650 do i = 1, this%dof%size()
651 if (test_field%x(i,1,1,1) .gt. 0.5)
then
657 call test_field%free()
668 if (.not.
allocated(this%name))
then
672 write(log_buf,
'(A,A)')
'BC assigned name : ', trim(this%name)
688 class(
bc_t),
intent(inout) :: this
689 character(len=*),
intent(in) :: file_name
694 call bdry_field%init(this%coef%dof,
'bdry')
698 bdry_field%x(k,1,1,1) = 1.0_rp
700 call dump_file%init(file_name)
701 call dump_file%write(bdry_field)
Apply the boundary condition to a scalar field on the device.
Apply the boundary condition to a scalar field.
Apply the boundary condition to a vector field on the device.
Apply the boundary condition to a vector field.
Finalize by building the mask and facet arrays.
Map a Fortran array to a device (allocate and associate)
Copy data between host and device (or device and device)
Unmap a Fortran array from a device (deassociate and free)
Defines a boundary condition.
subroutine bc_mark_zone(this, bc_zone)
Mark all facets from a zone.
subroutine bc_finalize_base(this)
Finalize the construction of the bc by populting the msk and facet arrays.
integer, parameter, public bc_mixed_constrains_tangent
subroutine bc_free_base(this)
Destructor for the base type, bc_t.
subroutine bc_mark_labeled_zones(this, zone_indices)
Mark all facets from labeled zones.
integer, parameter, public bc_mixed_constrains_normal
subroutine bc_restart_vector(this, u, v, w, ulag, vlag, wlag)
Default no-op restart hook for vector boundary conditions.
subroutine bc_mark_labeled_zone(this, zone_index)
Mark all facets from a labeled zone.
subroutine bc_restart_scalar(this, s, slag)
Default no-op restart hook for scalar boundary conditions. The lag series is optional because not eve...
subroutine bc_init_base(this, coef)
Constructor.
subroutine bc_apply_scalar_generic(this, x, time, strong, strm)
Apply the boundary condition to a scalar field. Dispatches to the CPU or the device version.
integer, parameter, public bc_dirichlet
Supported boundary condition types. The values are set in order of precedence for global resolution....
subroutine bc_apply_vector_generic(this, x, y, z, time, strong, strm)
Apply the boundary condition to a vector field. Dispatches to the CPU or the device version.
subroutine bc_debug_mask(this, file_name)
Write a field showing the mask of the bc.
subroutine bc_mark_facet(this, facet, el)
Mark facet on element el as part of the boundary condition.
subroutine bc_mark_facets(this, facet_list)
Mark all facets from a (facet, el) tuple list.
integer, parameter, public bc_neumann
subroutine, public device_cfill(a_d, c, n, strm)
Set all elements to a constant c .
Device abstraction, common interface for various accelerators.
integer, parameter, public host_to_device
integer, parameter, public device_to_host
type(c_ptr), bind(C), public glb_cmd_queue
Global command queue.
Defines a mapping of the degrees of freedom.
Defines a zone as a subset of facets in a mesh.
Contains the field_serties_t type.
Module for file I/O operations.
Defines Gather-scatter operations.
integer, parameter, public gs_op_add
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
Object for handling masks in Neko.
subroutine, public rzero(a, n)
Zero a real vector.
integer, parameter, public neko_msh_max_zlbls
Max num. zone labels.
integer, parameter, public neko_msh_max_zlbl_len
Max length of a zone label.
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Defines a function space.
Implements a dynamic stack ADT.
Module with things related to the simulation time.
character(len=100) function, dimension(:), allocatable, public split_string(string, delimiter)
Split a string based on delimiter (tokenizer) OBS: very hacky, this should really be improved,...
pure integer function, public linear_index(i, j, k, l, lx, ly, lz)
Compute the address of a (i,j,k,l) array with sizes (1:lx, 1:ly, 1:lz, :)
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.
Base type for a boundary condition.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Stores a series (sequence) of fields, logically connected to a base field, and arranged according to ...
A wrapper around a polymorphic generic_file_t that handles its init. This is essentially a factory fo...
Type for consistently handling masks in Neko. This type encapsulates the mask array and its associate...
The function space for the SEM solution fields.
Integer 2-tuple based stack.
A struct that contains all info about the time, expand as needed.