66 use json_module,
only : json_file
70 use,
intrinsic :: iso_c_binding, only : c_ptr, c_size_t
72 use mpi_f08,
only : mpi_allreduce, mpi_integer, mpi_sum
98 type(
vector_t) :: x_interface_dof, y_interface_dof, z_interface_dof
99 type(
vector_t) :: u_interface, v_interface, w_interface
101 integer :: iextm_order = 1
102 integer :: last_tstep = -1
106 integer :: n_int_tot = 0
107 logical :: find_interface = .false.
108 logical :: setup = .false.
109 logical :: log = .false.
114 morph_interface => null()
120 procedure, pass(this) :: init_from_components => &
127 procedure, pass(this) :: apply_scalar => &
130 procedure, pass(this) :: apply_vector => &
133 procedure, pass(this) :: apply_vector_dev => &
136 procedure, pass(this) :: apply_scalar_dev => &
160 type(
coef_t),
target,
intent(in) :: coef
161 type(json_file),
intent(inout) ::json
162 real(kind=
rp) :: tol, pad
171 if (this%iextm_order .lt. 1 .or. this%iextm_order .gt. 3)
then
172 call neko_error(
"The order of the IEXTm time scheme must be 1 to 3.")
176 call this%init_from_components(coef, tol, pad, log)
187 type(
coef_t),
intent(in) :: coef
188 real(kind=
rp),
intent(in),
optional :: tol, pad
189 logical,
intent(in),
optional :: log
192 call this%init_base(coef)
195 if (
present(tol))
then
196 if (tol .gt. 0.0_rp) this%interpolation_settings%tolerance = tol
198 if (
present(pad))
then
199 if (pad .gt. 0.0_rp) this%interpolation_settings%padding = pad
201 if (
present(log))
then
205 call this%bc_u%init_from_components(coef,
"u")
206 call this%bc_v%init_from_components(coef,
"v")
207 call this%bc_w%init_from_components(coef,
"w")
209 call this%field_list%init(3)
210 call this%field_list%assign_to_field(1, this%bc_u%field_bc)
211 call this%field_list%assign_to_field(2, this%bc_v%field_bc)
212 call this%field_list%assign_to_field(3, this%bc_w%field_bc)
215 call this%x_dof%init(this%dof%size(),
'x')
216 call this%y_dof%init(this%dof%size(),
'y')
217 call this%z_dof%init(this%dof%size(),
'z')
223 call device_copy(this%x_dof%x_d, this%dof%x_d, this%dof%size())
224 call device_copy(this%y_dof%x_d, this%dof%y_d, this%dof%size())
225 call device_copy(this%z_dof%x_d, this%dof%z_d, this%dof%size())
231 call copy(this%x_dof%x, this%dof%x, this%dof%size())
232 call copy(this%y_dof%x, this%dof%y, this%dof%size())
233 call copy(this%z_dof%x, this%dof%z, this%dof%size())
243 call this%bc_u%free()
244 call this%bc_v%free()
245 call this%bc_w%free()
247 call this%field_list%free()
248 call this%interface_dof%free()
249 call this%interface_field%free()
251 call this%x_dof%free()
252 call this%y_dof%free()
253 call this%z_dof%free()
255 call this%x_interface_dof%free()
256 call this%y_interface_dof%free()
257 call this%z_interface_dof%free()
258 call this%u_interface%free()
259 call this%v_interface%free()
260 call this%w_interface%free()
261 call this%u_interface_lag%free()
262 call this%v_interface_lag%free()
263 call this%w_interface_lag%free()
264 call this%interface_interpolator%free()
265 call this%interface_dof_mask%free()
266 call this%domain_element_mask%free()
267 call this%free_base()
280 integer,
intent(in) :: n
281 real(kind=
rp),
intent(inout),
dimension(n) :: x
283 logical,
intent(in),
optional :: strong
285 call neko_error(
"overset_interface_vector cannot apply scalar BCs.&
286 & Use overset_interface_vector::apply_vector instead!")
296 type(c_ptr),
intent(inout) :: x_d
298 logical,
intent(in),
optional :: strong
299 type(c_ptr),
intent(inout) :: strm
301 call neko_error(
"overset_interface_vector cannot apply scalar BCs.&
302 & Use overset_interface_vector::apply_vector instead!")
315 integer,
intent(in) :: n
316 real(kind=
rp),
intent(inout),
dimension(n) :: x
317 real(kind=
rp),
intent(inout),
dimension(n) :: y
318 real(kind=
rp),
intent(inout),
dimension(n) :: z
320 logical,
intent(in),
optional :: strong
323 if (
present(strong))
then
333 if (.not. this%updated)
then
334 call this%update(time)
335 this%updated = .true.
339 call masked_copy_0(x, this%bc_u%field_bc%x, this%msk, n, this%msk(0))
340 call masked_copy_0(y, this%bc_v%field_bc%x, this%msk, n, this%msk(0))
341 call masked_copy_0(z, this%bc_w%field_bc%x, this%msk, n, this%msk(0))
355 type(c_ptr),
intent(inout) :: x_d
356 type(c_ptr),
intent(inout) :: y_d
357 type(c_ptr),
intent(inout) :: z_d
359 logical,
intent(in),
optional :: strong
360 type(c_ptr),
intent(inout) :: strm
363 if (
present(strong))
then
370 if (.not. this%updated)
then
371 call this%update(time)
372 this%updated = .true.
375 if (this%msk(0) .gt. 0)
then
377 this%bc_u%msk_d, this%bc_u%dof%size(), this%msk(0), &
380 this%bc_v%msk_d, this%bc_v%dof%size(), this%msk(0), strm)
382 this%bc_w%msk_d, this%bc_w%dof%size(), this%msk(0), strm)
391 logical,
optional,
intent(in) :: only_facets
392 logical :: only_facets_
394 if (
present(only_facets))
then
395 only_facets_ = only_facets
397 only_facets_ = .false.
401 call this%finalize_base(only_facets_)
403 call this%bc_u%mark_facets(this%marked_facet)
404 call this%bc_v%mark_facets(this%marked_facet)
405 call this%bc_w%mark_facets(this%marked_facet)
407 call this%bc_u%finalize(only_facets_)
408 call this%bc_v%finalize(only_facets_)
409 call this%bc_w%finalize(only_facets_)
412 call this%build_masks_()
415 call this%x_interface_dof%init(this%interface_dof_mask%size(), &
417 call this%y_interface_dof%init(this%interface_dof_mask%size(), &
419 call this%z_interface_dof%init(this%interface_dof_mask%size(), &
421 call this%gather_interface_dofs_()
424 call this%setup_interpolator_()
427 call this%u_interface%init(this%interface_dof_mask%size(),
'u_interface')
428 call this%v_interface%init(this%interface_dof_mask%size(),
'v_interface')
429 call this%w_interface%init(this%interface_dof_mask%size(),
'w_interface')
432 call this%interface_dof%init(3)
433 call this%interface_dof%assign_to_vector(1, this%x_interface_dof)
434 call this%interface_dof%assign_to_vector(2, this%y_interface_dof)
435 call this%interface_dof%assign_to_vector(3, this%z_interface_dof)
437 call this%interface_field%init(3)
438 call this%interface_field%assign_to_vector(1, this%u_interface)
439 call this%interface_field%assign_to_vector(2, this%v_interface)
440 call this%interface_field%assign_to_vector(3, this%w_interface)
443 call this%u_interface_lag%init(this%u_interface, this%iextm_order)
444 call this%v_interface_lag%init(this%v_interface, this%iextm_order)
445 call this%w_interface_lag%init(this%w_interface, this%iextm_order)
447 call mpi_allreduce(this%u_interface%size(), this%n_int_tot, 1, mpi_integer, &
457 type(
field_t),
pointer :: u, v, w
459 integer :: nhist, ihist
460 real(kind=
rp) :: iextm_coeffs(4)
464 call this%morph_interface(this%interface_dof, this%interface_field, &
465 this%interface_dof_mask, time, this%name, &
475 if (this%find_interface)
then
478 call this%x_interface_dof%copy_from(
device_to_host, sync = .false.)
479 call this%y_interface_dof%copy_from(
device_to_host, sync = .false.)
480 call this%z_interface_dof%copy_from(
device_to_host, sync = .true.)
482 call this%interface_interpolator%find_points(this%x_interface_dof%x, &
483 this%y_interface_dof%x, this%z_interface_dof%x, &
484 this%x_interface_dof%size())
485 this%find_interface = .false.
495 call this%interface_interpolator%evaluate_masked(this%u_interface%x, &
496 u%x, this%domain_element_mask, .false.)
497 call this%interface_interpolator%evaluate_masked(this%v_interface%x, &
498 v%x, this%domain_element_mask, .false.)
499 call this%interface_interpolator%evaluate_masked(this%w_interface%x, &
500 w%x, this%domain_element_mask, .false.)
503 call this%log_interface_error_(u, v, w)
508 if (time%tstep .ne. this%last_tstep)
then
510 this%last_tstep = time%tstep
513 call this%u_interface_lag%update()
514 call this%v_interface_lag%update()
515 call this%w_interface_lag%update()
518 nhist = min(time%tstep, this%iextm_order)
519 call time_scheme%compute_coeffs(iextm_coeffs, time%dtlag, nhist)
522 call vector_cmult2(this%u_interface, this%u_interface_lag%lv(1), &
524 call vector_cmult2(this%v_interface, this%v_interface_lag%lv(1), &
526 call vector_cmult2(this%w_interface, this%w_interface_lag%lv(1), &
530 this%u_interface_lag%lv(ihist), iextm_coeffs(ihist))
532 this%v_interface_lag%lv(ihist), iextm_coeffs(ihist))
534 this%w_interface_lag%lv(ihist), iextm_coeffs(ihist))
543 this%interface_dof_mask, this%bc_u%dof%size())
546 this%interface_dof_mask, this%bc_v%dof%size())
549 this%interface_dof_mask, this%bc_w%dof%size())
557 type(
field_t),
pointer,
intent(in) :: u, v, w
558 real(kind=
rp) :: u_int_norm, v_int_norm, w_int_norm
561 logical :: clear_scratch = .false.
562 character(len=256) :: log_buf
586 write(log_buf,
'(A12,A3,A10,1x,A1,E15.7,A1,E15.7,A1,E15.7,A1)') &
587 'Interface BC',
' | ',
'L2 Error: ',
'(', &
588 u_int_norm,
',', v_int_norm,
',', w_int_norm,
')'
601 logical,
allocatable :: found(:)
602 integer :: i, j, k, e, new_size, nelems
603 integer :: lx, ly, lz
604 integer :: nonlinear_idx(4), linear_idx
608 call this%interface_dof_mask%init(this%msk(1:this%msk(0)), this%msk(0))
615 allocate(found(this%msh%nelv))
618 do i = 1, this%msk(0)
619 linear_idx = this%msk(i)
621 found(nonlinear_idx(4)) = .true.
626 do e = 1, this%msh%nelv
633 call stack%push(linear_idx)
640 call temp_mask%init(
stack%array(),
stack%size())
644 call this%domain_element_mask%invert_mask(temp_mask, this%dof%size())
646 call temp_mask%free()
656 this%dof%x(:,1,1,1), &
657 this%interface_dof_mask, &
660 this%dof%y(:,1,1,1), &
661 this%interface_dof_mask, &
664 this%dof%z(:,1,1,1), &
665 this%interface_dof_mask, &
668 call this%x_interface_dof%copy_from(
device_to_host, sync = .false.)
669 call this%y_interface_dof%copy_from(
device_to_host, sync = .false.)
670 call this%z_interface_dof%copy_from(
device_to_host, sync = .true.)
680 call this%interface_interpolator%init(this%dof, &
682 tol=this%interpolation_settings%tolerance, &
683 pad=this%interpolation_settings%padding, &
684 mask=this%domain_element_mask)
687 call this%interface_interpolator%find_points(this%x_interface_dof%x, &
688 this%y_interface_dof%x, &
689 this%z_interface_dof%x, &
690 this%x_interface_dof%size())
__inline__ __device__ void nonlinear_index(const int idx, const int lx, int *index)
Abstract interface defining a dirichlet condition on a list of fields.
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
User callback for overset-interface morphing and boundary-value updates.
Defines a boundary condition.
type(mpi_comm), public neko_global_comm
subroutine, public device_copy(a_d, b_d, n, strm)
Copy a vector .
subroutine, public device_masked_copy_0(a_d, b_d, mask_d, n, n_mask, strm)
Copy a masked vector .
Device abstraction, common interface for various accelerators.
integer, parameter, public host_to_device
integer, parameter, public device_to_host
Defines a dirichlet boundary condition.
Defines a mapping of the degrees of freedom.
Defines user dirichlet condition for a scalar field.
Implements global_interpolation given a dofmap.
Utilities for retrieving parameters from the case files.
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
Object for handling masks in Neko.
subroutine, public copy(a, b, n)
Copy a vector .
subroutine, public masked_copy_0(a, b, mask, n, n_mask)
Copy a masked vector .
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Defines overset interface vector boundary conditions.
subroutine overset_interface_vector_finalize(this, only_facets)
Finalize by building the mask arrays and propagating to underlying bcs.
subroutine overset_interface_vector_apply_scalar_dev(this, x_d, time, strong, strm)
No-op apply scalar (device).
subroutine overset_interface_vector_init_from_components(this, coef, tol, pad, log)
Constructor from components.
subroutine overset_interface_vector_free(this)
Destructor. Currently unused as is, all field_dirichlet attributes are freed in fluid_scheme_incompre...
subroutine overset_interface_vector_apply_vector_dev(this, x_d, y_d, z_d, time, strong, strm)
Apply the boundary condition to a vector field on the device.
subroutine overset_interface_vector_apply_scalar(this, x, n, time, strong)
No-op apply scalar.
subroutine overset_interface_vector_init(this, coef, json)
Constructor.
subroutine overset_interface_vector_apply_vector(this, x, y, z, n, time, strong)
Apply the boundary condition to a vector field.
Defines overset interface scalar boundary conditions.
subroutine overset_interface_update(this, time)
Update values at the overset interface.
subroutine gather_interface_dofs_(this)
Gather interface dofs.
subroutine log_interface_error_(this, s)
Log interface RMSE for the scalar field.
subroutine setup_interpolator_(this)
Set up the global interpolator.
subroutine build_masks_(this)
Build masks.
Defines a registry for storing solution fields.
type(registry_t), target, public neko_registry
Global field registry.
Defines a registry for storing and requesting temporary objects This can be used when you have a func...
type(scratch_registry_t), target, public neko_scratch_registry
Global scratch registry.
Implements a dynamic stack ADT.
Base class for time integration schemes.
Module with things related to the simulation time.
character(len=100) function, dimension(:), allocatable, public split_string(string, delimiter)
Split a string based on delimiter (tokenizer) OBS: very hacky, this should really be improved,...
pure integer function, public linear_index(i, j, k, l, lx, ly, lz)
Compute the address of a (i,j,k,l) array with sizes (1:lx, 1:ly, 1:lz, :)
subroutine, public vector_copy(a, b, n)
Copy a vector .
subroutine, public vector_masked_gather_copy(a, b, mask, n)
Gather a vector to reduced contigous array .
real(kind=rp) function, public vector_glsc2(a, b, n)
subroutine, public vector_add2s2(a, b, c1, n)
Vector addition with scalar multiplication (multiplication on second argument)
subroutine, public vector_masked_scatter_copy(a, b, mask, n)
Scatter a contiguous vector into an array .
subroutine, public vector_cmult2(a, b, c, n)
Multiplication by constant c .
Contains the vector_series_t type.
Base type for a boundary condition.
A list of allocatable `bc_t`. Follows the standard interface of lists.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Generic Dirichlet boundary condition on .
User defined dirichlet condition, for which the user can work with an entire field....
field_list_t, To be able to group fields together
Implements the settings helper data container for global interpolation.
Implements global interpolation for arbitrary points in the domain.
Explicit interface extrapolation scheme for overset grids.
Type for consistently handling masks in Neko. This type encapsulates the mask array and its associate...
Extension of the user defined dirichlet condition overset_interface
A struct that contains all info about the time, expand as needed.
vector_list_t, To be able to group vectors together
Stores a series (sequence) of vectors, logically connected to a base vector, and arranged according t...