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
103 real(kind=
rp) :: relaxation = 1.0_rp
104 integer :: last_tstep = -1
108 integer :: n_int_tot = 0
109 logical :: find_interface = .false.
110 logical :: setup = .false.
111 logical :: log = .false.
113 logical :: restart_pending = .false.
118 morph_interface => null()
124 procedure, pass(this) :: init_from_components => &
131 procedure, pass(this) :: apply_scalar => &
134 procedure, pass(this) :: apply_vector => &
137 procedure, pass(this) :: apply_vector_dev => &
140 procedure, pass(this) :: apply_scalar_dev => &
144 procedure, pass(this) :: restart_vector => &
170 type(
coef_t),
target,
intent(in) :: coef
171 type(json_file),
intent(inout) ::json
172 real(kind=
rp) :: tol, pad, relaxation
181 if (this%iextm_order .lt. 1 .or. this%iextm_order .gt. 3)
then
182 call neko_error(
"The order of the IEXTm time scheme must be 1 to 3.")
185 if (relaxation .le. 0.0_rp .or. relaxation .gt. 1.0_rp)
then
186 call neko_error(
"The overset relaxation factor must be in (0, 1].")
190 call this%init_from_components(coef, tol, pad, log, relaxation)
201 pad, log, relaxation)
203 type(
coef_t),
intent(in) :: coef
204 real(kind=
rp),
intent(in),
optional :: tol, pad, relaxation
205 logical,
intent(in),
optional :: log
208 call this%init_base(coef)
211 this%relaxation = 1.0_rp
213 this%restart_pending = .false.
216 if (
present(tol))
then
217 if (tol .gt. 0.0_rp) this%interpolation_settings%tolerance = tol
219 if (
present(pad))
then
220 if (pad .gt. 0.0_rp) this%interpolation_settings%padding = pad
222 if (
present(log))
then
225 if (
present(relaxation))
then
226 if (relaxation .le. 0.0_rp .or. relaxation .gt. 1.0_rp)
then
227 call neko_error(
"The overset relaxation factor must be in (0, 1].")
229 this%relaxation = relaxation
232 call this%bc_u%init_from_components(coef,
"u")
233 call this%bc_v%init_from_components(coef,
"v")
234 call this%bc_w%init_from_components(coef,
"w")
236 call this%field_list%init(3)
237 call this%field_list%assign_to_field(1, this%bc_u%field_bc)
238 call this%field_list%assign_to_field(2, this%bc_v%field_bc)
239 call this%field_list%assign_to_field(3, this%bc_w%field_bc)
242 call this%x_dof%init(this%dof%size(),
'x')
243 call this%y_dof%init(this%dof%size(),
'y')
244 call this%z_dof%init(this%dof%size(),
'z')
250 call device_copy(this%x_dof%x_d, this%dof%x%x_d, this%dof%size())
251 call device_copy(this%y_dof%x_d, this%dof%y%x_d, this%dof%size())
252 call device_copy(this%z_dof%x_d, this%dof%z%x_d, this%dof%size())
258 call copy(this%x_dof%x, this%dof%x%x, this%dof%size())
259 call copy(this%y_dof%x, this%dof%y%x, this%dof%size())
260 call copy(this%z_dof%x, this%dof%z%x, this%dof%size())
270 call this%bc_u%free()
271 call this%bc_v%free()
272 call this%bc_w%free()
274 call this%field_list%free()
275 call this%interface_dof%free()
276 call this%interface_field%free()
278 call this%x_dof%free()
279 call this%y_dof%free()
280 call this%z_dof%free()
282 call this%x_interface_dof%free()
283 call this%y_interface_dof%free()
284 call this%z_interface_dof%free()
285 call this%u_interface%free()
286 call this%v_interface%free()
287 call this%w_interface%free()
288 call this%u_interface_lag%free()
289 call this%v_interface_lag%free()
290 call this%w_interface_lag%free()
291 call this%interface_interpolator%free()
292 call this%interface_dof_mask%free()
293 call this%domain_element_mask%free()
294 call this%free_base()
296 this%restart_pending = .false.
312 type(
field_t),
intent(in) :: u, v, w
314 integer :: i, n_previous
316 call this%u_interface_lag%reset()
317 call this%v_interface_lag%reset()
318 call this%w_interface_lag%reset()
320 n_previous = min(this%iextm_order - 1, ulag%size())
324 do i = n_previous, 1, -1
326 ulag%lf(i)%x(:,1,1,1), this%interface_dof_mask, &
327 ulag%lf(i)%dof%size())
329 vlag%lf(i)%x(:,1,1,1), this%interface_dof_mask, &
330 vlag%lf(i)%dof%size())
332 wlag%lf(i)%x(:,1,1,1), this%interface_dof_mask, &
333 wlag%lf(i)%dof%size())
335 call this%u_interface_lag%update()
336 call this%v_interface_lag%update()
337 call this%w_interface_lag%update()
343 u%x(:,1,1,1), this%interface_dof_mask, u%dof%size())
345 v%x(:,1,1,1), this%interface_dof_mask, v%dof%size())
347 w%x(:,1,1,1), this%interface_dof_mask, w%dof%size())
349 this%restart_pending = .true.
358 integer,
intent(in) :: n
359 real(kind=
rp),
intent(inout),
dimension(n) :: x
361 logical,
intent(in),
optional :: strong
363 call neko_error(
"overset_interface_vector cannot apply scalar BCs.&
364 & Use overset_interface_vector::apply_vector instead!")
374 type(c_ptr),
intent(inout) :: x_d
376 logical,
intent(in),
optional :: strong
377 type(c_ptr),
intent(inout) :: strm
379 call neko_error(
"overset_interface_vector cannot apply scalar BCs.&
380 & Use overset_interface_vector::apply_vector instead!")
393 integer,
intent(in) :: n
394 real(kind=
rp),
intent(inout),
dimension(n) :: x
395 real(kind=
rp),
intent(inout),
dimension(n) :: y
396 real(kind=
rp),
intent(inout),
dimension(n) :: z
398 logical,
intent(in),
optional :: strong
401 if (
present(strong))
then
412 if (.not. this%updated)
then
413 call this%update(time)
414 this%updated = .true.
419 call masked_copy_0(x, this%bc_u%field_bc%x, this%msk, n, this%msk(0))
420 call masked_copy_0(y, this%bc_v%field_bc%x, this%msk, n, this%msk(0))
421 call masked_copy_0(z, this%bc_w%field_bc%x, this%msk, n, this%msk(0))
435 type(c_ptr),
intent(inout) :: x_d
436 type(c_ptr),
intent(inout) :: y_d
437 type(c_ptr),
intent(inout) :: z_d
439 logical,
intent(in),
optional :: strong
440 type(c_ptr),
intent(inout) :: strm
443 if (
present(strong))
then
451 if (.not. this%updated)
then
452 call this%update(time)
453 this%updated = .true.
457 if (this%msk(0) .gt. 0)
then
459 this%bc_u%msk_d, this%bc_u%dof%size(), this%msk(0), &
462 this%bc_v%msk_d, this%bc_v%dof%size(), this%msk(0), strm)
464 this%bc_w%msk_d, this%bc_w%dof%size(), this%msk(0), strm)
475 call this%finalize_base()
477 call this%bc_u%mark_facets(this%marked_facet)
478 call this%bc_v%mark_facets(this%marked_facet)
479 call this%bc_w%mark_facets(this%marked_facet)
481 call this%bc_u%finalize()
482 call this%bc_v%finalize()
483 call this%bc_w%finalize()
486 call this%build_masks_()
489 call this%x_interface_dof%init(this%interface_dof_mask%size(), &
491 call this%y_interface_dof%init(this%interface_dof_mask%size(), &
493 call this%z_interface_dof%init(this%interface_dof_mask%size(), &
495 call this%gather_interface_dofs_()
498 call this%setup_interpolator_()
501 call this%u_interface%init(this%interface_dof_mask%size(),
'u_interface')
502 call this%v_interface%init(this%interface_dof_mask%size(),
'v_interface')
503 call this%w_interface%init(this%interface_dof_mask%size(),
'w_interface')
506 call this%interface_dof%init(3)
507 call this%interface_dof%assign_to_vector(1, this%x_interface_dof)
508 call this%interface_dof%assign_to_vector(2, this%y_interface_dof)
509 call this%interface_dof%assign_to_vector(3, this%z_interface_dof)
511 call this%interface_field%init(3)
512 call this%interface_field%assign_to_vector(1, this%u_interface)
513 call this%interface_field%assign_to_vector(2, this%v_interface)
514 call this%interface_field%assign_to_vector(3, this%w_interface)
517 call this%u_interface_lag%init(this%u_interface, this%iextm_order)
518 call this%v_interface_lag%init(this%v_interface, this%iextm_order)
519 call this%w_interface_lag%init(this%w_interface, this%iextm_order)
521 call mpi_allreduce(this%u_interface%size(), this%n_int_tot, 1, mpi_integer, &
531 type(
field_t),
pointer :: u, v, w
533 integer :: nhist, ihist
534 real(kind=
rp) :: iextm_coeffs(4)
539 call this%morph_interface(this%interface_dof, this%interface_field, &
540 this%interface_dof_mask, time, this%name, &
550 if (this%find_interface)
then
553 call this%x_interface_dof%copy_from(
device_to_host, sync = .false.)
554 call this%y_interface_dof%copy_from(
device_to_host, sync = .false.)
555 call this%z_interface_dof%copy_from(
device_to_host, sync = .true.)
557 call this%interface_interpolator%find_points(this%x_interface_dof%x, &
558 this%y_interface_dof%x, this%z_interface_dof%x, &
559 this%x_interface_dof%size())
560 this%find_interface = .false.
571 if (.not. this%restart_pending)
then
572 call this%interface_interpolator%evaluate_masked(this%u_interface%x, &
573 u%x, this%domain_element_mask, .false.)
574 call this%interface_interpolator%evaluate_masked(this%v_interface%x, &
575 v%x, this%domain_element_mask, .false.)
576 call this%interface_interpolator%evaluate_masked(this%w_interface%x, &
577 w%x, this%domain_element_mask, .false.)
580 call this%log_interface_error_(u, v, w)
585 new_tstep = time%tstep .ne. this%last_tstep
590 this%last_tstep = time%tstep
593 call this%u_interface_lag%update()
594 call this%v_interface_lag%update()
595 call this%w_interface_lag%update()
598 nhist = min(this%u_interface_lag%filled_size(), this%iextm_order)
600 real(time%dtlag, kind=
rp), nhist)
603 call vector_cmult2(this%u_interface, this%u_interface_lag%lv(1), &
605 call vector_cmult2(this%v_interface, this%v_interface_lag%lv(1), &
607 call vector_cmult2(this%w_interface, this%w_interface_lag%lv(1), &
611 this%u_interface_lag%lv(ihist), iextm_coeffs(ihist))
613 this%v_interface_lag%lv(ihist), iextm_coeffs(ihist))
615 this%w_interface_lag%lv(ihist), iextm_coeffs(ihist))
618 this%restart_pending = .false.
624 if (.not. new_tstep)
call this%relax_interface_values_()
629 this%interface_dof_mask, this%bc_u%dof%size())
632 this%interface_dof_mask, this%bc_v%dof%size())
635 this%interface_dof_mask, this%bc_w%dof%size())
650 logical :: clear_scratch = .false.
653 if (this%relaxation .ge. 1.0_rp)
return
657 this%u_interface%size(), clear_scratch)
661 this%interface_dof_mask, this%bc_u%dof%size())
664 1.0_rp - this%relaxation)
668 this%interface_dof_mask, this%bc_v%dof%size())
671 1.0_rp - this%relaxation)
675 this%interface_dof_mask, this%bc_w%dof%size())
678 1.0_rp - this%relaxation)
688 type(
field_t),
pointer,
intent(in) :: u, v, w
689 real(kind=
rp) :: u_int_norm, v_int_norm, w_int_norm
692 logical :: clear_scratch = .false.
693 character(len=256) :: log_buf
717 write(log_buf,
'(A12,A3,A10,1x,A1,E15.7,A1,E15.7,A1,E15.7,A1)') &
718 'Interface BC',
' | ',
'L2 Error: ',
'(', &
719 u_int_norm,
',', v_int_norm,
',', w_int_norm,
')'
732 logical,
allocatable :: found(:)
733 integer :: i, j, k, e, new_size, nelems
734 integer :: lx, ly, lz
735 integer :: nonlinear_idx(4), linear_idx
739 call this%interface_dof_mask%init(this%msk(1:this%msk(0)), this%msk(0))
746 allocate(found(this%msh%nelv))
749 do i = 1, this%msk(0)
750 linear_idx = this%msk(i)
752 found(nonlinear_idx(4)) = .true.
757 do e = 1, this%msh%nelv
764 call stack%push(linear_idx)
771 call temp_mask%init(
stack%array(),
stack%size())
775 call this%domain_element_mask%invert_mask(temp_mask, this%dof%size())
777 call temp_mask%free()
787 this%dof%x%x(:,1,1,1), &
788 this%interface_dof_mask, &
791 this%dof%y%x(:,1,1,1), &
792 this%interface_dof_mask, &
795 this%dof%z%x(:,1,1,1), &
796 this%interface_dof_mask, &
799 call this%x_interface_dof%copy_from(
device_to_host, sync = .false.)
800 call this%y_interface_dof%copy_from(
device_to_host, sync = .false.)
801 call this%z_interface_dof%copy_from(
device_to_host, sync = .true.)
811 call this%interface_interpolator%init(this%dof, &
813 tol=this%interpolation_settings%tolerance, &
814 pad=this%interpolation_settings%padding, &
815 mask=this%domain_element_mask)
818 call this%interface_interpolator%find_points(this%x_interface_dof%x, &
819 this%y_interface_dof%x, &
820 this%z_interface_dof%x, &
821 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.
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...