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
78 character(len=:),
allocatable :: field_name
86 type(
vector_t) :: x_interface_dof, y_interface_dof, z_interface_dof
90 integer :: iextm_order = 1
92 real(kind=
rp) :: relaxation = 1.0_rp
93 integer :: last_tstep = -1
97 integer :: n_int_tot = 0
98 logical :: find_interface = .false.
99 logical :: setup = .false.
100 logical :: log = .false.
102 logical :: restart_pending = .false.
107 morph_interface => null()
113 procedure, pass(this) :: init_from_components => &
124 procedure, pass(this) :: apply_vector_dev => &
127 procedure, pass(this) :: apply_scalar_dev => &
166 interface_mask, time, bc_name, &
171 type(
mask_t),
intent(in) :: interface_mask
173 character(len=*),
intent(in) :: bc_name
174 logical,
intent(inout) :: find_interface
187 type(
coef_t),
target,
intent(in) :: coef
188 type(json_file),
intent(inout) :: json
189 character(len=:),
allocatable :: field_name
190 real(kind=
rp) :: tol, pad, relaxation
193 call json_get(json,
"field_name", field_name)
197 if (this%iextm_order .lt. 1 .or. this%iextm_order .gt. 3)
then
198 call neko_error(
"The order of the IEXTm time scheme must be 1 to 3.")
201 if (relaxation .le. 0.0_rp .or. relaxation .gt. 1.0_rp)
then
202 call neko_error(
"The overset relaxation factor must be in (0, 1].")
206 call this%init_from_components(coef, field_name, tol, pad, log, relaxation)
207 if (
allocated(field_name))
deallocate(field_name)
215 tol, pad, log, relaxation)
217 type(
coef_t),
intent(in) :: coef
218 character(len=*),
intent(in) :: field_name
219 real(kind=
rp),
intent(in),
optional :: tol, pad, relaxation
220 logical,
intent(in),
optional :: log
221 character(len=256) :: log_buf
223 call this%init_base(coef)
225 this%relaxation = 1.0_rp
227 this%restart_pending = .false.
229 if (
present(tol))
then
230 if (tol .gt. 0.0_rp)
then
231 this%interpolation_settings%tolerance = tol
235 if (
present(pad))
then
236 if (pad .gt. 0.0_rp)
then
237 this%interpolation_settings%padding = pad
241 if (
present(log))
then
245 if (
present(relaxation))
then
246 if (relaxation .le. 0.0_rp .or. relaxation .gt. 1.0_rp)
then
247 call neko_error(
"The overset relaxation factor must be in (0, 1].")
249 this%relaxation = relaxation
252 this%field_name = field_name
253 write (log_buf,
'(A,A)')
"Coupling overset interface for: ", &
254 trim(this%field_name)
257 call this%bc_s%init_from_components(coef, this%field_name)
258 call this%field_list%init(1)
259 call this%field_list%assign_to_field(1, this%bc_s%field_bc)
261 call this%x_dof%init(this%dof%size(),
'x')
262 call this%y_dof%init(this%dof%size(),
'y')
263 call this%z_dof%init(this%dof%size(),
'z')
266 call device_copy(this%x_dof%x_d, this%dof%x%x_d, this%dof%size())
267 call device_copy(this%y_dof%x_d, this%dof%y%x_d, this%dof%size())
268 call device_copy(this%z_dof%x_d, this%dof%z%x_d, this%dof%size())
274 call copy(this%x_dof%x, this%dof%x%x, this%dof%size())
275 call copy(this%y_dof%x, this%dof%y%x, this%dof%size())
276 call copy(this%z_dof%x, this%dof%z%x, this%dof%size())
285 call this%bc_s%free()
286 call this%field_list%free()
287 call this%interface_dof%free()
288 call this%interface_field%free()
290 call this%x_dof%free()
291 call this%y_dof%free()
292 call this%z_dof%free()
294 call this%x_interface_dof%free()
295 call this%y_interface_dof%free()
296 call this%z_interface_dof%free()
297 call this%s_interface%free()
298 call this%s_interface_lag%free()
300 if (
allocated(this%field_name))
then
301 deallocate(this%field_name)
304 call this%interface_interpolator%free()
306 call this%interface_dof_mask%free()
307 call this%domain_element_mask%free()
309 call this%free_base()
310 this%restart_pending = .false.
322 integer :: i, n_previous
324 call this%s_interface_lag%reset()
327 if (
present(slag))
then
328 n_previous = min(this%iextm_order - 1, slag%size())
329 do i = n_previous, 1, -1
331 slag%lf(i)%x(:,1,1,1), this%interface_dof_mask, &
332 slag%lf(i)%dof%size())
333 call this%s_interface_lag%update()
338 s%x(:,1,1,1), this%interface_dof_mask, s%dof%size())
340 this%restart_pending = .true.
349 integer,
intent(in) :: n
350 real(kind=
rp),
intent(inout),
dimension(n) :: x
352 logical,
intent(in),
optional :: strong
355 if (
present(strong))
then
364 if (.not. this%updated)
then
365 call this%update(time)
366 this%updated = .true.
370 call masked_copy_0(x, this%bc_s%field_bc%x, this%msk, n, this%msk(0))
382 type(c_ptr),
intent(inout) :: x_d
384 logical,
intent(in),
optional :: strong
385 type(c_ptr),
intent(inout) :: strm
388 if (
present(strong))
then
397 if (.not. this%updated)
then
398 call this%update(time)
399 this%updated = .true.
403 if (this%msk(0) .gt. 0)
then
405 this%bc_s%msk_d, this%bc_s%dof%size(), this%msk(0), strm)
415 integer,
intent(in) :: n
416 real(kind=
rp),
intent(inout),
dimension(n) :: x
417 real(kind=
rp),
intent(inout),
dimension(n) :: y
418 real(kind=
rp),
intent(inout),
dimension(n) :: z
420 logical,
intent(in),
optional :: strong
422 call neko_error(
"overset_interface cannot apply vector BCs.&
423 & Use overset_interface_vector instead!")
431 type(c_ptr),
intent(inout) :: x_d
432 type(c_ptr),
intent(inout) :: y_d
433 type(c_ptr),
intent(inout) :: z_d
435 logical,
intent(in),
optional :: strong
436 type(c_ptr),
intent(inout) :: strm
438 call neko_error(
"overset_interface cannot apply vector BCs.&
439 & Use overset_interface_vector instead!")
447 call this%finalize_base()
449 call this%bc_s%mark_facets(this%marked_facet)
450 call this%bc_s%finalize()
452 call this%build_masks_()
454 call this%x_interface_dof%init(this%interface_dof_mask%size(), &
456 call this%y_interface_dof%init(this%interface_dof_mask%size(), &
458 call this%z_interface_dof%init(this%interface_dof_mask%size(), &
460 call this%gather_interface_dofs_()
462 call this%setup_interpolator_()
464 call this%s_interface%init(this%interface_dof_mask%size(),
's_interface')
466 call this%interface_dof%init(3)
467 call this%interface_dof%assign_to_vector(1, this%x_interface_dof)
468 call this%interface_dof%assign_to_vector(2, this%y_interface_dof)
469 call this%interface_dof%assign_to_vector(3, this%z_interface_dof)
471 call this%interface_field%init(1)
472 call this%interface_field%assign_to_vector(1, this%s_interface)
474 call this%s_interface_lag%init(this%s_interface, this%iextm_order)
476 call mpi_allreduce(this%s_interface%size(), this%n_int_tot, 1, mpi_integer, &
487 integer :: nhist, ihist
488 real(kind=
rp) :: iextm_coeffs(4)
494 call this%morph_interface(this%interface_dof, this%interface_field, &
495 this%interface_dof_mask, time, this%name, &
501 if (this%find_interface)
then
504 call this%x_interface_dof%copy_from(
device_to_host, sync = .false.)
505 call this%y_interface_dof%copy_from(
device_to_host, sync = .false.)
506 call this%z_interface_dof%copy_from(
device_to_host, sync = .true.)
508 call this%interface_interpolator%find_points(this%x_interface_dof%x, &
509 this%y_interface_dof%x, this%z_interface_dof%x, &
510 this%x_interface_dof%size())
511 this%find_interface = .false.
519 if (.not. this%restart_pending)
then
520 call this%interface_interpolator%evaluate_masked(this%s_interface%x, &
521 s%x, this%domain_element_mask, .false.)
526 if (.not. this%restart_pending)
then
528 call this%log_interface_error_(s)
532 new_tstep = time%tstep .ne. this%last_tstep
536 this%last_tstep = time%tstep
538 call this%s_interface_lag%update()
540 nhist = min(this%s_interface_lag%filled_size(), this%iextm_order)
542 real(time%dtlag, kind=
rp), nhist)
544 call vector_cmult2(this%s_interface, this%s_interface_lag%lv(1), &
547 call vector_add2s2(this%s_interface, this%s_interface_lag%lv(ihist), &
551 this%restart_pending = .false.
557 if (.not. new_tstep)
call this%relax_interface_value_()
560 this%s_interface, this%interface_dof_mask, this%bc_s%dof%size())
578 logical :: clear_scratch = .false.
581 if (this%relaxation .ge. 1.0_rp)
return
585 this%s_interface%size(), clear_scratch)
587 this%interface_dof_mask, this%bc_s%dof%size())
592 1.0_rp - this%relaxation)
602 type(
field_t),
pointer,
intent(in) :: s
603 real(kind=
rp) :: s_int_norm
606 logical :: clear_scratch = .false.
607 character(len=256) :: log_buf
617 write(log_buf,
'(A12,A3,A10,1x,E15.7)')
'Interface BC',
' | ', &
618 'L2 Error: ', s_int_norm
631 logical,
allocatable :: found(:)
632 integer :: i, j, k, e, nelems
633 integer :: lx, ly, lz
634 integer :: nonlinear_idx(4), linear_idx
637 call this%interface_dof_mask%init(this%msk(1:this%msk(0)), this%msk(0))
643 allocate(found(this%msh%nelv))
646 do i = 1, this%msk(0)
647 linear_idx = this%msk(i)
649 found(nonlinear_idx(4)) = .true.
653 call idx_stack%init()
654 do e = 1, this%msh%nelv
661 call idx_stack%push(linear_idx)
670 call temp_mask%init(idx_stack%array(), idx_stack%size())
671 call idx_stack%free()
673 call this%domain_element_mask%invert_mask(temp_mask, this%dof%size())
674 call temp_mask%free()
683 this%interface_dof_mask, this%dof%size())
685 this%interface_dof_mask, this%dof%size())
687 this%interface_dof_mask, this%dof%size())
689 call this%x_interface_dof%copy_from(
device_to_host, sync = .false.)
690 call this%y_interface_dof%copy_from(
device_to_host, sync = .false.)
691 call this%z_interface_dof%copy_from(
device_to_host, sync = .true.)
699 call this%interface_interpolator%init(this%dof, &
701 tol = this%interpolation_settings%tolerance, &
702 pad = this%interpolation_settings%padding, &
703 mask = this%domain_element_mask)
705 call this%interface_interpolator%find_points(this%x_interface_dof%x, &
706 this%y_interface_dof%x, this%z_interface_dof%x, &
707 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).
subroutine, public profiler_start_region(name, region_id)
Started a named (name) profiler region.
subroutine, public profiler_end_region(name, region_id)
End the most recently started profiler region.
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...