37 use,
intrinsic :: iso_c_binding, only : c_ptr, c_null_ptr
40 use json_module,
only : json_file
68 real(kind=
rp),
allocatable,
private :: init_flux_(:)
71 logical :: uniform_0 = .false.
83 generic :: init_from_components => &
91 generic :: set_flux => set_flux_scalar, set_flux_array
104 class(
neumann_t),
intent(inout),
target :: this
105 type(
coef_t),
target,
intent(in) :: coef
106 type(json_file),
intent(inout) :: json
107 real(kind=
rp) :: flux
110 call this%init_base(coef)
111 this%strong = .false.
114 call json%get(
"flux", this%init_flux_, found)
117 if (.not. found)
then
119 allocate(this%init_flux_(1))
120 this%init_flux_(1) = flux
123 if ((
size(this%init_flux_) .ne. 1) &
124 .and. (
size(this%init_flux_) .ne. 3))
then
125 call neko_error(
"Neumann BC flux must be a scalar or a 3-component" // &
129 allocate(this%flux(
size(this%init_flux_)))
136 class(
neumann_t),
intent(inout),
target :: this
137 type(
coef_t),
intent(in) :: coef
138 real(kind=
rp),
intent(in) :: flux(3)
140 call this%init_base(coef)
141 this%init_flux_ = flux
143 if ((
size(this%init_flux_) .ne. 3))
then
144 call neko_error(
"Neumann BC flux must be a scalar or a 3-component" // &
147 allocate(this%flux(
size(this%init_flux_)))
154 class(
neumann_t),
intent(inout),
target :: this
155 type(
coef_t),
intent(in) :: coef
156 real(kind=
rp),
intent(in) :: flux
158 call this%init_base(coef)
159 allocate(this%init_flux_(1))
160 this%init_flux_(1) = flux
161 allocate(this%flux(
size(this%init_flux_)))
168 integer,
intent(in) :: n
169 real(kind=
rp),
intent(inout),
dimension(n) :: x
171 logical,
intent(in),
optional :: strong
172 integer :: i, m, k, facet
177 if (
present(strong))
then
184 if (.not. strong_)
then
188 facet = this%facet(i)
194 this%flux(1)%x(i) * &
195 this%coef%area(idx(2), idx(3), facet, idx(4))
198 this%flux(1)%x(i) * &
199 this%coef%area(idx(1), idx(3), facet, idx(4))
202 this%flux(1)%x(i) * &
203 this%coef%area(idx(1), idx(2), facet, idx(4))
214 integer,
intent(in) :: n
215 real(kind=
rp),
intent(inout),
dimension(n) :: x
216 real(kind=
rp),
intent(inout),
dimension(n) :: y
217 real(kind=
rp),
intent(inout),
dimension(n) :: z
219 logical,
intent(in),
optional :: strong
220 integer :: i, m, k, facet
225 if (
present(strong))
then
232 if (.not. strong_)
then
236 facet = this%facet(i)
242 this%flux(1)%x(i) * &
243 this%coef%area(idx(2), idx(3), facet, idx(4))
245 this%flux(2)%x(i) * &
246 this%coef%area(idx(2), idx(3), facet, idx(4))
248 this%flux(3)%x(i) * &
249 this%coef%area(idx(2), idx(3), facet, idx(4))
252 this%flux(1)%x(i) * &
253 this%coef%area(idx(1), idx(3), facet, idx(4))
255 this%flux(2)%x(i) * &
256 this%coef%area(idx(1), idx(3), facet, idx(4))
258 this%flux(3)%x(i) * &
259 this%coef%area(idx(1), idx(3), facet, idx(4))
262 this%flux(1)%x(i) * &
263 this%coef%area(idx(1), idx(2), facet, idx(4))
265 this%flux(2)%x(i) * &
266 this%coef%area(idx(1), idx(2), facet, idx(4))
268 this%flux(3)%x(i) * &
269 this%coef%area(idx(1), idx(2), facet, idx(4))
279 class(
neumann_t),
intent(inout),
target :: this
280 type(c_ptr),
intent(inout) :: x_d
282 logical,
intent(in),
optional :: strong
283 type(c_ptr),
intent(inout) :: strm
286 if (
present(strong))
then
292 if (.not. this%uniform_0 .and. this%msk(0) .gt. 0 .and. &
295 this%flux(1)%x_d, this%coef%area_d, this%coef%Xh%lx, &
296 size(this%msk), strm)
304 class(
neumann_t),
intent(inout),
target :: this
305 type(c_ptr),
intent(inout) :: x_d
306 type(c_ptr),
intent(inout) :: y_d
307 type(c_ptr),
intent(inout) :: z_d
309 logical,
intent(in),
optional :: strong
310 type(c_ptr),
intent(inout) :: strm
313 if (
present(strong))
then
319 if (.not. this%uniform_0 .and. this%msk(0) .gt. 0 .and. &
323 this%flux(1)%x_d, this%flux(2)%x_d, this%flux(3)%x_d, &
324 this%coef%area_d, this%coef%Xh%lx, &
325 size(this%msk), strm)
332 class(
neumann_t),
target,
intent(inout) :: this
334 call this%free_base()
340 class(
neumann_t),
target,
intent(inout) :: this
341 logical,
optional,
intent(in) :: only_facets
344 if (
present(only_facets))
then
345 if (.not. only_facets)
then
346 call neko_error(
"For neumann_t, only_facets has to be true.")
350 call this%finalize_base(.true.)
353 do i = 1,
size(this%init_flux_)
354 call this%flux(i)%init(this%msk(0))
355 this%flux(i) = this%init_flux_(i)
358 this%uniform_0 = .true.
361 this%uniform_0 =
abscmp(this%init_flux_(i), 0.0_rp) .and. this%uniform_0
370 real(kind=
rp),
intent(in) :: flux
371 integer,
intent(in) :: comp
373 if (
size(this%flux) .lt. comp)
then
374 call neko_error(
"Component index out of bounds in " // &
375 "neumann_set_flux_scalar")
378 this%flux(comp) = flux
381 this%uniform_0 =
abscmp(flux, 0.0_rp) .and. this%uniform_0
391 integer,
intent(in) :: comp
394 if (
size(this%flux) .lt. comp)
then
395 call neko_error(
"Component index out of bounds in " // &
396 "neuman_set_flux_array")
399 this%flux(comp) = flux
402 this%uniform_0 = .false.
__inline__ __device__ void nonlinear_index(const int idx, const int lx, int *index)
Copy data between host and device (or device and device)
Defines a boundary condition.
subroutine, public device_copy(a_d, b_d, n, strm)
Copy a vector .
subroutine, public device_cfill(a_d, c, n, strm)
Set all elements to a constant c .
subroutine, public device_neumann_apply_scalar(msk, facet, x, flux, area, lx, m, strm)
subroutine, public device_neumann_apply_vector(msk, facet, x, y, z, flux_x, flux_y, flux_z, area, lx, m, strm)
Device abstraction, common interface for various accelerators.
integer, parameter, public device_to_host
Utilities for retrieving parameters from the case files.
subroutine, public cfill(a, c, n)
Set all elements to a constant c .
subroutine, public copy(a, b, n)
Copy a vector .
integer, parameter neko_bcknd_device
Defines a Neumann boundary condition.
subroutine neumann_init_from_components_array(this, coef, flux)
Constructor from components, using a flux array for vector components.
subroutine neumann_set_flux_scalar(this, flux, comp)
Set the flux using a scalar.
subroutine neumann_set_flux_array(this, flux, comp)
Set a flux component using a vector_t of values.
subroutine neumann_apply_vector_dev(this, x_d, y_d, z_d, time, strong, strm)
Boundary condition apply for a generic Neumann condition to vectors x, y and z (device version)
subroutine neumann_finalize(this, only_facets)
Finalize by setting the flux.
subroutine neumann_init_from_components_single(this, coef, flux)
Constructor from components, using an signle flux.
subroutine neumann_init(this, coef, json)
Constructor.
subroutine neumann_apply_vector(this, x, y, z, n, time, strong)
Boundary condition apply for a generic Neumann condition to vectors x, y and z.
subroutine neumann_apply_scalar(this, x, n, time, strong)
Boundary condition apply for a generic Neumann condition to a vector x.
subroutine neumann_apply_scalar_dev(this, x_d, time, strong, strm)
Boundary condition apply for a generic Neumann condition to a vector x (device version)
subroutine neumann_free(this)
Destructor.
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 Neumann boundary condition. Sets the flux of the field to the chosen values.
A struct that contains all info about the time, expand as needed.