38 rhs_maker_ext_fctry, rhs_maker_bdf_fctry, rhs_maker_oifs_fctry
65 use json_module,
only : json_file, json_core, json_value
74 use mpi_f08,
only : mpi_allreduce, mpi_integer, mpi_max
88 class(
ax_t),
allocatable :: ax
131 procedure, pass(this) :: register_checkpoint => &
151 module subroutine scalar_pnpn_bc_factory(object, scheme, json, coef,
user)
152 class(
bc_t),
pointer,
intent(inout) :: object
153 type(scalar_pnpn_t),
intent(in) :: scheme
154 type(json_file),
intent(inout) :: json
155 type(
coef_t),
target,
intent(in) :: coef
157 end subroutine scalar_pnpn_bc_factory
164 module subroutine scalar_pnpn_bc_allocator(object, type_name)
165 class(
bc_t),
pointer,
intent(inout) :: object
166 character(len=*),
intent(in) :: type_name
167 end subroutine scalar_pnpn_bc_allocator
178 subroutine scalar_pnpn_bc_allocate(obj)
180 class(
bc_t),
pointer,
intent(inout) :: obj
181 end subroutine scalar_pnpn_bc_allocate
188 module subroutine register_scalar_pnpn_bc(type_name, allocator)
189 character(len=*),
intent(in) :: type_name
190 procedure(scalar_pnpn_bc_allocate),
pointer,
intent(in) :: allocator
191 end subroutine register_scalar_pnpn_bc
195 type scalar_pnpn_bc_allocator_entry
196 character(len=NEKO_VARNAME_LEN) :: type_name
197 procedure(scalar_pnpn_bc_allocate),
pointer,
nopass :: allocator => null()
198 end type scalar_pnpn_bc_allocator_entry
201 type(scalar_pnpn_bc_allocator_entry),
allocatable,
private :: &
202 scalar_pnpn_bc_registry(:)
205 integer,
private :: scalar_pnpn_bc_registry_size = 0
207 public :: scalar_pnpn_bc_allocator, scalar_pnpn_bc_allocate, &
208 register_scalar_pnpn_bc
224 subroutine scalar_pnpn_init(this, msh, coef, gs, params, numerics_params, &
225 user, chkp, ulag, vlag, wlag, time_scheme, rho)
226 class(scalar_pnpn_t),
target,
intent(inout) :: this
227 type(
mesh_t),
target,
intent(in) :: msh
228 type(
coef_t),
target,
intent(in) :: coef
229 type(
gs_t),
target,
intent(inout) :: gs
230 type(json_file),
target,
intent(inout) :: params
231 type(json_file),
target,
intent(inout) :: numerics_params
232 type(
user_t),
target,
intent(in) :: user
233 type(
chkp_t),
target,
intent(inout) :: chkp
236 type(
field_t),
target,
intent(in) :: rho
238 class(
bc_t),
pointer :: bc_i
239 character(len=15),
parameter :: scheme =
'Modular (Pn/Pn)'
241 real(kind=
dp),
pointer :: tlag(:), dtlag(:)
246 call this%scheme_init(msh, coef, gs, params, scheme,
user, rho)
249 if (this%svv_enabled)
then
250 call ax_helm_allocator(this%ax, type_name =
"standard_svv")
251 select type (operator => this%ax)
253 operator%svv => this%svv
256 call ax_helm_allocator(this%ax, type_name =
"standard")
260 call scalar_residual_factory(this%res)
263 call rhs_maker_ext_fctry(this%makeext)
266 call rhs_maker_bdf_fctry(this%makebdf)
269 call rhs_maker_oifs_fctry(this%makeoifs)
272 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
273 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
275 call this%s_res%init(dm_xh,
"s_res")
277 call this%abx1%init(dm_xh, trim(this%name) //
"_abx1")
279 call this%abx2%init(dm_xh, trim(this%name) //
"_abx2")
281 call this%advs%init(dm_xh,
"advs")
283 call this%ds%init(dm_xh,
'ds')
288 call this%setup_bcs_(
user)
290 do i = 1, this%bcs%size()
292 bc_i => this%bcs%get(i)
293 call this%bc_projector%mark(bc_i)
298 call this%proj_s%init(this%dm_Xh%size(), this%projection_dim, &
299 this%projection_activ_step)
315 call chkp%get_time_history(tlag, dtlag)
316 call advection_factory(this%adv, numerics_params, this%c_Xh, &
317 ulag, vlag, wlag, dtlag, &
320 end subroutine scalar_pnpn_init
323 subroutine scalar_pnpn_register_checkpoint(this, chkp)
324 class(scalar_pnpn_t),
target,
intent(inout) :: this
325 type(chkp_t),
intent(inout) :: chkp
326 type(checkpoint_payload_t),
pointer :: payload
328 payload => chkp%add_payload(
"scalars/" // trim(this%name))
329 call payload%add_field(this%s)
330 call payload%add_series(this%slag)
331 call payload%add_field(this%abx1)
332 call payload%add_field(this%abx2)
334 end subroutine scalar_pnpn_register_checkpoint
337 subroutine scalar_pnpn_restart(this, chkp)
338 class(scalar_pnpn_t),
target,
intent(inout) :: this
339 type(chkp_t),
intent(inout) :: chkp
341 class(bc_t),
pointer :: bc_i
342 logical :: interpolated
344 n = this%s%dof%size()
355 interpolated =
allocated(chkp%previous_mesh%elements) .or. &
356 chkp%previous_Xh%lx .ne. this%Xh%lx
358 if (interpolated)
then
359 call col2(this%s%x, this%c_Xh%mult, n)
360 call col2(this%slag%lf(1)%x, this%c_Xh%mult, n)
361 call col2(this%slag%lf(2)%x, this%c_Xh%mult, n)
363 if (neko_bcknd_device .eq. 1)
then
364 call device_memcpy(this%s%x, this%s%x_d, &
365 n, host_to_device, sync = .false.)
366 call device_memcpy(this%slag%lf(1)%x, this%slag%lf(1)%x_d, &
367 n, host_to_device, sync = .false.)
368 call device_memcpy(this%slag%lf(2)%x, this%slag%lf(2)%x_d, &
369 n, host_to_device, sync = .false.)
370 call device_memcpy(this%abx1%x, this%abx1%x_d, &
371 n, host_to_device, sync = .false.)
372 call device_memcpy(this%abx2%x, this%abx2%x_d, &
373 n, host_to_device, sync = .false.)
374 call device_memcpy(this%advs%x, this%advs%x_d, &
375 n, host_to_device, sync = .false.)
378 if (interpolated)
then
379 call this%gs_Xh%op(this%s, gs_op_add)
380 call this%gs_Xh%op(this%slag%lf(1), gs_op_add)
381 call this%gs_Xh%op(this%slag%lf(2), gs_op_add)
385 do i = 1, this%bcs%size()
386 bc_i => this%bcs%get(i)
387 call bc_i%restart(this%s, this%slag)
392 end subroutine scalar_pnpn_restart
394 subroutine scalar_pnpn_free(this)
395 class(scalar_pnpn_t),
intent(inout) :: this
398 if (
allocated(this%Ax))
then
404 call this%scheme_free()
406 call this%bc_projector%free()
407 call this%proj_s%free()
409 call this%s_res%free()
413 call this%abx1%free()
414 call this%abx2%free()
416 call this%advs%free()
418 if (
allocated(this%adv))
then
427 if (
allocated(this%res))
then
431 if (
allocated(this%makeext))
then
432 deallocate(this%makeext)
435 if (
allocated(this%makebdf))
then
436 deallocate(this%makebdf)
439 if (
allocated(this%makeoifs))
then
440 deallocate(this%makeoifs)
443 end subroutine scalar_pnpn_free
445 subroutine scalar_pnpn_step(this, time, ext_bdf, dt_controller, &
447 class(scalar_pnpn_t),
intent(inout) :: this
448 type(time_state_t),
intent(in) :: time
449 type(time_scheme_controller_t),
intent(in) :: ext_bdf
450 type(time_step_controller_t),
intent(in) :: dt_controller
451 type(ksp_monitor_t),
intent(inout) :: ksp_results
452 type(field_t),
pointer :: rho_cp
453 integer :: rho_cp_index
457 if (this%freeze)
return
459 n = this%dm_Xh%size()
460 call neko_scratch_registry%request_field(rho_cp, rho_cp_index, .false.)
462 call profiler_start_region(trim(this%name), 2)
463 associate(u => this%u, v => this%v, w => this%w, s => this%s, &
464 cp => this%cp, rho => this%rho, lambda_tot => this%lambda_tot, &
466 s_res => this%s_res, &
467 ax => this%Ax, f_xh => this%f_Xh, xh => this%Xh, &
468 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
469 slag => this%slag, oifs => this%oifs, &
470 projection_dim => this%projection_dim, &
471 msh => this%msh, res => this%res, makeoifs => this%makeoifs, &
472 makeext => this%makeext, makebdf => this%makebdf, &
473 t => time%t, tstep => time%tstep, dt => time%dt)
476 call print_debug(this)
479 call this%update_material_properties(time)
480 call field_col3(rho_cp, rho, cp, n)
483 if (this%svv_enabled)
then
484 call this%svv%update(rho_cp, tstep)
488 call this%source_term%compute(time)
494 call this%adv%compute_scalar(this%ulag%lf(1), this%vlag%lf(1), &
495 this%wlag%lf(1), s, this%advs, &
496 xh, this%c_Xh, dm_xh%size())
499 call this%adv%compute_scalar(u, v, w, s, f_xh, &
500 xh, this%c_Xh, dm_xh%size())
504 call field_col2(f_xh, rho_cp, n)
507 call this%bcs%apply_scalar(f_xh%x, n, time, .false.)
510 call makeext%compute_scalar(this%abx1, this%abx2, f_xh%x, &
511 ext_bdf%advection_coeffs%x, n)
514 call makeoifs%compute_scalar(this%advs%x, f_xh%x, &
515 rho_cp,
real(dt, kind=rp), n)
519 call makebdf%compute_scalar(slag, f_xh%x, s, c_xh%B, &
520 rho_cp,
real(dt, kind=rp), ext_bdf%diffusion_coeffs%x, &
527 call this%apply_strong_bcs(time)
530 call profiler_start_region(trim(this%name) //
'_residual', 20)
531 call res%compute(ax, s, s_res, f_xh, c_xh, msh, xh, lambda_tot, &
532 rho_cp, ext_bdf%diffusion_coeffs%x(1), &
533 real(dt, kind=rp), dm_xh%size())
535 call gs_xh%op(s_res, gs_op_add)
538 call this%bc_projector%apply(s_res%x, dm_xh%size())
540 call profiler_end_region(trim(this%name) //
'_residual', 20)
542 call this%proj_s%pre_solving(s_res%x, tstep, c_xh, n, dt_controller)
544 call this%pc%update()
545 call profiler_start_region(trim(this%name) //
'_solve', 21)
546 ksp_results = this%ksp%solve(ax, ds, s_res%x, n, &
547 c_xh, this%bc_projector, gs_xh)
548 ksp_results%name = trim(this%name)
549 call profiler_end_region(trim(this%name) //
'_solve', 21)
551 call this%proj_s%post_solving(ds%x, ax, c_xh, this%bc_projector, gs_xh, &
552 n, tstep, dt_controller)
555 if (neko_bcknd_device .eq. 1)
then
556 call device_add2s2(s%x_d, ds%x_d, 1.0_rp, n)
558 call add2s2(s%x, ds%x, 1.0_rp, n)
562 call neko_scratch_registry%relinquish_field(rho_cp_index)
563 call profiler_end_region(trim(this%name), 2)
564 end subroutine scalar_pnpn_step
566 subroutine print_debug(this)
567 class(scalar_pnpn_t),
intent(inout) :: this
568 character(len=LOG_SIZE) :: log_buf
571 n = this%dm_Xh%size()
573 write(log_buf,
'(A, A, E15.7, A, E15.7, A, E15.7)')
'Scalar debug', &
574 ' l2norm s', glsc2(this%s%x, this%s%x, n), &
575 ' slag1', glsc2(this%slag%lf(1)%x, this%slag%lf(1)%x, n), &
576 ' slag2', glsc2(this%slag%lf(2)%x, this%slag%lf(2)%x, n)
577 call neko_log%message(log_buf, lvl = neko_log_debug)
578 write(log_buf,
'(A, A, E15.7, A, E15.7)')
'Scalar debug2', &
579 ' l2norm abx1', glsc2(this%abx1%x, this%abx1%x, n), &
580 ' abx2', glsc2(this%abx2%x, this%abx2%x, n)
581 call neko_log%message(log_buf, lvl = neko_log_debug)
582 end subroutine print_debug
586 subroutine scalar_pnpn_setup_bcs_(this, user)
587 class(scalar_pnpn_t),
target,
intent(inout) :: this
588 type(user_t),
target,
intent(in) :: user
589 integer :: i, j, n_bcs, zone_size, global_zone_size, ierr
590 type(json_core) :: core
591 type(json_value),
pointer :: bc_object
592 type(json_file) :: bc_subdict
593 class(bc_t),
pointer :: bc_i
596 logical,
allocatable :: marked_zones(:)
597 integer,
allocatable :: zone_indices(:)
598 character(len=256) :: error_msg
600 if (this%params%valid_path(
'boundary_conditions'))
then
601 call this%params%info(
'boundary_conditions', &
603 call this%params%get_core(core)
604 call this%params%get(
'boundary_conditions', bc_object, found)
606 call this%bcs%init(n_bcs)
608 allocate(marked_zones(
size(this%msh%labeled_zones)))
609 marked_zones = .false.
613 call json_extract_item(core, bc_object, i, bc_subdict)
618 call json_get(bc_subdict,
"zone_indices", zone_indices)
620 do j = 1,
size(zone_indices)
621 zone_size = this%msh%labeled_zones(zone_indices(j))%size
622 call mpi_allreduce(zone_size, global_zone_size, 1, &
623 mpi_integer, mpi_max, neko_comm, ierr)
625 if (global_zone_size .eq. 0)
then
626 write(error_msg,
'(A, I0, A, A, I0, A)') &
627 "Zone index ", zone_indices(j), &
628 " is invalid as this zone has 0 size, meaning it ", &
629 "does not exist in the mesh. Check scalar boundary ", &
631 call neko_error(error_msg)
635 if (marked_zones(zone_indices(j)))
then
636 write(error_msg,
'(A, I0, A, A, A, A)')&
637 "Zone with index ", zone_indices(j), &
638 " has already been assigned a boundary condition. ", &
639 "Please check your boundary_conditions entry for the ", &
640 "scalar and make sure that each zone index appears only ",&
641 "in a single boundary condition."
642 call neko_error(error_msg)
645 marked_zones(zone_indices(j)) = .true.
651 call scalar_pnpn_bc_factory(bc_i, this, bc_subdict, this%c_Xh,
user)
652 call this%bcs%append(bc_i)
656 do i = 1,
size(this%msh%labeled_zones)
657 if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
658 (.not. marked_zones(i)))
then
659 write(error_msg,
'(A, I0)') &
660 "No scalar boundary condition assigned to zone ", i
661 call neko_error(error_msg)
667 do i = 1,
size(this%msh%labeled_zones)
668 if (this%msh%labeled_zones(i)%size .gt. 0)
then
669 write(error_msg,
'(A, A)') &
670 "No boundary_conditions entry in the case file for scalar ", &
672 call neko_error(error_msg)
682 end subroutine scalar_pnpn_setup_bcs_
686 subroutine scalar_scheme_apply_strong_bcs(this, time)
687 class(scalar_pnpn_t),
intent(inout) :: this
688 type(time_state_t),
intent(in) :: time
691 class(bc_t),
pointer :: bc_i
695 call this%bcs%apply(this%s, time = time, strong = .true.)
701 call this%gs_Xh%op(this%s, gs_op_min, glb_cmd_event)
702 call device_event_sync(glb_cmd_event)
706 call this%bcs%apply(this%s, time = time, strong = .true.)
709 call this%gs_Xh%op(this%s, gs_op_max, glb_cmd_event)
710 call device_event_sync(glb_cmd_event)
713 do i = 1, this%bcs%size()
714 bc_i => this%bcs%get(i)
715 bc_i%updated = .false.
719 end subroutine scalar_scheme_apply_strong_bcs
Copy data between host and device (or device and device)
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.
Subroutines to add advection terms to the RHS of a transport equation.
Base type for an SVV Helmholtz operator.
Defines a Matrix-vector product.
Defines a boundary condition.
integer, parameter, public bc_dirichlet
Supported boundary condition types. The values are set in order of precedence for global resolution....
Format-independent checkpoint payloads.
Defines format-independent checkpoint registration and restart state.
type(mpi_comm), public neko_comm
MPI communicator.
subroutine, public device_add2s2(a_d, b_d, c1, n, strm)
Vector addition with scalar multiplication (multiplication on first argument)
subroutine, public device_col2(a_d, b_d, n, strm)
Vector multiplication .
Device abstraction, common interface for various accelerators.
subroutine, public device_event_sync(event)
Synchronize an event.
integer, parameter, public host_to_device
type(c_ptr), bind(C), public glb_cmd_event
Event for the global command queue.
Dirichlet condition applied in the facet normal direction.
subroutine, public field_col2(a, b, n)
Vector multiplication .
subroutine, public field_col3(a, b, c, n)
Vector multiplication with 3 vectors .
Contains the field_serties_t type.
Utilities for retrieving parameters from the case files.
Implements the base abstract type for Krylov solvers plus helper types.
integer, parameter, public neko_log_debug
Debug.
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
real(kind=rp) function, public glsc2(a, b, n)
Weighted inner product .
subroutine, public col2(a, b, n)
Vector multiplication .
subroutine, public add2s2(a, b, c1, n)
Vector addition with scalar multiplication (multiplication on second argument)
integer, parameter neko_bcknd_device
integer, parameter, public dp
integer, parameter, public rp
Global precision used in computations.
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.
Project x onto X, the space of old solutions and back again.
Routines to generate the right-hand sides for the convection-diffusion equation. Employs the EXT/BDF ...
Implements scalar_projector_t.
Contains the scalar_pnpn_t type.
subroutine scalar_pnpn_step(this, time, ext_bdf, dt_controller, ksp_results)
subroutine scalar_pnpn_setup_bcs_(this, user)
Initialize boundary conditions.
subroutine scalar_scheme_apply_strong_bcs(this, time)
Apply strong boundary conditions.
subroutine scalar_pnpn_restart(this, chkp)
subroutine scalar_pnpn_register_checkpoint(this, chkp)
Register this scalar scheme with the checkpoint.
subroutine scalar_pnpn_init(this, msh, coef, gs, params, numerics_params, user, chkp, ulag, vlag, wlag, time_scheme, rho)
Constructor.
subroutine scalar_pnpn_free(this)
Defines the residual for the scalar transport equation.
Contains the scalar_scheme_t type.
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.
Compound scheme for the advection and diffusion operators in a transport equation.
Base class for time integration schemes.
Module with things related to the simulation time.
Implements type time_step_controller.
Interfaces for user interaction with NEKO.
integer, parameter, public neko_varname_len
Base abstract type for computing the advection operator.
Helmholtz operator carrying a non-owning SVV object.
Base type for a matrix-vector product providing .
Base type for a boundary condition.
Collection of live simulation data registered for checkpointing.
A named collection of live fields to checkpoint together.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Dirichlet condition in facet normal direction.
Stores a series (sequence) of fields, logically connected to a base field, and arranged according to ...
Type for storing initial and final residuals in a Krylov solver.
Abstract type to add contributions to F from lagged BD terms.
Abstract type to sum up contributions to kth order extrapolation scheme.
Abstract type to add contributions of kth order OIFS scheme.
Projector for scalar boundary conditions.
Abstract type to compute scalar residual.
Base type for a scalar advection-diffusion solver.
Implements the logic to compute the time coefficients for the advection and diffusion operators in a ...
A struct that contains all info about the time, expand as needed.
Provides a tool to set time step dt.
A type collecting all the overridable user routines and flag to suppress type injection from custom m...