38 use json_module,
only : json_file
49 use,
intrinsic :: iso_c_binding, only : c_ptr, c_null_ptr
59 type(
coef_t),
pointer :: coef => null()
69 character(len=:),
allocatable :: scheme_name
71 integer,
pointer :: msk(:) => null()
72 type(c_ptr) :: msk_d = c_null_ptr
74 integer,
pointer :: facet(:) => null()
90 integer :: n_nodes = 0
92 type(
field_t),
pointer :: tau_field => null()
121 procedure, pass(this) :: validate_single_sample => &
132 real(kind=
rp),
intent(in) :: t
133 integer,
intent(in) :: tstep
149 character(len=*),
intent(in) :: scheme_name
150 type(
coef_t),
intent(in) :: coef
151 integer,
intent(in) :: msk(:)
152 integer,
intent(in) :: facet(:)
153 type(json_file),
intent(inout) :: json
166 type(
coef_t),
intent(in) :: coef
167 character(len=*),
intent(in) :: scheme_name
168 type(json_file),
intent(inout) :: json
179 integer,
intent(in) :: msk(:)
180 integer,
intent(in) :: facet(:)
181 character(len=*),
optional,
intent(in) :: bc_name
182 type(
user_t),
target,
optional,
intent(in) :: user
203 module subroutine wall_model_factory(object, scheme_name, coef, msk, &
205 class(wall_model_t),
allocatable,
intent(inout) :: object
206 character(len=*),
intent(in) :: scheme_name
207 type(
coef_t),
intent(in) :: coef
208 integer,
intent(in) :: msk(:)
209 integer,
intent(in) :: facet(:)
210 type(json_file),
intent(inout) :: json
211 end subroutine wall_model_factory
218 module subroutine wall_model_allocator(object, type_name)
219 class(wall_model_t),
allocatable,
intent(inout) :: object
220 character(len=:),
allocatable,
intent(in) :: type_name
221 end subroutine wall_model_allocator
232 subroutine wall_model_allocate(obj)
234 class(wall_model_t),
allocatable,
intent(inout) :: obj
235 end subroutine wall_model_allocate
240 module subroutine register_wall_model(type_name, allocator)
241 character(len=*),
intent(in) :: type_name
242 procedure(wall_model_allocate),
pointer,
intent(in) :: allocator
243 end subroutine register_wall_model
249 character(len=20) :: type_name
250 procedure(wall_model_allocate),
pointer,
nopass :: allocator
251 end type allocator_entry
254 type(allocator_entry),
allocatable :: wall_model_registry(:)
257 integer :: wall_model_registry_size = 0
259 public :: wall_model_factory, wall_model_allocator, register_wall_model, &
269 subroutine wall_model_init_base(this, scheme_name, coef, msk, facet, sampler)
270 class(wall_model_t),
intent(inout) :: this
271 type(
coef_t),
target,
intent(in) :: coef
272 integer,
target,
intent(in) :: msk(0:)
273 integer,
target,
intent(in) :: facet(0:)
274 character(len=*) :: scheme_name
281 if (.not.
allocated(sampler))
then
282 call neko_error(
'Wall model sampler has not been initialized')
284 call move_alloc(sampler, this%sampler)
285 this%scheme_name = trim(scheme_name)
286 this%mu =>
neko_registry%get_field_by_name(this%scheme_name //
"_mu")
287 this%rho =>
neko_registry%get_field_by_name(this%scheme_name // &
291 ignore_existing = .true.)
294 call this%finalize_base(msk, facet)
295 end subroutine wall_model_init_base
301 subroutine wall_model_partial_init_base(this, coef, scheme_name, json)
302 class(wall_model_t),
intent(inout) :: this
303 type(
coef_t),
target,
intent(in) :: coef
304 character(len=*),
intent(in) :: scheme_name
305 type(json_file),
intent(inout) :: json
307 call this%free_base()
312 this%scheme_name = trim(scheme_name)
314 this%mu =>
neko_registry%get_field_by_name(this%scheme_name //
"_mu")
315 this%rho =>
neko_registry%get_field_by_name(this%scheme_name // &
319 ignore_existing = .true.)
321 end subroutine wall_model_partial_init_base
323 subroutine wall_model_finalize_base(this, msk, facet, bc_name, user)
324 class(wall_model_t),
intent(inout) :: this
325 integer,
target,
intent(in) :: msk(0:)
326 integer,
target,
intent(in) :: facet(:)
327 character(len=*),
optional,
intent(in) :: bc_name
328 type(
user_t),
target,
optional,
intent(in) :: user
330 this%msk(0:msk(0)) => msk
332 this%facet(0:msk(0)) => facet
334 call this%tau_x%init(this%msk(0))
335 call this%tau_y%init(this%msk(0))
336 call this%tau_z%init(this%msk(0))
338 call this%n_x%init(this%msk(0))
339 call this%n_y%init(this%msk(0))
340 call this%n_z%init(this%msk(0))
342 call this%setup_geometry()
343 if (.not.
allocated(this%sampler))
then
344 call neko_error(
'Wall model sampler has not been initialized')
346 if (
present(bc_name))
then
347 if (
present(
user))
then
348 call this%sampler%finalize(this%coef, this%msk, this%facet, &
349 this%n_x, this%n_y, this%n_z, bc_name,
user)
351 call this%sampler%finalize(this%coef, this%msk, this%facet, &
352 this%n_x, this%n_y, this%n_z, bc_name)
355 if (this%sampler%user_values)
then
356 call neko_error(
'Wall model user sampler has no boundary context')
358 call this%sampler%finalize(this%coef, this%msk, this%facet, &
359 this%n_x, this%n_y, this%n_z)
362 end subroutine wall_model_finalize_base
365 subroutine wall_model_free_base(this)
366 class(wall_model_t),
intent(inout) :: this
371 nullify(this%tau_field)
374 this%msk_d = c_null_ptr
376 call this%tau_x%free()
377 call this%tau_y%free()
378 call this%tau_z%free()
380 if (
allocated(this%sampler))
then
381 call this%sampler%free()
382 deallocate(this%sampler)
385 if (
allocated(this%scheme_name))
then
386 deallocate(this%scheme_name)
394 end subroutine wall_model_free_base
397 subroutine wall_model_setup_geometry(this)
398 class(wall_model_t),
intent(inout) :: this
399 integer :: n_nodes, fid, idx(4), i, linear
400 real(kind=
rp) :: normal(3)
402 call this%coef%require_facets(
'wall_model')
404 n_nodes = this%msk(0)
405 this%n_nodes = n_nodes
412 normal = this%coef%get_normal(idx(1), idx(2), idx(3), idx(4), fid)
414 this%n_x%x(i) = normal(1)
415 this%n_y%x(i) = normal(2)
416 this%n_z%x(i) = normal(3)
429 end subroutine wall_model_setup_geometry
431 subroutine wall_model_validate_single_sample(this)
432 class(wall_model_t),
intent(inout) :: this
434 if (this%sampler%n_samples /= 1)
then
435 call neko_error(
'This wall model requires exactly one sample per node')
437 end subroutine wall_model_validate_single_sample
440 class(wall_model_t),
intent(inout) :: this
442 real(kind=
rp) :: magtau
450 this%tau_field%x_d, &
454 magtau = sqrt(this%tau_x%x(i)**2 + &
455 this%tau_y%x(i)**2 + &
457 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.
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...
Device abstraction, common interface for various accelerators.
integer, parameter, public host_to_device
Defines a mapping of the degrees of freedom.
Utilities for retrieving parameters from the case files.
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.
Interfaces for user interaction with NEKO.
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_partial_init_base(this, coef, scheme_name, json)
Partial initialization based on JSON, prior to knowing the mask and facets.
subroutine wall_model_init_base(this, scheme_name, coef, msk, facet, sampler)
Constructor for the wall_model_t (base) class.
subroutine wall_model_setup_geometry(this)
Build wall-node normals independently of the sampling strategy.
subroutine wall_model_free_base(this)
Destructor for the wall_model_t (base) class.
subroutine wall_model_validate_single_sample(this)
subroutine wall_model_finalize_base(this, msk, facet, bc_name, user)
Factory for wall-model samplers.
subroutine, public wall_sampler_factory(object, json)
Wall sampler factory.
Defines the abstract interface for wall-model field samplers.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
A type collecting all the overridable user routines and flag to suppress type injection from custom m...
Base abstract type for wall-stress models for wall-modelled LES.
Base type for sampling solution fields at points associated with wall nodes. Samples belonging to one...