66 use json_module,
only : json_file
70 use,
intrinsic :: iso_c_binding, only : c_ptr, c_size_t
73 use mpi_f08,
only : mpi_allreduce, mpi_integer, mpi_sum
99 type(
vector_t) :: x_interface_dof, y_interface_dof, z_interface_dof
100 type(
vector_t) :: u_interface, v_interface, w_interface
102 integer :: iextm_order = 1
104 real(kind=
rp) :: relaxation = 1.0_rp
105 integer :: last_tstep = -1
109 integer :: n_int_tot = 0
110 logical :: find_interface = .false.
111 logical :: setup = .false.
112 logical :: log = .false.
114 logical :: restart_pending = .false.
119 morph_interface => null()
125 procedure, pass(this) :: init_from_components => &
132 procedure, pass(this) :: apply_scalar => &
135 procedure, pass(this) :: apply_vector => &
138 procedure, pass(this) :: apply_vector_dev => &
141 procedure, pass(this) :: apply_scalar_dev => &
145 procedure, pass(this) :: restart_vector => &
171 type(
coef_t),
target,
intent(in) :: coef
172 type(json_file),
intent(inout) ::json
173 real(kind=
rp) :: tol, pad, relaxation
182 if (this%iextm_order .lt. 1 .or. this%iextm_order .gt. 3)
then
183 call neko_error(
"The order of the IEXTm time scheme must be 1 to 3.")
186 if (relaxation .le. 0.0_rp .or. relaxation .gt. 1.0_rp)
then
187 call neko_error(
"The overset relaxation factor must be in (0, 1].")
191 call this%init_from_components(coef, tol, pad, log, relaxation)
202 pad, log, relaxation)
204 type(
coef_t),
intent(in) :: coef
205 real(kind=
rp),
intent(in),
optional :: tol, pad, relaxation
206 logical,
intent(in),
optional :: log
209 call this%init_base(coef)
212 this%relaxation = 1.0_rp
214 this%restart_pending = .false.
217 if (
present(tol))
then
218 if (tol .gt. 0.0_rp) this%interpolation_settings%tolerance = tol
220 if (
present(pad))
then
221 if (pad .gt. 0.0_rp) this%interpolation_settings%padding = pad
223 if (
present(log))
then
226 if (
present(relaxation))
then
227 if (relaxation .le. 0.0_rp .or. relaxation .gt. 1.0_rp)
then
228 call neko_error(
"The overset relaxation factor must be in (0, 1].")
230 this%relaxation = relaxation
233 call this%bc_u%init_from_components(coef,
"u")
234 call this%bc_v%init_from_components(coef,
"v")
235 call this%bc_w%init_from_components(coef,
"w")
237 call this%field_list%init(3)
238 call this%field_list%assign_to_field(1, this%bc_u%field_bc)
239 call this%field_list%assign_to_field(2, this%bc_v%field_bc)
240 call this%field_list%assign_to_field(3, this%bc_w%field_bc)
243 call this%x_dof%init(this%dof%size(),
'x')
244 call this%y_dof%init(this%dof%size(),
'y')
245 call this%z_dof%init(this%dof%size(),
'z')
251 call device_copy(this%x_dof%x_d, this%dof%x%x_d, this%dof%size())
252 call device_copy(this%y_dof%x_d, this%dof%y%x_d, this%dof%size())
253 call device_copy(this%z_dof%x_d, this%dof%z%x_d, this%dof%size())
259 call copy(this%x_dof%x, this%dof%x%x, this%dof%size())
260 call copy(this%y_dof%x, this%dof%y%x, this%dof%size())
261 call copy(this%z_dof%x, this%dof%z%x, this%dof%size())
271 call this%bc_u%free()
272 call this%bc_v%free()
273 call this%bc_w%free()
275 call this%field_list%free()
276 call this%interface_dof%free()
277 call this%interface_field%free()
279 call this%x_dof%free()
280 call this%y_dof%free()
281 call this%z_dof%free()
283 call this%x_interface_dof%free()
284 call this%y_interface_dof%free()
285 call this%z_interface_dof%free()
286 call this%u_interface%free()
287 call this%v_interface%free()
288 call this%w_interface%free()
289 call this%u_interface_lag%free()
290 call this%v_interface_lag%free()
291 call this%w_interface_lag%free()
292 call this%interface_interpolator%free()
293 call this%interface_dof_mask%free()
294 call this%domain_element_mask%free()
295 call this%free_base()
297 this%restart_pending = .false.
313 type(
field_t),
intent(in) :: u, v, w
315 integer :: i, n_previous
317 call this%u_interface_lag%reset()
318 call this%v_interface_lag%reset()
319 call this%w_interface_lag%reset()
321 n_previous = min(this%iextm_order - 1, ulag%size())
325 do i = n_previous, 1, -1
327 ulag%lf(i)%x(:,1,1,1), this%interface_dof_mask, &
328 ulag%lf(i)%dof%size())
330 vlag%lf(i)%x(:,1,1,1), this%interface_dof_mask, &
331 vlag%lf(i)%dof%size())
333 wlag%lf(i)%x(:,1,1,1), this%interface_dof_mask, &
334 wlag%lf(i)%dof%size())
336 call this%u_interface_lag%update()
337 call this%v_interface_lag%update()
338 call this%w_interface_lag%update()
344 u%x(:,1,1,1), this%interface_dof_mask, u%dof%size())
346 v%x(:,1,1,1), this%interface_dof_mask, v%dof%size())
348 w%x(:,1,1,1), this%interface_dof_mask, w%dof%size())
350 this%restart_pending = .true.
359 integer,
intent(in) :: n
360 real(kind=
rp),
intent(inout),
dimension(n) :: x
362 logical,
intent(in),
optional :: strong
364 call neko_error(
"overset_interface_vector cannot apply scalar BCs.&
365 & Use overset_interface_vector::apply_vector instead!")
375 type(c_ptr),
intent(inout) :: x_d
377 logical,
intent(in),
optional :: strong
378 type(c_ptr),
intent(inout) :: strm
380 call neko_error(
"overset_interface_vector cannot apply scalar BCs.&
381 & Use overset_interface_vector::apply_vector instead!")
394 integer,
intent(in) :: n
395 real(kind=
rp),
intent(inout),
dimension(n) :: x
396 real(kind=
rp),
intent(inout),
dimension(n) :: y
397 real(kind=
rp),
intent(inout),
dimension(n) :: z
399 logical,
intent(in),
optional :: strong
402 if (
present(strong))
then
414 if (.not. this%updated)
then
415 call this%update(time)
416 this%updated = .true.
421 call masked_copy_0(x, this%bc_u%field_bc%x, this%msk, n, this%msk(0))
422 call masked_copy_0(y, this%bc_v%field_bc%x, this%msk, n, this%msk(0))
423 call masked_copy_0(z, this%bc_w%field_bc%x, this%msk, n, this%msk(0))
438 type(c_ptr),
intent(inout) :: x_d
439 type(c_ptr),
intent(inout) :: y_d
440 type(c_ptr),
intent(inout) :: z_d
442 logical,
intent(in),
optional :: strong
443 type(c_ptr),
intent(inout) :: strm
446 if (
present(strong))
then
455 if (.not. this%updated)
then
456 call this%update(time)
457 this%updated = .true.
461 if (this%msk(0) .gt. 0)
then
463 this%bc_u%msk_d, this%bc_u%dof%size(), this%msk(0), &
466 this%bc_v%msk_d, this%bc_v%dof%size(), this%msk(0), strm)
468 this%bc_w%msk_d, this%bc_w%dof%size(), this%msk(0), strm)
480 call this%finalize_base()
482 call this%bc_u%mark_facets(this%marked_facet)
483 call this%bc_v%mark_facets(this%marked_facet)
484 call this%bc_w%mark_facets(this%marked_facet)
486 call this%bc_u%finalize()
487 call this%bc_v%finalize()
488 call this%bc_w%finalize()
491 call this%build_masks_()
494 call this%x_interface_dof%init(this%interface_dof_mask%size(), &
496 call this%y_interface_dof%init(this%interface_dof_mask%size(), &
498 call this%z_interface_dof%init(this%interface_dof_mask%size(), &
500 call this%gather_interface_dofs_()
503 call this%setup_interpolator_()
506 call this%u_interface%init(this%interface_dof_mask%size(),
'u_interface')
507 call this%v_interface%init(this%interface_dof_mask%size(),
'v_interface')
508 call this%w_interface%init(this%interface_dof_mask%size(),
'w_interface')
511 call this%interface_dof%init(3)
512 call this%interface_dof%assign_to_vector(1, this%x_interface_dof)
513 call this%interface_dof%assign_to_vector(2, this%y_interface_dof)
514 call this%interface_dof%assign_to_vector(3, this%z_interface_dof)
516 call this%interface_field%init(3)
517 call this%interface_field%assign_to_vector(1, this%u_interface)
518 call this%interface_field%assign_to_vector(2, this%v_interface)
519 call this%interface_field%assign_to_vector(3, this%w_interface)
522 call this%u_interface_lag%init(this%u_interface, this%iextm_order)
523 call this%v_interface_lag%init(this%v_interface, this%iextm_order)
524 call this%w_interface_lag%init(this%w_interface, this%iextm_order)
526 call mpi_allreduce(this%u_interface%size(), this%n_int_tot, 1, mpi_integer, &
536 type(
field_t),
pointer :: u, v, w
538 integer :: nhist, ihist
539 real(kind=
rp) :: iextm_coeffs(4)
546 call this%morph_interface(this%interface_dof, this%interface_field, &
547 this%interface_dof_mask, time, this%name, &
559 if (this%find_interface)
then
562 call this%x_interface_dof%copy_from(
device_to_host, sync = .false.)
563 call this%y_interface_dof%copy_from(
device_to_host, sync = .false.)
564 call this%z_interface_dof%copy_from(
device_to_host, sync = .true.)
566 call this%interface_interpolator%find_points(this%x_interface_dof%x, &
567 this%y_interface_dof%x, this%z_interface_dof%x, &
568 this%x_interface_dof%size())
569 this%find_interface = .false.
580 if (.not. this%restart_pending)
then
581 call this%interface_interpolator%evaluate_masked(this%u_interface%x, &
582 u%x, this%domain_element_mask, .false.)
583 call this%interface_interpolator%evaluate_masked(this%v_interface%x, &
584 v%x, this%domain_element_mask, .false.)
585 call this%interface_interpolator%evaluate_masked(this%w_interface%x, &
586 w%x, this%domain_element_mask, .false.)
591 if (.not. this%restart_pending)
then
593 call this%log_interface_error_(u, v, w)
598 new_tstep = time%tstep .ne. this%last_tstep
604 this%last_tstep = time%tstep
607 call this%u_interface_lag%update()
608 call this%v_interface_lag%update()
609 call this%w_interface_lag%update()
612 nhist = min(this%u_interface_lag%filled_size(), this%iextm_order)
614 real(time%dtlag, kind=
rp), nhist)
617 call vector_cmult2(this%u_interface, this%u_interface_lag%lv(1), &
619 call vector_cmult2(this%v_interface, this%v_interface_lag%lv(1), &
621 call vector_cmult2(this%w_interface, this%w_interface_lag%lv(1), &
625 this%u_interface_lag%lv(ihist), iextm_coeffs(ihist))
627 this%v_interface_lag%lv(ihist), iextm_coeffs(ihist))
629 this%w_interface_lag%lv(ihist), iextm_coeffs(ihist))
632 this%restart_pending = .false.
639 if (.not. new_tstep)
call this%relax_interface_values_()
644 this%interface_dof_mask, this%bc_u%dof%size())
647 this%interface_dof_mask, this%bc_v%dof%size())
650 this%interface_dof_mask, this%bc_w%dof%size())
666 logical :: clear_scratch = .false.
669 if (this%relaxation .ge. 1.0_rp)
return
673 this%u_interface%size(), clear_scratch)
677 this%interface_dof_mask, this%bc_u%dof%size())
680 1.0_rp - this%relaxation)
684 this%interface_dof_mask, this%bc_v%dof%size())
687 1.0_rp - this%relaxation)
691 this%interface_dof_mask, this%bc_w%dof%size())
694 1.0_rp - this%relaxation)
704 type(
field_t),
pointer,
intent(in) :: u, v, w
705 real(kind=
rp) :: u_int_norm, v_int_norm, w_int_norm
708 logical :: clear_scratch = .false.
709 character(len=256) :: log_buf
733 write(log_buf,
'(A12,A3,A10,1x,A1,E15.7,A1,E15.7,A1,E15.7,A1)') &
734 'Interface BC',
' | ',
'L2 Error: ',
'(', &
735 u_int_norm,
',', v_int_norm,
',', w_int_norm,
')'
748 logical,
allocatable :: found(:)
749 integer :: i, j, k, e, new_size, nelems
750 integer :: lx, ly, lz
751 integer :: nonlinear_idx(4), linear_idx
755 call this%interface_dof_mask%init(this%msk(1:this%msk(0)), this%msk(0))
762 allocate(found(this%msh%nelv))
765 do i = 1, this%msk(0)
766 linear_idx = this%msk(i)
768 found(nonlinear_idx(4)) = .true.
773 do e = 1, this%msh%nelv
780 call stack%push(linear_idx)
787 call temp_mask%init(
stack%array(),
stack%size())
791 call this%domain_element_mask%invert_mask(temp_mask, this%dof%size())
793 call temp_mask%free()
803 this%dof%x%x(:,1,1,1), &
804 this%interface_dof_mask, &
807 this%dof%y%x(:,1,1,1), &
808 this%interface_dof_mask, &
811 this%dof%z%x(:,1,1,1), &
812 this%interface_dof_mask, &
815 call this%x_interface_dof%copy_from(
device_to_host, sync = .false.)
816 call this%y_interface_dof%copy_from(
device_to_host, sync = .false.)
817 call this%z_interface_dof%copy_from(
device_to_host, sync = .true.)
827 call this%interface_interpolator%init(this%dof, &
829 tol=this%interpolation_settings%tolerance, &
830 pad=this%interpolation_settings%padding, &
831 mask=this%domain_element_mask)
834 call this%interface_interpolator%find_points(this%x_interface_dof%x, &
835 this%y_interface_dof%x, &
836 this%z_interface_dof%x, &
837 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.
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 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.
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 vector boundary conditions.
subroutine relax_interface_values_(this)
Under-relax a Schwarz correction using the previously applied interface. For each velocity component,...
subroutine overset_interface_vector_init_from_components(this, coef, tol, pad, log, relaxation)
Constructor from components.
subroutine overset_interface_vector_apply_scalar_dev(this, x_d, time, strong, strm)
No-op apply scalar (device).
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_restart(this, u, v, w, ulag, vlag, wlag)
Restore interface history from checkpointed solution fields. Values are inserted from oldest to newes...
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_finalize(this)
Finalize by building the mask arrays and propagating to underlying bcs.
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.
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.
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_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.
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
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...
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...