58 use json_module,
only : json_file
64 use mpi_f08,
only : mpi_allreduce, mpi_integer, mpi_sum
65 use,
intrinsic :: iso_c_binding, only : c_ptr
77 character(len=:),
allocatable :: field_name
85 type(
vector_t) :: x_interface_dof, y_interface_dof, z_interface_dof
89 integer :: iextm_order = 1
91 real(kind=
rp) :: relaxation = 1.0_rp
92 integer :: last_tstep = -1
96 integer :: n_int_tot = 0
97 logical :: find_interface = .false.
98 logical :: setup = .false.
99 logical :: log = .false.
101 logical :: restart_pending = .false.
106 morph_interface => null()
112 procedure, pass(this) :: init_from_components => &
123 procedure, pass(this) :: apply_vector_dev => &
126 procedure, pass(this) :: apply_scalar_dev => &
165 interface_mask, time, bc_name, &
170 type(
mask_t),
intent(in) :: interface_mask
172 character(len=*),
intent(in) :: bc_name
173 logical,
intent(inout) :: find_interface
186 type(
coef_t),
target,
intent(in) :: coef
187 type(json_file),
intent(inout) :: json
188 character(len=:),
allocatable :: field_name
189 real(kind=
rp) :: tol, pad, relaxation
192 call json_get(json,
"field_name", field_name)
196 if (this%iextm_order .lt. 1 .or. this%iextm_order .gt. 3)
then
197 call neko_error(
"The order of the IEXTm time scheme must be 1 to 3.")
200 if (relaxation .le. 0.0_rp .or. relaxation .gt. 1.0_rp)
then
201 call neko_error(
"The overset relaxation factor must be in (0, 1].")
205 call this%init_from_components(coef, field_name, tol, pad, log, relaxation)
206 if (
allocated(field_name))
deallocate(field_name)
214 tol, pad, log, relaxation)
216 type(
coef_t),
intent(in) :: coef
217 character(len=*),
intent(in) :: field_name
218 real(kind=
rp),
intent(in),
optional :: tol, pad, relaxation
219 logical,
intent(in),
optional :: log
220 character(len=256) :: log_buf
222 call this%init_base(coef)
224 this%relaxation = 1.0_rp
226 this%restart_pending = .false.
228 if (
present(tol))
then
229 if (tol .gt. 0.0_rp)
then
230 this%interpolation_settings%tolerance = tol
234 if (
present(pad))
then
235 if (pad .gt. 0.0_rp)
then
236 this%interpolation_settings%padding = pad
240 if (
present(log))
then
244 if (
present(relaxation))
then
245 if (relaxation .le. 0.0_rp .or. relaxation .gt. 1.0_rp)
then
246 call neko_error(
"The overset relaxation factor must be in (0, 1].")
248 this%relaxation = relaxation
251 this%field_name = field_name
252 write (log_buf,
'(A,A)')
"Coupling overset interface for: ", &
253 trim(this%field_name)
256 call this%bc_s%init_from_components(coef, this%field_name)
257 call this%field_list%init(1)
258 call this%field_list%assign_to_field(1, this%bc_s%field_bc)
260 call this%x_dof%init(this%dof%size(),
'x')
261 call this%y_dof%init(this%dof%size(),
'y')
262 call this%z_dof%init(this%dof%size(),
'z')
265 call device_copy(this%x_dof%x_d, this%dof%x%x_d, this%dof%size())
266 call device_copy(this%y_dof%x_d, this%dof%y%x_d, this%dof%size())
267 call device_copy(this%z_dof%x_d, this%dof%z%x_d, this%dof%size())
273 call copy(this%x_dof%x, this%dof%x%x, this%dof%size())
274 call copy(this%y_dof%x, this%dof%y%x, this%dof%size())
275 call copy(this%z_dof%x, this%dof%z%x, this%dof%size())
284 call this%bc_s%free()
285 call this%field_list%free()
286 call this%interface_dof%free()
287 call this%interface_field%free()
289 call this%x_dof%free()
290 call this%y_dof%free()
291 call this%z_dof%free()
293 call this%x_interface_dof%free()
294 call this%y_interface_dof%free()
295 call this%z_interface_dof%free()
296 call this%s_interface%free()
297 call this%s_interface_lag%free()
299 if (
allocated(this%field_name))
then
300 deallocate(this%field_name)
303 call this%interface_interpolator%free()
305 call this%interface_dof_mask%free()
306 call this%domain_element_mask%free()
308 call this%free_base()
309 this%restart_pending = .false.
321 integer :: i, n_previous
323 call this%s_interface_lag%reset()
326 if (
present(slag))
then
327 n_previous = min(this%iextm_order - 1, slag%size())
328 do i = n_previous, 1, -1
330 slag%lf(i)%x(:,1,1,1), this%interface_dof_mask, &
331 slag%lf(i)%dof%size())
332 call this%s_interface_lag%update()
337 s%x(:,1,1,1), this%interface_dof_mask, s%dof%size())
339 this%restart_pending = .true.
348 integer,
intent(in) :: n
349 real(kind=
rp),
intent(inout),
dimension(n) :: x
351 logical,
intent(in),
optional :: strong
354 if (
present(strong))
then
362 if (.not. this%updated)
then
363 call this%update(time)
364 this%updated = .true.
368 call masked_copy_0(x, this%bc_s%field_bc%x, this%msk, n, this%msk(0))
379 type(c_ptr),
intent(inout) :: x_d
381 logical,
intent(in),
optional :: strong
382 type(c_ptr),
intent(inout) :: strm
385 if (
present(strong))
then
393 if (.not. this%updated)
then
394 call this%update(time)
395 this%updated = .true.
399 if (this%msk(0) .gt. 0)
then
401 this%bc_s%msk_d, this%bc_s%dof%size(), this%msk(0), strm)
410 integer,
intent(in) :: n
411 real(kind=
rp),
intent(inout),
dimension(n) :: x
412 real(kind=
rp),
intent(inout),
dimension(n) :: y
413 real(kind=
rp),
intent(inout),
dimension(n) :: z
415 logical,
intent(in),
optional :: strong
417 call neko_error(
"overset_interface cannot apply vector BCs.&
418 & Use overset_interface_vector instead!")
426 type(c_ptr),
intent(inout) :: x_d
427 type(c_ptr),
intent(inout) :: y_d
428 type(c_ptr),
intent(inout) :: z_d
430 logical,
intent(in),
optional :: strong
431 type(c_ptr),
intent(inout) :: strm
433 call neko_error(
"overset_interface cannot apply vector BCs.&
434 & Use overset_interface_vector instead!")
442 call this%finalize_base()
444 call this%bc_s%mark_facets(this%marked_facet)
445 call this%bc_s%finalize()
447 call this%build_masks_()
449 call this%x_interface_dof%init(this%interface_dof_mask%size(), &
451 call this%y_interface_dof%init(this%interface_dof_mask%size(), &
453 call this%z_interface_dof%init(this%interface_dof_mask%size(), &
455 call this%gather_interface_dofs_()
457 call this%setup_interpolator_()
459 call this%s_interface%init(this%interface_dof_mask%size(),
's_interface')
461 call this%interface_dof%init(3)
462 call this%interface_dof%assign_to_vector(1, this%x_interface_dof)
463 call this%interface_dof%assign_to_vector(2, this%y_interface_dof)
464 call this%interface_dof%assign_to_vector(3, this%z_interface_dof)
466 call this%interface_field%init(1)
467 call this%interface_field%assign_to_vector(1, this%s_interface)
469 call this%s_interface_lag%init(this%s_interface, this%iextm_order)
471 call mpi_allreduce(this%s_interface%size(), this%n_int_tot, 1, mpi_integer, &
482 integer :: nhist, ihist
483 real(kind=
rp) :: iextm_coeffs(4)
487 call this%morph_interface(this%interface_dof, this%interface_field, &
488 this%interface_dof_mask, time, this%name, &
492 if (this%find_interface)
then
495 call this%x_interface_dof%copy_from(
device_to_host, sync = .false.)
496 call this%y_interface_dof%copy_from(
device_to_host, sync = .false.)
497 call this%z_interface_dof%copy_from(
device_to_host, sync = .true.)
499 call this%interface_interpolator%find_points(this%x_interface_dof%x, &
500 this%y_interface_dof%x, this%z_interface_dof%x, &
501 this%x_interface_dof%size())
502 this%find_interface = .false.
510 if (.not. this%restart_pending)
then
511 call this%interface_interpolator%evaluate_masked(this%s_interface%x, &
512 s%x, this%domain_element_mask, .false.)
515 call this%log_interface_error_(s)
519 new_tstep = time%tstep .ne. this%last_tstep
522 this%last_tstep = time%tstep
524 call this%s_interface_lag%update()
526 nhist = min(this%s_interface_lag%filled_size(), this%iextm_order)
528 real(time%dtlag, kind=
rp), nhist)
530 call vector_cmult2(this%s_interface, this%s_interface_lag%lv(1), &
533 call vector_add2s2(this%s_interface, this%s_interface_lag%lv(ihist), &
537 this%restart_pending = .false.
542 if (.not. new_tstep)
call this%relax_interface_value_()
545 this%s_interface, this%interface_dof_mask, this%bc_s%dof%size())
561 logical :: clear_scratch = .false.
564 if (this%relaxation .ge. 1.0_rp)
return
568 this%s_interface%size(), clear_scratch)
570 this%interface_dof_mask, this%bc_s%dof%size())
575 1.0_rp - this%relaxation)
585 type(
field_t),
pointer,
intent(in) :: s
586 real(kind=
rp) :: s_int_norm
589 logical :: clear_scratch = .false.
590 character(len=256) :: log_buf
600 write(log_buf,
'(A12,A3,A10,1x,E15.7)')
'Interface BC',
' | ', &
601 'L2 Error: ', s_int_norm
614 logical,
allocatable :: found(:)
615 integer :: i, j, k, e, nelems
616 integer :: lx, ly, lz
617 integer :: nonlinear_idx(4), linear_idx
620 call this%interface_dof_mask%init(this%msk(1:this%msk(0)), this%msk(0))
626 allocate(found(this%msh%nelv))
629 do i = 1, this%msk(0)
630 linear_idx = this%msk(i)
632 found(nonlinear_idx(4)) = .true.
636 call idx_stack%init()
637 do e = 1, this%msh%nelv
644 call idx_stack%push(linear_idx)
653 call temp_mask%init(idx_stack%array(), idx_stack%size())
654 call idx_stack%free()
656 call this%domain_element_mask%invert_mask(temp_mask, this%dof%size())
657 call temp_mask%free()
666 this%interface_dof_mask, this%dof%size())
668 this%interface_dof_mask, this%dof%size())
670 this%interface_dof_mask, this%dof%size())
672 call this%x_interface_dof%copy_from(
device_to_host, sync = .false.)
673 call this%y_interface_dof%copy_from(
device_to_host, sync = .false.)
674 call this%z_interface_dof%copy_from(
device_to_host, sync = .true.)
682 call this%interface_interpolator%init(this%dof, &
684 tol = this%interpolation_settings%tolerance, &
685 pad = this%interpolation_settings%padding, &
686 mask = this%domain_element_mask)
688 call this%interface_interpolator%find_points(this%x_interface_dof%x, &
689 this%y_interface_dof%x, this%z_interface_dof%x, &
690 this%x_interface_dof%size())
__inline__ __device__ void nonlinear_index(const int idx, const int lx, int *index)
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Retrieves a parameter by name or throws an error.
User callback for overset-interface morphing and boundary-value updates.
Defines a boundary condition.
integer, parameter, public bc_dirichlet
Supported boundary condition types. The values are set in order of precedence for global resolution....
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 device_to_host
Defines user dirichlet condition for a scalar field.
Contains the field_serties_t type.
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 scalar boundary conditions.
subroutine overset_interface_finalize(this)
Finalize by building the mask arrays and preparing interpolation data.
subroutine overset_interface_update(this, time)
Update values at the overset interface.
subroutine overset_interface_apply_scalar(this, x, n, time, strong)
Apply scalar.
subroutine gather_interface_dofs_(this)
Gather interface dofs.
subroutine overset_interface_apply_vector(this, x, y, z, n, time, strong)
(No-op) Apply vector.
subroutine overset_interface_free(this)
Destructor.
subroutine overset_interface_apply_scalar_dev(this, x_d, time, strong, strm)
Apply scalar (device).
subroutine overset_interface_restart(this, s, slag)
Restore scalar interface history from an accepted solution field. The lag series is present for trans...
subroutine overset_interface_init_from_components(this, coef, field_name, tol, pad, log, relaxation)
Constructor from components.
subroutine log_interface_error_(this, s)
Log interface RMSE for the scalar field.
subroutine overset_interface_init(this, coef, json)
Constructor.
subroutine setup_interpolator_(this)
Set up the global interpolator.
subroutine relax_interface_value_(this)
Under-relax a Schwarz correction using the previously applied interface. Blend the new donor value g_...
subroutine build_masks_(this)
Build masks.
subroutine overset_interface_apply_vector_dev(this, x_d, y_d, z_d, time, strong, strm)
(No-op) Apply vector (device).
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.
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_cmult(a, c, n)
Multiplication by constant c .
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.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
User defined dirichlet condition, for which the user can work with an entire field....
field_list_t, To be able to group fields together
Stores a series (sequence) of fields, logically connected to a base field, and arranged according to ...
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...
Overset interface BC for a scalar field.
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...