43 use,
intrinsic :: iso_fortran_env
44 use,
intrinsic :: iso_c_binding
46 use json_module,
only : json_file
56 real(kind=
rp),
dimension(3) :: uinf = [0d0, 0d0, 0d0]
57 real(kind=
rp) :: delta
59 type(c_ptr),
private :: blax_d = c_null_ptr
60 type(c_ptr),
private :: blay_d = c_null_ptr
61 type(c_ptr),
private :: blaz_d = c_null_ptr
71 procedure, pass(this) :: init_from_components => &
85 class(
blasius_t),
intent(inout),
target :: this
86 type(
coef_t),
target,
intent(in) :: coef
87 type(json_file),
intent(inout) :: json
88 real(kind=
rp) :: delta
89 real(kind=
rp),
allocatable :: uinf(:)
90 character(len=:),
allocatable :: approximation
92 call this%init_base(coef)
95 call json_get(json,
'approximation', approximation)
98 if (
size(uinf) .ne. 3)
then
99 call neko_error(
"The uinf keyword for the blasius profile should be an &
103 call this%init_from_components(coef, delta, uinf, approximation)
114 class(
blasius_t),
intent(inout),
target :: this
115 type(
coef_t),
target,
intent(in) :: coef
116 real(kind=
rp) :: delta
117 real(kind=
rp) :: uinf(3)
118 character(len=*) :: approximation
120 call this%init_base(coef)
126 select case (trim(approximation))
140 call neko_error(
'Invalid Blasius approximation')
145 class(
blasius_t),
target,
intent(inout) :: this
147 call this%free_base()
150 if (c_associated(this%blax_d))
then
154 if (c_associated(this%blay_d))
then
158 if (c_associated(this%blaz_d))
then
167 integer,
intent(in) :: n
168 real(kind=
rp),
intent(inout),
dimension(n) :: x
170 logical,
intent(in),
optional :: strong
175 class(
blasius_t),
intent(inout),
target :: this
176 type(c_ptr),
intent(inout) :: x_d
178 logical,
intent(in),
optional :: strong
179 type(c_ptr),
intent(inout) :: strm
185 integer,
intent(in) :: n
186 real(kind=
rp),
intent(inout),
dimension(n) :: x
187 real(kind=
rp),
intent(inout),
dimension(n) :: y
188 real(kind=
rp),
intent(inout),
dimension(n) :: z
190 logical,
intent(in),
optional :: strong
191 integer :: i, m, k, idx(4), facet
194 if (
present(strong))
then
200 associate(xc => this%coef%dof%x, yc => this%coef%dof%y, &
201 zc => this%coef%dof%z, nx => this%coef%nx, ny => this%coef%ny, &
202 nz => this%coef%nz, lx => this%coef%Xh%lx)
203 m = this%facet_node_msk(0)
207 k = this%facet_node_msk(i)
208 facet = this%facet(i)
212 x(k) = this%bla(zc(idx(1), idx(2), idx(3), idx(4)), &
213 this%delta, this%uinf(1))
218 y(k) = this%bla(xc(idx(1), idx(2), idx(3), idx(4)), &
219 this%delta, this%uinf(2))
224 z(k) = this%bla(yc(idx(1), idx(2), idx(3), idx(4)), &
225 this%delta, this%uinf(3))
235 class(
blasius_t),
intent(inout),
target :: this
236 type(c_ptr),
intent(inout) :: x_d
237 type(c_ptr),
intent(inout) :: y_d
238 type(c_ptr),
intent(inout) :: z_d
239 type(time_state_t),
intent(in),
optional :: time
240 logical,
intent(in),
optional :: strong
241 integer :: i, m, k, idx(4), facet
242 integer(c_size_t) :: s
243 real(kind=rp),
allocatable :: bla_x(:), bla_y(:), bla_z(:)
245 type(c_ptr),
intent(inout) :: strm
247 if (
present(strong))
then
253 associate(xc => this%coef%dof%x, yc => this%coef%dof%y, &
254 zc => this%coef%dof%z, nx => this%coef%nx, ny => this%coef%ny, &
255 nz => this%coef%nz, lx => this%coef%Xh%lx , &
256 blax_d => this%blax_d, blay_d => this%blay_d, &
257 blaz_d => this%blaz_d)
259 m = this%facet_node_msk(0)
263 if (.not. c_associated(blax_d) .and. strong_ .and. m .gt. 0)
then
264 allocate(bla_x(m), bla_y(m), bla_z(m))
266 if (rp .eq. real32)
then
268 else if (rp .eq. real64)
then
272 call device_alloc(blax_d, s)
273 call device_alloc(blay_d, s)
274 call device_alloc(blaz_d, s)
277 k = this%facet_node_msk(i)
278 facet = this%facet(i)
282 bla_x(i) = this%bla(zc(idx(1), idx(2), idx(3), idx(4)), &
283 this%delta, this%uinf(1))
288 bla_y(i) = this%bla(xc(idx(1), idx(2), idx(3), idx(4)), &
289 this%delta, this%uinf(2))
294 bla_z(i) = this%bla(yc(idx(1), idx(2), idx(3), idx(4)), &
295 this%delta, this%uinf(3))
300 call device_memcpy(bla_x, blax_d, m, host_to_device, sync = .false.)
301 call device_memcpy(bla_y, blay_d, m, host_to_device, sync = .false.)
302 call device_memcpy(bla_z, blaz_d, m, host_to_device, sync = .true.)
304 deallocate(bla_x, bla_y, bla_z)
307 if (strong_ .and. this%msk(0) .gt. 0)
then
308 call device_inhom_dirichlet_apply_vector(this%msk_d, x_d, y_d, z_d, &
309 blax_d, blay_d, blaz_d, m, strm)
319 real(kind=rp),
intent(in) :: uinf(3)
320 real(kind=rp),
intent(in) :: delta
321 character(len=*) :: type
325 select case (trim(type))
327 this%bla => blasius_linear
329 this%bla => blasius_quadratic
331 this%bla => blasius_cubic
333 this%bla => blasius_quartic
335 this%bla => blasius_sin
337 this%bla => blasius_tanh
339 call neko_error(
'Invalid Blasius approximation')
345 class(
blasius_t),
target,
intent(inout) :: this
346 call this%finalize_base()
__inline__ __device__ void nonlinear_index(const int idx, const int lx, int *index)
Copy data between host and device (or device and device)
Abstract interface for computing a Blasius flow profile.
Retrieves a parameter by name or throws an error.
Defines a boundary condition.
integer, parameter, public bc_dirichlet
Supported boundary condition types. The values are set in order of precedence for global resolution....
Defines a Blasius profile dirichlet condition.
subroutine blasius_apply_scalar_dev(this, x_d, time, strong, strm)
No-op scalar apply (device version)
subroutine blasius_init(this, coef, json)
Constructor.
subroutine blasius_init_from_components(this, coef, delta, uinf, approximation)
Constructor from components.
subroutine blasius_apply_vector(this, x, y, z, n, time, strong)
Apply blasius conditions (vector valued)
subroutine blasius_apply_scalar(this, x, n, time, strong)
No-op scalar apply.
subroutine blasius_apply_vector_dev(this, x_d, y_d, z_d, time, strong, strm)
Apply blasius conditions (vector valued) (device version)
subroutine blasius_free(this)
subroutine blasius_finalize(this)
Finalize.
subroutine blasius_set_params(this, uinf, delta, type)
Set Blasius parameters.
Device backend wrappers for inhomogeneous Dirichlet boundary conditions.
subroutine device_inhom_dirichlet_apply_vector(msk, x, y, z, bla_x, bla_y, bla_z, m, strm)
Apply an inhomogeneous Dirichlet condition to a vector field on the device.
Device abstraction, common interface for various accelerators.
integer, parameter, public host_to_device
subroutine, public device_free(x_d)
Deallocate memory on the device.
subroutine, public device_alloc(x_d, s)
Allocate memory on the device.
real(kind=rp) function, public blasius_quadratic(y, delta, u)
Quadratic approximate Blasius Profile .
real(kind=rp) function, public blasius_quartic(y, delta, u)
Quartic approximate Blasius Profile .
real(kind=rp) function, public blasius_sin(y, delta, u)
Sinusoidal approximate Blasius Profile .
real(kind=rp) function, public blasius_cubic(y, delta, u)
Cubic approximate Blasius Profile .
real(kind=rp) function, public blasius_tanh(y, delta, u)
Hyperbolic tangent approximate Blasius Profile from O. Savas (2012) where is the 99 percent thickne...
real(kind=rp) function, public blasius_linear(y, delta, u)
Linear approximate Blasius profile .
Utilities for retrieving parameters from the case files.
integer, parameter, public rp
Global precision used in computations.
Module with things related to the simulation time.
Base type for a boundary condition.
Blasius profile for inlet (vector valued).
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
A struct that contains all info about the time, expand as needed.