37 use,
intrinsic :: iso_fortran_env, only : error_unit
39 rhs_maker_ext_fctry, rhs_maker_bdf_fctry, rhs_maker_oifs_fctry
64 use json_module,
only : json_file, json_core, json_value
72 use mpi_f08,
only : mpi_allreduce, mpi_integer, mpi_max
86 class(
ax_t),
allocatable :: ax
149 module subroutine bc_factory(object, scheme, json, coef,
user)
150 class(
bc_t),
pointer,
intent(inout) :: object
151 type(scalar_pnpn_t),
intent(in) :: scheme
152 type(json_file),
intent(inout) :: json
153 type(
coef_t),
target,
intent(in) :: coef
155 end subroutine bc_factory
172 subroutine scalar_pnpn_init(this, msh, coef, gs, params, numerics_params, &
173 user, chkp, ulag, vlag, wlag, time_scheme, rho)
174 class(scalar_pnpn_t),
target,
intent(inout) :: this
175 type(
mesh_t),
target,
intent(in) :: msh
176 type(
coef_t),
target,
intent(in) :: coef
177 type(
gs_t),
target,
intent(inout) :: gs
178 type(json_file),
target,
intent(inout) :: params
179 type(json_file),
target,
intent(inout) :: numerics_params
180 type(
user_t),
target,
intent(in) :: user
181 type(
chkp_t),
target,
intent(inout) :: chkp
184 type(
field_t),
target,
intent(in) :: rho
186 class(
bc_t),
pointer :: bc_i
187 character(len=15),
parameter :: scheme =
'Modular (Pn/Pn)'
193 call this%scheme_init(msh, coef, gs, params, scheme,
user, rho)
196 call ax_helm_factory(this%ax, full_formulation = .false.)
199 call scalar_residual_factory(this%res)
202 call rhs_maker_ext_fctry(this%makeext)
205 call rhs_maker_bdf_fctry(this%makebdf)
208 call rhs_maker_oifs_fctry(this%makeoifs)
211 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
212 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
214 call this%s_res%init(dm_xh,
"s_res")
216 call this%abx1%init(dm_xh, trim(this%name) //
"_abx1")
218 call this%abx2%init(dm_xh, trim(this%name) //
"_abx2")
220 call this%advs%init(dm_xh,
"advs")
222 call this%ds%init(dm_xh,
'ds')
227 call this%setup_bcs_(
user)
230 call this%bc_res%init(this%c_Xh, params)
231 do i = 1, this%bcs%size()
232 if (this%bcs%strong(i))
then
233 bc_i => this%bcs%get(i)
234 call this%bc_res%mark_facets(bc_i%marked_facet)
239 call this%bc_res%finalize()
241 call this%bclst_ds%init()
242 call this%bclst_ds%append(this%bc_res)
246 call this%proj_s%init(this%dm_Xh%size(), this%projection_dim, &
247 this%projection_activ_step)
256 call advection_factory(this%adv, numerics_params, this%c_Xh, &
257 ulag, vlag, wlag, this%chkp%dtlag, &
260 end subroutine scalar_pnpn_init
263 subroutine scalar_pnpn_restart(this, chkp)
264 class(scalar_pnpn_t),
target,
intent(inout) :: this
265 type(chkp_t),
intent(inout) :: chkp
266 real(kind=rp) :: dtlag(10), tlag(10)
268 type(field_t),
pointer :: temp_field
272 n = this%s%dof%size()
276 call col2(this%s%x, this%c_Xh%mult, n)
277 call col2(this%slag%lf(1)%x, this%c_Xh%mult, n)
278 call col2(this%slag%lf(2)%x, this%c_Xh%mult, n)
279 if (neko_bcknd_device .eq. 1)
then
280 call device_memcpy(this%s%x, this%s%x_d, &
281 n, host_to_device, sync = .false.)
282 call device_memcpy(this%slag%lf(1)%x, this%slag%lf(1)%x_d, &
283 n, host_to_device, sync = .false.)
284 call device_memcpy(this%slag%lf(2)%x, this%slag%lf(2)%x_d, &
285 n, host_to_device, sync = .false.)
286 call device_memcpy(this%abx1%x, this%abx1%x_d, &
287 n, host_to_device, sync = .false.)
288 call device_memcpy(this%abx2%x, this%abx2%x_d, &
289 n, host_to_device, sync = .false.)
290 call device_memcpy(this%advs%x, this%advs%x_d, &
291 n, host_to_device, sync = .false.)
294 call this%gs_Xh%op(this%s, gs_op_add)
295 call this%gs_Xh%op(this%slag%lf(1), gs_op_add)
296 call this%gs_Xh%op(this%slag%lf(2), gs_op_add)
298 end subroutine scalar_pnpn_restart
300 subroutine scalar_pnpn_free(this)
301 class(scalar_pnpn_t),
intent(inout) :: this
304 call this%scheme_free()
306 call this%bc_res%free()
307 call this%bclst_ds%free()
308 call this%proj_s%free()
310 call this%s_res%free()
314 call this%abx1%free()
315 call this%abx2%free()
317 call this%advs%free()
319 if (
allocated(this%adv))
then
324 if (
allocated(this%Ax))
then
328 if (
allocated(this%res))
then
332 if (
allocated(this%makeext))
then
333 deallocate(this%makeext)
336 if (
allocated(this%makebdf))
then
337 deallocate(this%makebdf)
340 if (
allocated(this%makeoifs))
then
341 deallocate(this%makeoifs)
344 end subroutine scalar_pnpn_free
346 subroutine scalar_pnpn_step(this, time, ext_bdf, dt_controller, &
348 class(scalar_pnpn_t),
intent(inout) :: this
349 type(time_state_t),
intent(in) :: time
350 type(time_scheme_controller_t),
intent(in) :: ext_bdf
351 type(time_step_controller_t),
intent(in) :: dt_controller
352 type(ksp_monitor_t),
intent(inout) :: ksp_results
353 type(field_t),
pointer :: rho_cp
354 integer :: rho_cp_index
358 if (this%freeze)
return
360 n = this%dm_Xh%size()
361 call neko_scratch_registry%request_field(rho_cp, rho_cp_index, .false.)
363 call profiler_start_region(trim(this%name), 2)
364 associate(u => this%u, v => this%v, w => this%w, s => this%s, &
365 cp => this%cp, rho => this%rho, lambda_tot => this%lambda_tot, &
367 s_res => this%s_res, &
368 ax => this%Ax, f_xh => this%f_Xh, xh => this%Xh, &
369 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
370 slag => this%slag, oifs => this%oifs, &
371 projection_dim => this%projection_dim, &
372 msh => this%msh, res => this%res, makeoifs => this%makeoifs, &
373 makeext => this%makeext, makebdf => this%makebdf, &
374 t => time%t, tstep => time%tstep, dt => time%dt)
377 call print_debug(this)
380 call this%update_material_properties(time)
381 call field_col3(rho_cp, rho, cp, n)
384 call this%source_term%compute(time)
388 call this%adv%compute_scalar(u, v, w, s, this%advs, &
389 xh, this%c_Xh, dm_xh%size())
392 call this%adv%compute_scalar(u, v, w, s, f_xh, &
393 xh, this%c_Xh, dm_xh%size())
397 call field_col2(f_xh, rho_cp, n)
400 call this%bcs%apply_scalar(f_xh%x, n, time, .false.)
403 call makeext%compute_scalar(this%abx1, this%abx2, f_xh%x, &
404 ext_bdf%advection_coeffs%x, n)
407 call makeoifs%compute_scalar(this%advs%x, f_xh%x, &
412 call makebdf%compute_scalar(slag, f_xh%x, s, c_xh%B, &
413 rho_cp, dt, ext_bdf%diffusion_coeffs%x, ext_bdf%ndiff, n)
419 call this%apply_strong_bcs(time)
422 call profiler_start_region(trim(this%name) //
'_residual', 20)
423 call res%compute(ax, s, s_res, f_xh, c_xh, msh, xh, lambda_tot, &
424 rho_cp, ext_bdf%diffusion_coeffs%x(1), dt, &
427 call gs_xh%op(s_res, gs_op_add)
430 call this%bclst_ds%apply_scalar(s_res%x, dm_xh%size())
432 call profiler_end_region(trim(this%name) //
'_residual', 20)
434 call this%proj_s%pre_solving(s_res%x, tstep, c_xh, n, dt_controller)
436 call this%pc%update()
437 call profiler_start_region(trim(this%name) //
'_solve', 21)
438 ksp_results = this%ksp%solve(ax, ds, s_res%x, n, &
439 c_xh, this%bclst_ds, gs_xh)
440 ksp_results%name = trim(this%name)
441 call profiler_end_region(trim(this%name) //
'_solve', 21)
443 call this%proj_s%post_solving(ds%x, ax, c_xh, this%bclst_ds, gs_xh, &
444 n, tstep, dt_controller)
447 if (neko_bcknd_device .eq. 1)
then
448 call device_add2s2(s%x_d, ds%x_d, 1.0_rp, n)
450 call add2s2(s%x, ds%x, 1.0_rp, n)
454 call neko_scratch_registry%relinquish_field(rho_cp_index)
455 call profiler_end_region(trim(this%name), 2)
456 end subroutine scalar_pnpn_step
458 subroutine print_debug(this)
459 class(scalar_pnpn_t),
intent(inout) :: this
460 character(len=LOG_SIZE) :: log_buf
463 n = this%dm_Xh%size()
465 write(log_buf,
'(A, A, E15.7, A, E15.7, A, E15.7)')
'Scalar debug', &
466 ' l2norm s', glsc2(this%s%x, this%s%x, n), &
467 ' slag1', glsc2(this%slag%lf(1)%x, this%slag%lf(1)%x, n), &
468 ' slag2', glsc2(this%slag%lf(2)%x, this%slag%lf(2)%x, n)
469 call neko_log%message(log_buf, lvl = neko_log_debug)
470 write(log_buf,
'(A, A, E15.7, A, E15.7)')
'Scalar debug2', &
471 ' l2norm abx1', glsc2(this%abx1%x, this%abx1%x, n), &
472 ' abx2', glsc2(this%abx2%x, this%abx2%x, n)
473 call neko_log%message(log_buf, lvl = neko_log_debug)
474 end subroutine print_debug
478 subroutine scalar_pnpn_setup_bcs_(this, user)
479 class(scalar_pnpn_t),
target,
intent(inout) :: this
480 type(user_t),
target,
intent(in) :: user
481 integer :: i, j, n_bcs, zone_size, global_zone_size, ierr
482 type(json_core) :: core
483 type(json_value),
pointer :: bc_object
484 type(json_file) :: bc_subdict
485 class(bc_t),
pointer :: bc_i
488 logical,
allocatable :: marked_zones(:)
489 integer,
allocatable :: zone_indices(:)
491 if (this%params%valid_path(
'boundary_conditions'))
then
492 call this%params%info(
'boundary_conditions', &
494 call this%params%get_core(core)
495 call this%params%get(
'boundary_conditions', bc_object, found)
497 call this%bcs%init(n_bcs)
499 allocate(marked_zones(
size(this%msh%labeled_zones)))
500 marked_zones = .false.
504 call json_extract_item(core, bc_object, i, bc_subdict)
509 call json_get(bc_subdict,
"zone_indices", zone_indices)
511 do j = 1,
size(zone_indices)
512 zone_size = this%msh%labeled_zones(zone_indices(j))%size
513 call mpi_allreduce(zone_size, global_zone_size, 1, &
514 mpi_integer, mpi_max, neko_comm, ierr)
516 if (global_zone_size .eq. 0)
then
517 write(error_unit,
'(A, A, I0, A, A, I0, A)') &
518 "*** ERROR ***: ",
"Zone index ", zone_indices(j), &
519 " is invalid as this zone has 0 size, meaning it ", &
520 "does not exist in the mesh. Check scalar boundary ", &
525 if (marked_zones(zone_indices(j)))
then
526 write(error_unit,
'(A, A, I0, A, A, A, A)')
"*** ERROR ***: ", &
527 "Zone with index ", zone_indices(j), &
528 " has already been assigned a boundary condition. ", &
529 "Please check your boundary_conditions entry for the ", &
530 "scalar and make sure that each zone index appears only ",&
531 "in a single boundary condition."
534 marked_zones(zone_indices(j)) = .true.
540 call bc_factory(bc_i, this, bc_subdict, this%c_Xh,
user)
541 call this%bcs%append(bc_i)
545 do i = 1,
size(this%msh%labeled_zones)
546 if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
547 (.not. marked_zones(i)))
then
548 write(error_unit,
'(A, A, I0)')
"*** ERROR ***: ", &
549 "No scalar boundary condition assigned to zone ", i
555 do i = 1,
size(this%msh%labeled_zones)
556 if (this%msh%labeled_zones(i)%size .gt. 0)
then
557 write(error_unit,
'(A, A, A)')
"*** ERROR ***: ", &
558 "No boundary_conditions entry in the case file for scalar ", &
569 end subroutine scalar_pnpn_setup_bcs_
573 subroutine scalar_scheme_apply_strong_bcs(this, time)
574 class(scalar_pnpn_t),
intent(inout) :: this
575 type(time_state_t),
intent(in) :: time
578 class(bc_t),
pointer :: bc_i
582 call this%bcs%apply(this%s, time = time, strong = .true.)
588 call this%gs_Xh%op(this%s, gs_op_min, glb_cmd_event)
589 call device_event_sync(glb_cmd_event)
593 call this%bcs%apply(this%s, time = time, strong = .true.)
596 call this%gs_Xh%op(this%s, gs_op_max, glb_cmd_event)
597 call device_event_sync(glb_cmd_event)
600 do i = 1, this%bcs%size()
601 bc_i => this%bcs%get(i)
602 bc_i%updated = .false.
606 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.
Defines a Matrix-vector product.
Defines a boundary condition.
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 log level.
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 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 ...
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_init(this, msh, coef, gs, params, numerics_params, user, chkp, ulag, vlag, wlag, time_scheme, rho)
Boundary condition factory. Both constructs and initializes the object.
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.
Defines a zero-valued Dirichlet boundary condition.
Base abstract type for computing the advection operator.
Base type for a matrix-vector product providing .
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,...
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.
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...
Zero-valued Dirichlet boundary condition. Used for no-slip walls, but also for various auxillary cond...