38 use json_module,
only : json_file
50 use,
intrinsic :: iso_c_binding, only : c_ptr, c_null_ptr, c_associated
60 type(
coef_t),
pointer :: coef => null()
70 character(len=:),
allocatable :: scheme_name
72 integer,
pointer :: msk(:) => null()
73 type(c_ptr) :: msk_d = c_null_ptr
75 integer,
pointer :: facet(:) => null()
89 integer,
allocatable :: ind_r(:)
90 type(c_ptr) :: ind_r_d = c_null_ptr
92 integer,
allocatable :: ind_s(:)
93 type(c_ptr) :: ind_s_d = c_null_ptr
95 integer,
allocatable :: ind_t(:)
96 type(c_ptr) :: ind_t_d = c_null_ptr
98 integer,
allocatable :: ind_e(:)
99 type(c_ptr) :: ind_e_d = c_null_ptr
103 integer :: h_index = 0
105 integer :: n_nodes = 0
146 real(kind=
rp),
intent(in) :: t
147 integer,
intent(in) :: tstep
164 character(len=*),
intent(in) :: scheme_name
165 type(
coef_t),
intent(in) :: coef
166 integer,
intent(in) :: msk(:)
167 integer,
intent(in) :: facet(:)
168 integer,
intent(in) :: h_index
169 type(json_file),
intent(inout) :: json
181 type(
coef_t),
intent(in) :: coef
182 type(json_file),
intent(inout) :: json
193 integer,
intent(in) :: msk(:)
194 integer,
intent(in) :: facet(:)
216 module subroutine wall_model_factory(object, scheme_name, coef, msk, &
218 class(wall_model_t),
allocatable,
intent(inout) :: object
219 character(len=*),
intent(in) :: scheme_name
220 type(
coef_t),
intent(in) :: coef
221 integer,
intent(in) :: msk(:)
222 integer,
intent(in) :: facet(:)
223 type(json_file),
intent(inout) :: json
224 end subroutine wall_model_factory
231 module subroutine wall_model_allocator(object, type_name)
232 class(wall_model_t),
allocatable,
intent(inout) :: object
233 character(len=:),
allocatable,
intent(in) :: type_name
234 end subroutine wall_model_allocator
245 subroutine wall_model_allocate(obj)
247 class(wall_model_t),
allocatable,
intent(inout) :: obj
248 end subroutine wall_model_allocate
253 module subroutine register_wall_model(type_name, allocator)
254 character(len=*),
intent(in) :: type_name
255 procedure(wall_model_allocate),
pointer,
intent(in) :: allocator
256 end subroutine register_wall_model
262 character(len=20) :: type_name
263 procedure(wall_model_allocate),
pointer,
nopass :: allocator
264 end type allocator_entry
267 type(allocator_entry),
allocatable :: wall_model_registry(:)
270 integer :: wall_model_registry_size = 0
272 public :: wall_model_factory, wall_model_allocator, register_wall_model, &
282 subroutine wall_model_init_base(this, scheme_name, coef, msk, facet, index)
283 class(wall_model_t),
intent(inout) :: this
284 type(
coef_t),
target,
intent(in) :: coef
285 integer,
target,
intent(in) :: msk(0:)
286 integer,
target,
intent(in) :: facet(0:)
287 character(len=*) :: scheme_name
288 integer,
intent(in) :: index
295 this%scheme_name = trim(scheme_name)
296 this%mu =>
neko_registry%get_field_by_name(this%scheme_name //
"_mu")
297 this%rho =>
neko_registry%get_field_by_name(this%scheme_name // &
301 ignore_existing = .true.)
304 call this%finalize_base(msk, facet)
305 end subroutine wall_model_init_base
311 subroutine wall_model_partial_init_base(this, coef, json)
312 class(wall_model_t),
intent(inout) :: this
313 type(
coef_t),
target,
intent(in) :: coef
314 type(json_file),
intent(inout) :: json
316 call this%free_base()
320 call json_get(json,
"h_index", this%h_index)
321 call json_get(json,
"scheme_name", this%scheme_name)
323 this%mu =>
neko_registry%get_field_by_name(this%scheme_name //
"_mu")
324 this%rho =>
neko_registry%get_field_by_name(this%scheme_name // &
328 ignore_existing = .true.)
330 end subroutine wall_model_partial_init_base
332 subroutine wall_model_finalize_base(this, msk, facet)
333 class(wall_model_t),
intent(inout) :: this
334 integer,
target,
intent(in) :: msk(0:)
335 integer,
target,
intent(in) :: facet(:)
337 this%msk(0:msk(0)) => msk
339 this%facet(0:msk(0)) => facet
341 call this%tau_x%init(this%msk(0))
342 call this%tau_y%init(this%msk(0))
343 call this%tau_z%init(this%msk(0))
345 allocate(this%ind_r(this%msk(0)))
346 allocate(this%ind_s(this%msk(0)))
347 allocate(this%ind_t(this%msk(0)))
348 allocate(this%ind_e(this%msk(0)))
350 call this%h%init(this%msk(0))
351 call this%n_x%init(this%msk(0))
352 call this%n_y%init(this%msk(0))
353 call this%n_z%init(this%msk(0))
355 call this%find_points()
359 call device_map(this%ind_r, this%ind_r_d, this%n_nodes)
360 call device_map(this%ind_s, this%ind_s_d, this%n_nodes)
361 call device_map(this%ind_t, this%ind_t_d, this%n_nodes)
362 call device_map(this%ind_e, this%ind_e_d, this%n_nodes)
373 end subroutine wall_model_finalize_base
376 subroutine wall_model_free_base(this)
377 class(wall_model_t),
intent(inout) :: this
382 nullify(this%tau_field)
386 call this%tau_x%free()
387 call this%tau_y%free()
388 call this%tau_z%free()
390 if (
allocated(this%ind_r))
then
391 deallocate(this%ind_r)
393 if (
allocated(this%ind_s))
then
394 deallocate(this%ind_s)
396 if (
allocated(this%ind_t))
then
397 deallocate(this%ind_t)
399 if (
allocated(this%ind_e))
then
400 deallocate(this%ind_e)
403 if (c_associated(this%msk_d))
then
406 if (c_associated(this%ind_r_d))
then
409 if (c_associated(this%ind_s_d))
then
412 if (c_associated(this%ind_t_d))
then
415 if (c_associated(this%ind_e_d))
then
419 if (
allocated(this%scheme_name))
then
420 deallocate(this%scheme_name)
430 end subroutine wall_model_free_base
433 subroutine wall_model_find_points(this)
434 class(wall_model_t),
intent(inout) :: this
435 integer :: n_nodes, fid, idx(4), i, linear
436 real(kind=
rp) :: normal(3), p(3), x, y, z, xw, yw, zw, magp
437 real(kind=
rp) :: hmin, hmax
438 type(
field_t),
pointer :: h_field
440 character(len=LOG_SIZE),
allocatable :: log_msg
442 n_nodes = this%msk(0)
443 this%n_nodes = n_nodes
445 call neko_registry%add_field(this%coef%dof,
"sampling_height", &
446 ignore_existing=.true.)
448 h_field =>
neko_registry%get_field_by_name(
"sampling_height")
455 normal = this%coef%get_normal(idx(1), idx(2), idx(3), idx(4), fid)
457 this%n_x%x(i) = normal(1)
458 this%n_y%x(i) = normal(2)
459 this%n_z%x(i) = normal(3)
466 this%ind_r(i) = idx(1) + this%h_index
467 this%ind_s(i) = idx(2)
468 this%ind_t(i) = idx(3)
470 this%ind_r(i) = idx(1) - this%h_index
471 this%ind_s(i) = idx(2)
472 this%ind_t(i) = idx(3)
474 this%ind_r(i) = idx(1)
475 this%ind_s(i) = idx(2) + this%h_index
476 this%ind_t(i) = idx(3)
478 this%ind_r(i) = idx(1)
479 this%ind_s(i) = idx(2) - this%h_index
480 this%ind_t(i) = idx(3)
482 this%ind_r(i) = idx(1)
483 this%ind_s(i) = idx(2)
484 this%ind_t(i) = idx(3) + this%h_index
486 this%ind_r(i) = idx(1)
487 this%ind_s(i) = idx(2)
488 this%ind_t(i) = idx(3) - this%h_index
490 call neko_error(
"The face index is not correct ")
492 this%ind_e(i) = idx(4)
495 xw = this%dof%x(idx(1), idx(2), idx(3), idx(4))
496 yw = this%dof%y(idx(1), idx(2), idx(3), idx(4))
497 zw = this%dof%z(idx(1), idx(2), idx(3), idx(4))
500 x = this%dof%x(this%ind_r(i), this%ind_s(i), this%ind_t(i), &
502 y = this%dof%y(this%ind_r(i), this%ind_s(i), this%ind_t(i), &
504 z = this%dof%z(this%ind_r(i), this%ind_s(i), this%ind_t(i), &
513 magp = sqrt(p(1)**2 + p(2)**2 + p(3)**2)
516 this%h%x(i) = p(1)*normal(1) + p(2)*normal(2) + p(3)*normal(3)
518 h_field%x(linear,1,1,1) = this%h%x(i)
522 if ((this%h%x(i) - magp) / magp > 0.1)
then
523 write(log_msg,*)
"Significant misalignment between wall normal and"
525 write(log_msg,*)
"sampling point direction at wall node", xw, yw, zw
549 call h_file%init(
"sampling_height.fld")
550 call h_file%write(h_field)
551 end subroutine wall_model_find_points
554 class(wall_model_t),
intent(inout) :: this
556 real(kind=
rp) :: magtau
564 this%tau_field%x_d, &
568 magtau = sqrt(this%tau_x%x(i)**2 + &
569 this%tau_y%x(i)**2 + &
571 this%tau_field%x(this%msk(i),1,1,1) = magtau
__inline__ __device__ void nonlinear_index(const int idx, const int lx, int *index)
__global__ void wall_model_compute_mag_field(const T *__restrict__ tau_x_d, const T *__restrict__ tau_y_d, const T *__restrict__ tau_z_d, T *__restrict__ tau_field_d, const int *__restrict__ msk_d, const int m)
Return the device pointer for an associated Fortran array.
Map a Fortran array to a device (allocate and associate)
Copy data between host and device (or device and device)
Retrieves a parameter by name or throws an error.
Compute wall shear stress.
Finilzation of partial construction, similar to bc_t
Partial constructor from JSON, meant to work as the first stage of initialization before the finalize...
integer, public pe_rank
MPI rank.
Device abstraction, common interface for various accelerators.
integer, parameter, public host_to_device
subroutine, public device_free(x_d)
Deallocate memory on the device.
Defines a mapping of the degrees of freedom.
Module for file I/O operations.
Utilities for retrieving parameters from the case files.
integer, parameter, public neko_log_debug
Debug log level.
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
real(kind=rp) function, public glmax(a, n)
Max of a vector of length n.
real(kind=rp) function, public glmin(a, n)
Min of a vector of length n.
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Defines a registry for storing solution fields.
type(registry_t), target, public neko_registry
Global field registry.
Implements the device kernel for the wall_model_t type.
subroutine, public wall_model_compute_mag_field_device(tau_x_d, tau_y_d, tau_z_d, tau_field_d, msk_d, m)
Compute the wall shear stress's magnitude on device.
subroutine wall_model_finalize_base(this, msk, facet)
subroutine wall_model_init_base(this, scheme_name, coef, msk, facet, index)
Constructor for the wall_model_t (base) class.
subroutine wall_model_partial_init_base(this, coef, json)
Partial initialization based on JSON, prior to knowing the mask and facets.
subroutine wall_model_find_points(this)
Find sampling points based on the requested index.
subroutine wall_model_free_base(this)
Destructor for the wall_model_t (base) class.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
A wrapper around a polymorphic generic_file_t that handles its init. This is essentially a factory fo...
Base abstract type for wall-stress models for wall-modelled LES.