38 rhs_maker_ext_fctry, rhs_maker_bdf_fctry, rhs_maker_oifs_fctry
65 use json_module,
only : json_file, json_core, json_value
73 use mpi_f08,
only : mpi_allreduce, mpi_integer, mpi_max
87 class(
ax_t),
allocatable :: ax
130 procedure, pass(this) :: register_checkpoint => &
150 module subroutine scalar_pnpn_bc_factory(object, scheme, json, coef,
user)
151 class(
bc_t),
pointer,
intent(inout) :: object
152 type(scalar_pnpn_t),
intent(in) :: scheme
153 type(json_file),
intent(inout) :: json
154 type(
coef_t),
target,
intent(in) :: coef
156 end subroutine scalar_pnpn_bc_factory
163 module subroutine scalar_pnpn_bc_allocator(object, type_name)
164 class(
bc_t),
pointer,
intent(inout) :: object
165 character(len=*),
intent(in) :: type_name
166 end subroutine scalar_pnpn_bc_allocator
177 subroutine scalar_pnpn_bc_allocate(obj)
179 class(
bc_t),
pointer,
intent(inout) :: obj
180 end subroutine scalar_pnpn_bc_allocate
187 module subroutine register_scalar_pnpn_bc(type_name, allocator)
188 character(len=*),
intent(in) :: type_name
189 procedure(scalar_pnpn_bc_allocate),
pointer,
intent(in) :: allocator
190 end subroutine register_scalar_pnpn_bc
194 type scalar_pnpn_bc_allocator_entry
195 character(len=NEKO_TYPENAME_LEN) :: type_name
196 procedure(scalar_pnpn_bc_allocate),
pointer,
nopass :: allocator => null()
197 end type scalar_pnpn_bc_allocator_entry
200 type(scalar_pnpn_bc_allocator_entry),
allocatable,
private :: &
201 scalar_pnpn_bc_registry(:)
204 integer,
private :: scalar_pnpn_bc_registry_size = 0
206 public :: scalar_pnpn_bc_allocator, scalar_pnpn_bc_allocate, &
207 register_scalar_pnpn_bc
223 subroutine scalar_pnpn_init(this, msh, coef, gs, params, numerics_params, &
224 user, chkp, ulag, vlag, wlag, time_scheme, rho)
225 class(scalar_pnpn_t),
target,
intent(inout) :: this
226 type(
mesh_t),
target,
intent(in) :: msh
227 type(
coef_t),
target,
intent(in) :: coef
228 type(
gs_t),
target,
intent(inout) :: gs
229 type(json_file),
target,
intent(inout) :: params
230 type(json_file),
target,
intent(inout) :: numerics_params
231 type(
user_t),
target,
intent(in) :: user
232 type(
chkp_t),
target,
intent(inout) :: chkp
235 type(
field_t),
target,
intent(in) :: rho
237 class(
bc_t),
pointer :: bc_i
238 character(len=15),
parameter :: scheme =
'Modular (Pn/Pn)'
240 real(kind=
dp),
pointer :: tlag(:), dtlag(:)
245 call this%scheme_init(msh, coef, gs, params, scheme,
user, rho)
248 if (this%svv_enabled)
then
249 call ax_helm_allocator(this%ax, type_name =
"standard_svv")
250 select type (operator => this%ax)
252 operator%svv => this%svv
254 else if (this%c_Xh%geo_compression)
then
255 call ax_helm_allocator(this%ax, type_name =
"standard_compr")
257 call ax_helm_allocator(this%ax, type_name =
"standard")
261 call scalar_residual_factory(this%res)
264 call rhs_maker_ext_fctry(this%makeext)
267 call rhs_maker_bdf_fctry(this%makebdf)
270 call rhs_maker_oifs_fctry(this%makeoifs)
273 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
274 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
276 call this%s_res%init(dm_xh,
"s_res")
278 call this%abx1%init(dm_xh, trim(this%name) //
"_abx1")
280 call this%abx2%init(dm_xh, trim(this%name) //
"_abx2")
282 call this%advs%init(dm_xh,
"advs")
284 call this%ds%init(dm_xh,
'ds')
289 call this%setup_bcs_(
user)
291 do i = 1, this%bcs%size()
293 bc_i => this%bcs%get(i)
294 call this%bc_projector%mark(bc_i)
299 call this%proj_s%init(this%dm_Xh%size(), this%projection_dim, &
300 this%projection_activ_step)
316 call chkp%get_time_history(tlag, dtlag)
317 call advection_factory(this%adv, numerics_params, this%c_Xh, &
318 ulag, vlag, wlag, dtlag, &
321 end subroutine scalar_pnpn_init
324 subroutine scalar_pnpn_register_checkpoint(this, chkp)
325 class(scalar_pnpn_t),
target,
intent(inout) :: this
326 type(chkp_t),
intent(inout) :: chkp
327 type(checkpoint_payload_t),
pointer :: payload
329 payload => chkp%add_payload(
"scalars/" // trim(this%name))
330 call payload%add_field(this%s)
331 call payload%add_series(this%slag)
332 call payload%add_field(this%abx1)
333 call payload%add_field(this%abx2)
335 end subroutine scalar_pnpn_register_checkpoint
338 subroutine scalar_pnpn_restart(this, chkp)
339 class(scalar_pnpn_t),
target,
intent(inout) :: this
340 type(chkp_t),
intent(inout) :: chkp
342 class(bc_t),
pointer :: bc_i
343 logical :: interpolated
345 n = this%s%dof%size()
356 interpolated =
allocated(chkp%previous_mesh%elements) .or. &
357 chkp%previous_Xh%lx .ne. this%Xh%lx
359 if (interpolated)
then
360 call col2(this%s%x, this%c_Xh%mult, n)
361 call col2(this%slag%lf(1)%x, this%c_Xh%mult, n)
362 call col2(this%slag%lf(2)%x, this%c_Xh%mult, n)
364 if (neko_bcknd_device .eq. 1)
then
365 call device_memcpy(this%s%x, this%s%x_d, &
366 n, host_to_device, sync = .false.)
367 call device_memcpy(this%slag%lf(1)%x, this%slag%lf(1)%x_d, &
368 n, host_to_device, sync = .false.)
369 call device_memcpy(this%slag%lf(2)%x, this%slag%lf(2)%x_d, &
370 n, host_to_device, sync = .false.)
371 call device_memcpy(this%abx1%x, this%abx1%x_d, &
372 n, host_to_device, sync = .false.)
373 call device_memcpy(this%abx2%x, this%abx2%x_d, &
374 n, host_to_device, sync = .false.)
375 call device_memcpy(this%advs%x, this%advs%x_d, &
376 n, host_to_device, sync = .false.)
379 if (interpolated)
then
380 call this%gs_Xh%op(this%s, gs_op_add)
381 call this%gs_Xh%op(this%slag%lf(1), gs_op_add)
382 call this%gs_Xh%op(this%slag%lf(2), gs_op_add)
386 do i = 1, this%bcs%size()
387 bc_i => this%bcs%get(i)
388 call bc_i%restart(this%s, this%slag)
393 end subroutine scalar_pnpn_restart
395 subroutine scalar_pnpn_free(this)
396 class(scalar_pnpn_t),
intent(inout) :: this
399 if (
allocated(this%Ax))
then
405 call this%scheme_free()
407 call this%bc_projector%free()
408 call this%proj_s%free()
410 call this%s_res%free()
414 call this%abx1%free()
415 call this%abx2%free()
417 call this%advs%free()
419 if (
allocated(this%adv))
then
428 if (
allocated(this%res))
then
432 if (
allocated(this%makeext))
then
433 deallocate(this%makeext)
436 if (
allocated(this%makebdf))
then
437 deallocate(this%makebdf)
440 if (
allocated(this%makeoifs))
then
441 deallocate(this%makeoifs)
444 end subroutine scalar_pnpn_free
446 subroutine scalar_pnpn_step(this, time, ext_bdf, dt_controller, &
448 class(scalar_pnpn_t),
intent(inout) :: this
449 type(time_state_t),
intent(in) :: time
450 type(time_scheme_controller_t),
intent(in) :: ext_bdf
451 type(time_step_controller_t),
intent(in) :: dt_controller
452 type(ksp_monitor_t),
intent(inout) :: ksp_results
453 type(field_t),
pointer :: rho_cp
454 integer :: rho_cp_index
458 if (this%freeze)
return
460 n = this%dm_Xh%size()
461 call neko_scratch_registry%request_field(rho_cp, rho_cp_index, .false.)
463 call profiler_start_region(trim(this%name), 2)
464 associate(u => this%u, v => this%v, w => this%w, s => this%s, &
465 cp => this%cp, rho => this%rho, lambda_tot => this%lambda_tot, &
467 s_res => this%s_res, &
468 ax => this%Ax, f_xh => this%f_Xh, xh => this%Xh, &
469 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
470 slag => this%slag, oifs => this%oifs, &
471 projection_dim => this%projection_dim, &
472 msh => this%msh, res => this%res, makeoifs => this%makeoifs, &
473 makeext => this%makeext, makebdf => this%makebdf, &
474 t => time%t, tstep => time%tstep, dt => time%dt)
477 call print_debug(this)
480 call this%update_material_properties(time)
481 call field_col3(rho_cp, rho, cp, n)
484 if (this%svv_enabled)
then
485 call this%svv%update(rho_cp, tstep)
489 call this%source_term%compute(time, extrapolate = .true.)
495 call this%adv%compute_scalar(this%ulag%lf(1), this%vlag%lf(1), &
496 this%wlag%lf(1), s, this%advs, &
497 xh, this%c_Xh, dm_xh%size())
500 call this%adv%compute_scalar(u, v, w, s, f_xh, &
501 xh, this%c_Xh, dm_xh%size())
505 call field_col2(f_xh, rho_cp, n)
508 call this%bcs%apply_scalar(f_xh%x, n, time, .false.)
511 call makeext%compute_scalar(this%abx1, this%abx2, f_xh%x, &
512 ext_bdf%advection_coeffs%x, n)
515 call makeoifs%compute_scalar(this%advs%x, f_xh%x, &
516 rho_cp,
real(dt, kind=rp), n)
520 call makebdf%compute_scalar(slag, f_xh%x, s, c_xh%B, &
521 rho_cp,
real(dt, kind=rp), ext_bdf%diffusion_coeffs%x, &
528 call this%source_term%compute(time, extrapolate = .false., &
534 call this%apply_strong_bcs(time)
537 call profiler_start_region(trim(this%name) //
'_residual', 20)
538 call res%compute(ax, s, s_res, f_xh, c_xh, msh, xh, lambda_tot, &
539 rho_cp, ext_bdf%diffusion_coeffs%x(1), &
540 real(dt, kind=rp), dm_xh%size())
542 call gs_xh%op(s_res, gs_op_add)
545 call this%bc_projector%apply(s_res%x, dm_xh%size())
547 call profiler_end_region(trim(this%name) //
'_residual', 20)
549 call this%proj_s%pre_solving(s_res%x, tstep, c_xh, n, dt_controller)
551 call this%pc%update()
552 call profiler_start_region(trim(this%name) //
'_solve', 21)
553 ksp_results = this%ksp%solve(ax, ds, s_res%x, n, &
554 c_xh, this%bc_projector, gs_xh)
555 ksp_results%name = trim(this%name)
556 call profiler_end_region(trim(this%name) //
'_solve', 21)
558 call this%proj_s%post_solving(ds%x, ax, c_xh, this%bc_projector, gs_xh, &
559 n, tstep, dt_controller)
562 if (neko_bcknd_device .eq. 1)
then
563 call device_add2s2(s%x_d, ds%x_d, 1.0_rp, n)
565 call add2s2(s%x, ds%x, 1.0_rp, n)
569 call neko_scratch_registry%relinquish_field(rho_cp_index)
570 call profiler_end_region(trim(this%name), 2)
571 end subroutine scalar_pnpn_step
573 subroutine print_debug(this)
574 class(scalar_pnpn_t),
intent(inout) :: this
575 character(len=LOG_SIZE) :: log_buf
578 if (neko_log%level() .lt. neko_log_debug)
return
580 write(log_buf,
'(A, A, E15.7, A, E15.7, A, E15.7)')
'Scalar debug', &
581 ' l2norm s', field_glsc2(this%s, this%s), &
582 ' slag1', field_glsc2(this%slag%lf(1), this%slag%lf(1)), &
583 ' slag2', field_glsc2(this%slag%lf(2), this%slag%lf(2))
584 call neko_log%message(log_buf, lvl = neko_log_debug)
585 write(log_buf,
'(A, A, E15.7, A, E15.7)')
'Scalar debug2', &
586 ' l2norm abx1', field_glsc2(this%abx1, this%abx1), &
587 ' abx2', field_glsc2(this%abx2, this%abx2)
588 call neko_log%message(log_buf, lvl = neko_log_debug)
589 end subroutine print_debug
593 subroutine scalar_pnpn_setup_bcs_(this, user)
594 class(scalar_pnpn_t),
target,
intent(inout) :: this
595 type(user_t),
target,
intent(in) :: user
596 integer :: i, j, n_bcs, zone_size, global_zone_size, ierr
597 type(json_core) :: core
598 type(json_value),
pointer :: bc_object
599 type(json_file) :: bc_subdict
600 class(bc_t),
pointer :: bc_i
603 logical,
allocatable :: marked_zones(:)
604 integer,
allocatable :: zone_indices(:)
605 character(len=256) :: error_msg
607 if (this%params%valid_path(
'boundary_conditions'))
then
608 call this%params%info(
'boundary_conditions', &
610 call this%params%get_core(core)
611 call this%params%get(
'boundary_conditions', bc_object, found)
613 call this%bcs%init(n_bcs)
615 allocate(marked_zones(
size(this%msh%labeled_zones)))
616 marked_zones = .false.
620 call json_extract_item(core, bc_object, i, bc_subdict)
625 call json_get(bc_subdict,
"zone_indices", zone_indices)
627 do j = 1,
size(zone_indices)
628 zone_size = this%msh%labeled_zones(zone_indices(j))%size
629 call mpi_allreduce(zone_size, global_zone_size, 1, &
630 mpi_integer, mpi_max, neko_comm, ierr)
632 if (global_zone_size .eq. 0)
then
633 write(error_msg,
'(A, I0, A, A, I0, A)') &
634 "Zone index ", zone_indices(j), &
635 " is invalid as this zone has 0 size, meaning it ", &
636 "does not exist in the mesh. Check scalar boundary ", &
638 call neko_error(error_msg)
642 if (marked_zones(zone_indices(j)))
then
643 write(error_msg,
'(A, I0, A, A, A, A)')&
644 "Zone with index ", zone_indices(j), &
645 " has already been assigned a boundary condition. ", &
646 "Please check your boundary_conditions entry for the ", &
647 "scalar and make sure that each zone index appears only ",&
648 "in a single boundary condition."
649 call neko_error(error_msg)
652 marked_zones(zone_indices(j)) = .true.
658 call scalar_pnpn_bc_factory(bc_i, this, bc_subdict, this%c_Xh,
user)
659 call this%bcs%append(bc_i)
663 do i = 1,
size(this%msh%labeled_zones)
664 if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
665 (.not. marked_zones(i)))
then
666 write(error_msg,
'(A, I0)') &
667 "No scalar boundary condition assigned to zone ", i
668 call neko_error(error_msg)
674 do i = 1,
size(this%msh%labeled_zones)
675 if (this%msh%labeled_zones(i)%size .gt. 0)
then
676 write(error_msg,
'(A, A)') &
677 "No boundary_conditions entry in the case file for scalar ", &
679 call neko_error(error_msg)
689 end subroutine scalar_pnpn_setup_bcs_
693 subroutine scalar_scheme_apply_strong_bcs(this, time)
694 class(scalar_pnpn_t),
intent(inout) :: this
695 type(time_state_t),
intent(in) :: time
698 class(bc_t),
pointer :: bc_i
702 call this%bcs%apply(this%s, time = time, strong = .true.)
708 call this%gs_Xh%op(this%s, gs_op_min, glb_cmd_event)
709 call device_event_sync(glb_cmd_event)
713 call this%bcs%apply(this%s, time = time, strong = .true.)
716 call this%gs_Xh%op(this%s, gs_op_max, glb_cmd_event)
717 call device_event_sync(glb_cmd_event)
720 do i = 1, this%bcs%size()
721 bc_i => this%bcs%get(i)
722 bc_i%updated = .false.
726 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 .
real(kind=rp) function, public field_glsc2(a, b, n)
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
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_typename_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...