44 use json_module,
only : json_file
48 use,
intrinsic :: iso_c_binding, only : c_ptr, c_null_ptr
60 real(kind=
rp),
allocatable :: gx(:)
61 real(kind=
rp),
allocatable :: gy(:)
62 real(kind=
rp),
allocatable :: gz(:)
64 real(kind=
rp),
allocatable :: xm(:)
65 real(kind=
rp),
allocatable :: ym(:)
66 real(kind=
rp),
allocatable :: zm(:)
68 type(c_ptr) :: gx_d = c_null_ptr
69 type(c_ptr) :: gy_d = c_null_ptr
70 type(c_ptr) :: gz_d = c_null_ptr
75 procedure, pass(this) :: init_from_components => &
82 procedure, pass(this) :: apply_scalar => &
85 procedure, pass(this) :: apply_vector => &
88 procedure, pass(this) :: apply_scalar_dev => &
91 procedure, pass(this) :: apply_vector_dev => &
104 type(
coef_t),
target,
intent(in) :: coef
105 type(json_file),
intent(inout) :: json
106 character(len=NEKO_EXPR_LEN),
allocatable :: str(:)
108 call json_get(json,
"value", str, filler =
'')
110 if (
size(str) .ne. 3)
then
111 call neko_error(
"An expression velocity boundary condition takes " // &
112 "exactly three expressions, one per component")
115 call this%init_from_components(coef, str(1), str(2), str(3))
116 if (
allocated(str))
deallocate(str)
128 type(
coef_t),
target,
intent(in) :: coef
129 character(len=*),
intent(in) :: str_x
130 character(len=*),
intent(in) :: str_y
131 character(len=*),
intent(in) :: str_z
134 call this%init_base(coef)
136 if (len_trim(str_x) .eq. 0 .or. len_trim(str_y) .eq. 0 .or. &
137 len_trim(str_z) .eq. 0)
then
138 call neko_error(
"An expression boundary condition needs a non-empty " &
139 //
"expression for every component")
142 call this%expr(1)%init(str_x)
143 call this%expr(2)%init(str_y)
144 call this%expr(3)%init(str_z)
153 call this%free_base()
156 call this%expr(i)%free()
159 if (
allocated(this%gx))
then
166 if (
allocated(this%gy))
then
173 if (
allocated(this%gz))
then
180 if (
allocated(this%xm))
deallocate(this%xm)
181 if (
allocated(this%ym))
deallocate(this%ym)
182 if (
allocated(this%zm))
deallocate(this%zm)
192 logical,
optional,
intent(in) :: only_facets
193 logical :: only_facets_
196 if (
present(only_facets))
then
197 only_facets_ = only_facets
199 only_facets_ = .false.
202 call this%finalize_base(only_facets_)
207 allocate(this%xm(m), this%ym(m), this%zm(m))
208 allocate(this%gx(m), this%gy(m), this%gz(m))
220 if (.not. this%expr(1)%time_dependent)
then
221 call this%expr(1)%eval(this%gx, m, this%xm, this%ym, this%zm)
223 "boundary condition")
225 if (.not. this%expr(2)%time_dependent)
then
226 call this%expr(2)%eval(this%gy, m, this%xm, this%ym, this%zm)
228 "boundary condition")
230 if (.not. this%expr(3)%time_dependent)
then
231 call this%expr(3)%eval(this%gz, m, this%xm, this%ym, this%zm)
233 "boundary condition")
254 type(c_ptr),
intent(inout),
optional :: strm
257 if (.not. (this%expr(1)%time_dependent .or. &
258 this%expr(2)%time_dependent .or. &
259 this%expr(3)%time_dependent))
return
260 if (this%updated)
return
262 if (.not.
present(time))
then
263 call neko_error(
"A boundary condition expression depends on time, " // &
264 "but the solver did not provide a time state")
269 if (this%expr(1)%time_dependent)
then
270 call this%expr(1)%eval(this%gx, m, this%xm, this%ym, this%zm, &
273 "boundary condition")
275 if (this%expr(2)%time_dependent)
then
276 call this%expr(2)%eval(this%gy, m, this%xm, this%ym, this%zm, &
279 "boundary condition")
281 if (this%expr(3)%time_dependent)
then
282 call this%expr(3)%eval(this%gz, m, this%xm, this%ym, this%zm, &
285 "boundary condition")
293 sync = .false., strm = strm)
295 sync = .false., strm = strm)
297 sync = .true., strm = strm)
300 this%updated = .true.
311 integer,
intent(in) :: n
312 real(kind=
rp),
intent(inout),
dimension(n) :: x
314 logical,
intent(in),
optional :: strong
325 type(c_ptr),
intent(inout) :: x_d
327 logical,
intent(in),
optional :: strong
328 type(c_ptr),
intent(inout) :: strm
341 integer,
intent(in) :: n
342 real(kind=
rp),
intent(inout),
dimension(n) :: x
343 real(kind=
rp),
intent(inout),
dimension(n) :: y
344 real(kind=
rp),
intent(inout),
dimension(n) :: z
346 logical,
intent(in),
optional :: strong
350 if (
present(strong))
then
357 if (.not. strong_ .or. m .eq. 0)
return
365 call this%update(time)
387 z_d, time, strong, strm)
389 type(c_ptr),
intent(inout) :: x_d
390 type(c_ptr),
intent(inout) :: y_d
391 type(c_ptr),
intent(inout) :: z_d
393 logical,
intent(in),
optional :: strong
394 type(c_ptr),
intent(inout) :: strm
398 if (
present(strong))
then
405 if (.not. strong_ .or. m .eq. 0)
return
407 call this%update(time, strm)
410 this%gx_d, this%gy_d, this%gz_d, m, strm)
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)
Retrieves a parameter by name or throws an error.
Defines a boundary condition.
subroutine device_inhom_dirichlet_apply_vector(msk, x, y, z, bla_x, bla_y, bla_z, m, strm)
Device abstraction, common interface for various accelerators.
integer, parameter, public host_to_device
Defines a vector valued Dirichlet condition prescribed by mathematical expressions.
subroutine expression_dirichlet_vector_update(this, time, strm)
Bring the values up to date with the current time.
subroutine expression_dirichlet_vector_apply_vector_dev(this, x_d, y_d, z_d, time, strong, strm)
Apply the condition to a vector field (device version).
subroutine expression_dirichlet_vector_apply_scalar(this, x, n, time, strong)
(No-op) Apply scalar.
subroutine expression_dirichlet_vector_apply_vector(this, x, y, z, n, time, strong)
Apply the condition to a vector field.
subroutine expression_dirichlet_vector_init(this, coef, json)
Constructor from JSON.
subroutine expression_dirichlet_vector_free(this)
Destructor.
subroutine expression_dirichlet_vector_finalize(this, only_facets)
Finalize.
subroutine expression_dirichlet_vector_apply_scalar_dev(this, x_d, time, strong, strm)
(No-op) Apply scalar (device version).
subroutine expression_dirichlet_vector_init_from_components(this, coef, str_x, str_y, str_z)
Constructor from components.
Defines a Dirichlet condition prescribed by a mathematical expression.
subroutine, public expression_mask_coords(bc, xm, ym, zm)
Tabulate the coordinates of the points of the mask of a boundary condition.
Evaluation of mathematical expressions given as strings in the case file.
subroutine, public expression_check_finite(str, res, n, usage)
Abort if an expression did not evaluate to a finite value everywhere.
integer, parameter, public neko_expr_len
Maximum length of an expression string read from the case file.
Utilities for retrieving parameters from the case files.
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Module with things related to the simulation time.
Base type for a boundary condition.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
A compiled mathematical expression.
Vector valued Dirichlet condition, with one mathematical expression per component,...
A struct that contains all info about the time, expand as needed.