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
334 if (.not. this%updated)
then
335 call this%update(time)
336 this%updated = .true.
341 call masked_copy_0(x, this%bc_u%field_bc%x, this%msk, n, this%msk(0))
342 call masked_copy_0(y, this%bc_v%field_bc%x, this%msk, n, this%msk(0))
343 call masked_copy_0(z, this%bc_w%field_bc%x, this%msk, n, this%msk(0))
357 type(c_ptr),
intent(inout) :: x_d
358 type(c_ptr),
intent(inout) :: y_d
359 type(c_ptr),
intent(inout) :: z_d
361 logical,
intent(in),
optional :: strong
362 type(c_ptr),
intent(inout) :: strm
365 if (
present(strong))
then
373 if (.not. this%updated)
then
374 call this%update(time)
375 this%updated = .true.
379 if (this%msk(0) .gt. 0)
then
381 this%bc_u%msk_d, this%bc_u%dof%size(), this%msk(0), &
384 this%bc_v%msk_d, this%bc_v%dof%size(), this%msk(0), strm)
386 this%bc_w%msk_d, this%bc_w%dof%size(), this%msk(0), strm)
395 logical,
optional,
intent(in) :: only_facets
396 logical :: only_facets_
398 if (
present(only_facets))
then
399 only_facets_ = only_facets
401 only_facets_ = .false.
405 call this%finalize_base(only_facets_)
407 call this%bc_u%mark_facets(this%marked_facet)
408 call this%bc_v%mark_facets(this%marked_facet)
409 call this%bc_w%mark_facets(this%marked_facet)
411 call this%bc_u%finalize(only_facets_)
412 call this%bc_v%finalize(only_facets_)
413 call this%bc_w%finalize(only_facets_)
416 call this%build_masks_()
419 call this%x_interface_dof%init(this%interface_dof_mask%size(), &
421 call this%y_interface_dof%init(this%interface_dof_mask%size(), &
423 call this%z_interface_dof%init(this%interface_dof_mask%size(), &
425 call this%gather_interface_dofs_()
428 call this%setup_interpolator_()
431 call this%u_interface%init(this%interface_dof_mask%size(),
'u_interface')
432 call this%v_interface%init(this%interface_dof_mask%size(),
'v_interface')
433 call this%w_interface%init(this%interface_dof_mask%size(),
'w_interface')
436 call this%interface_dof%init(3)
437 call this%interface_dof%assign_to_vector(1, this%x_interface_dof)
438 call this%interface_dof%assign_to_vector(2, this%y_interface_dof)
439 call this%interface_dof%assign_to_vector(3, this%z_interface_dof)
441 call this%interface_field%init(3)
442 call this%interface_field%assign_to_vector(1, this%u_interface)
443 call this%interface_field%assign_to_vector(2, this%v_interface)
444 call this%interface_field%assign_to_vector(3, this%w_interface)
447 call this%u_interface_lag%init(this%u_interface, this%iextm_order)
448 call this%v_interface_lag%init(this%v_interface, this%iextm_order)
449 call this%w_interface_lag%init(this%w_interface, this%iextm_order)
451 call mpi_allreduce(this%u_interface%size(), this%n_int_tot, 1, mpi_integer, &
461 type(
field_t),
pointer :: u, v, w
463 integer :: nhist, ihist
464 real(kind=
rp) :: iextm_coeffs(4)
468 call this%morph_interface(this%interface_dof, this%interface_field, &
469 this%interface_dof_mask, time, this%name, &
479 if (this%find_interface)
then
482 call this%x_interface_dof%copy_from(
device_to_host, sync = .false.)
483 call this%y_interface_dof%copy_from(
device_to_host, sync = .false.)
484 call this%z_interface_dof%copy_from(
device_to_host, sync = .true.)
486 call this%interface_interpolator%find_points(this%x_interface_dof%x, &
487 this%y_interface_dof%x, this%z_interface_dof%x, &
488 this%x_interface_dof%size())
489 this%find_interface = .false.
499 call this%interface_interpolator%evaluate_masked(this%u_interface%x, &
500 u%x, this%domain_element_mask, .false.)
501 call this%interface_interpolator%evaluate_masked(this%v_interface%x, &
502 v%x, this%domain_element_mask, .false.)
503 call this%interface_interpolator%evaluate_masked(this%w_interface%x, &
504 w%x, this%domain_element_mask, .false.)
507 call this%log_interface_error_(u, v, w)
512 if (time%tstep .ne. this%last_tstep)
then
514 this%last_tstep = time%tstep
517 call this%u_interface_lag%update()
518 call this%v_interface_lag%update()
519 call this%w_interface_lag%update()
522 nhist = min(time%tstep, this%iextm_order)
523 call time_scheme%compute_coeffs(iextm_coeffs, time%dtlag, nhist)
526 call vector_cmult2(this%u_interface, this%u_interface_lag%lv(1), &
528 call vector_cmult2(this%v_interface, this%v_interface_lag%lv(1), &
530 call vector_cmult2(this%w_interface, this%w_interface_lag%lv(1), &
534 this%u_interface_lag%lv(ihist), iextm_coeffs(ihist))
536 this%v_interface_lag%lv(ihist), iextm_coeffs(ihist))
538 this%w_interface_lag%lv(ihist), iextm_coeffs(ihist))
547 this%interface_dof_mask, this%bc_u%dof%size())
550 this%interface_dof_mask, this%bc_v%dof%size())
553 this%interface_dof_mask, this%bc_w%dof%size())
561 type(
field_t),
pointer,
intent(in) :: u, v, w
562 real(kind=
rp) :: u_int_norm, v_int_norm, w_int_norm
565 logical :: clear_scratch = .false.
566 character(len=256) :: log_buf
590 write(log_buf,
'(A12,A3,A10,1x,A1,E15.7,A1,E15.7,A1,E15.7,A1)') &
591 'Interface BC',
' | ',
'L2 Error: ',
'(', &
592 u_int_norm,
',', v_int_norm,
',', w_int_norm,
')'
605 logical,
allocatable :: found(:)
606 integer :: i, j, k, e, new_size, nelems
607 integer :: lx, ly, lz
608 integer :: nonlinear_idx(4), linear_idx
612 call this%interface_dof_mask%init(this%msk(1:this%msk(0)), this%msk(0))
619 allocate(found(this%msh%nelv))
622 do i = 1, this%msk(0)
623 linear_idx = this%msk(i)
625 found(nonlinear_idx(4)) = .true.
630 do e = 1, this%msh%nelv
637 call stack%push(linear_idx)
644 call temp_mask%init(
stack%array(),
stack%size())
648 call this%domain_element_mask%invert_mask(temp_mask, this%dof%size())
650 call temp_mask%free()
660 this%dof%x(:,1,1,1), &
661 this%interface_dof_mask, &
664 this%dof%y(:,1,1,1), &
665 this%interface_dof_mask, &
668 this%dof%z(:,1,1,1), &
669 this%interface_dof_mask, &
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.)
684 call this%interface_interpolator%init(this%dof, &
686 tol=this%interpolation_settings%tolerance, &
687 pad=this%interpolation_settings%padding, &
688 mask=this%domain_element_mask)
691 call this%interface_interpolator%find_points(this%x_interface_dof%x, &
692 this%y_interface_dof%x, &
693 this%z_interface_dof%x, &
694 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...