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
71 use mpi_f08,
only : mpi_allreduce, mpi_integer, mpi_max
85 class(
ax_t),
allocatable :: ax
145 module subroutine bc_factory(object, scheme, json, coef,
user)
146 class(
bc_t),
pointer,
intent(inout) :: object
147 type(scalar_pnpn_t),
intent(in) :: scheme
148 type(json_file),
intent(inout) :: json
149 type(
coef_t),
target,
intent(in) :: coef
151 end subroutine bc_factory
168 subroutine scalar_pnpn_init(this, msh, coef, gs, params, numerics_params, &
169 user, chkp, ulag, vlag, wlag, time_scheme, rho)
170 class(scalar_pnpn_t),
target,
intent(inout) :: this
171 type(
mesh_t),
target,
intent(in) :: msh
172 type(
coef_t),
target,
intent(in) :: coef
173 type(
gs_t),
target,
intent(inout) :: gs
174 type(json_file),
target,
intent(inout) :: params
175 type(json_file),
target,
intent(inout) :: numerics_params
176 type(
user_t),
target,
intent(in) :: user
177 type(
chkp_t),
target,
intent(inout) :: chkp
180 type(
field_t),
target,
intent(in) :: rho
182 class(
bc_t),
pointer :: bc_i
183 character(len=15),
parameter :: scheme =
'Modular (Pn/Pn)'
189 call this%scheme_init(msh, coef, gs, params, scheme,
user, rho)
192 call ax_helm_allocator(this%ax, type_name =
"standard")
195 call scalar_residual_factory(this%res)
198 call rhs_maker_ext_fctry(this%makeext)
201 call rhs_maker_bdf_fctry(this%makebdf)
204 call rhs_maker_oifs_fctry(this%makeoifs)
207 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
208 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
210 call this%s_res%init(dm_xh,
"s_res")
212 call this%abx1%init(dm_xh, trim(this%name) //
"_abx1")
214 call this%abx2%init(dm_xh, trim(this%name) //
"_abx2")
216 call this%advs%init(dm_xh,
"advs")
218 call this%ds%init(dm_xh,
'ds')
223 call this%setup_bcs_(
user)
225 do i = 1, this%bcs%size()
227 bc_i => this%bcs%get(i)
228 call this%bc_projector%mark(bc_i)
233 call this%proj_s%init(this%dm_Xh%size(), this%projection_dim, &
234 this%projection_activ_step)
250 call advection_factory(this%adv, numerics_params, this%c_Xh, &
251 ulag, vlag, wlag, this%chkp%dtlag, &
254 end subroutine scalar_pnpn_init
257 subroutine scalar_pnpn_restart(this, chkp)
258 class(scalar_pnpn_t),
target,
intent(inout) :: this
259 type(chkp_t),
intent(inout) :: chkp
260 real(kind=rp) :: dtlag(10), tlag(10)
262 type(field_t),
pointer :: temp_field
266 n = this%s%dof%size()
270 call col2(this%s%x, this%c_Xh%mult, n)
271 call col2(this%slag%lf(1)%x, this%c_Xh%mult, n)
272 call col2(this%slag%lf(2)%x, this%c_Xh%mult, n)
273 if (neko_bcknd_device .eq. 1)
then
274 call device_memcpy(this%s%x, this%s%x_d, &
275 n, host_to_device, sync = .false.)
276 call device_memcpy(this%slag%lf(1)%x, this%slag%lf(1)%x_d, &
277 n, host_to_device, sync = .false.)
278 call device_memcpy(this%slag%lf(2)%x, this%slag%lf(2)%x_d, &
279 n, host_to_device, sync = .false.)
280 call device_memcpy(this%abx1%x, this%abx1%x_d, &
281 n, host_to_device, sync = .false.)
282 call device_memcpy(this%abx2%x, this%abx2%x_d, &
283 n, host_to_device, sync = .false.)
284 call device_memcpy(this%advs%x, this%advs%x_d, &
285 n, host_to_device, sync = .false.)
288 call this%gs_Xh%op(this%s, gs_op_add)
289 call this%gs_Xh%op(this%slag%lf(1), gs_op_add)
290 call this%gs_Xh%op(this%slag%lf(2), gs_op_add)
292 end subroutine scalar_pnpn_restart
294 subroutine scalar_pnpn_free(this)
295 class(scalar_pnpn_t),
intent(inout) :: this
298 call this%scheme_free()
300 call this%bc_projector%free()
301 call this%proj_s%free()
303 call this%s_res%free()
307 call this%abx1%free()
308 call this%abx2%free()
310 call this%advs%free()
312 if (
allocated(this%adv))
then
321 if (
allocated(this%Ax))
then
325 if (
allocated(this%res))
then
329 if (
allocated(this%makeext))
then
330 deallocate(this%makeext)
333 if (
allocated(this%makebdf))
then
334 deallocate(this%makebdf)
337 if (
allocated(this%makeoifs))
then
338 deallocate(this%makeoifs)
341 end subroutine scalar_pnpn_free
343 subroutine scalar_pnpn_step(this, time, ext_bdf, dt_controller, &
345 class(scalar_pnpn_t),
intent(inout) :: this
346 type(time_state_t),
intent(in) :: time
347 type(time_scheme_controller_t),
intent(in) :: ext_bdf
348 type(time_step_controller_t),
intent(in) :: dt_controller
349 type(ksp_monitor_t),
intent(inout) :: ksp_results
350 type(field_t),
pointer :: rho_cp
351 integer :: rho_cp_index
355 if (this%freeze)
return
357 n = this%dm_Xh%size()
358 call neko_scratch_registry%request_field(rho_cp, rho_cp_index, .false.)
360 call profiler_start_region(trim(this%name), 2)
361 associate(u => this%u, v => this%v, w => this%w, s => this%s, &
362 cp => this%cp, rho => this%rho, lambda_tot => this%lambda_tot, &
364 s_res => this%s_res, &
365 ax => this%Ax, f_xh => this%f_Xh, xh => this%Xh, &
366 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
367 slag => this%slag, oifs => this%oifs, &
368 projection_dim => this%projection_dim, &
369 msh => this%msh, res => this%res, makeoifs => this%makeoifs, &
370 makeext => this%makeext, makebdf => this%makebdf, &
371 t => time%t, tstep => time%tstep, dt => time%dt)
374 call print_debug(this)
377 call this%update_material_properties(time)
378 call field_col3(rho_cp, rho, cp, n)
381 call this%source_term%compute(time)
387 call this%adv%compute_scalar(this%ulag%lf(1), this%vlag%lf(1), &
388 this%wlag%lf(1), 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, &
408 rho_cp,
real(dt, kind=rp), n)
412 call makebdf%compute_scalar(slag, f_xh%x, s, c_xh%B, &
413 rho_cp,
real(dt, kind=rp), ext_bdf%diffusion_coeffs%x, &
420 call this%apply_strong_bcs(time)
423 call profiler_start_region(trim(this%name) //
'_residual', 20)
424 call res%compute(ax, s, s_res, f_xh, c_xh, msh, xh, lambda_tot, &
425 rho_cp, ext_bdf%diffusion_coeffs%x(1), &
426 real(dt, kind=rp), dm_xh%size())
428 call gs_xh%op(s_res, gs_op_add)
431 call this%bc_projector%apply(s_res%x, dm_xh%size())
433 call profiler_end_region(trim(this%name) //
'_residual', 20)
435 call this%proj_s%pre_solving(s_res%x, tstep, c_xh, n, dt_controller)
437 call this%pc%update()
438 call profiler_start_region(trim(this%name) //
'_solve', 21)
439 ksp_results = this%ksp%solve(ax, ds, s_res%x, n, &
440 c_xh, this%bc_projector, gs_xh)
441 ksp_results%name = trim(this%name)
442 call profiler_end_region(trim(this%name) //
'_solve', 21)
444 call this%proj_s%post_solving(ds%x, ax, c_xh, this%bc_projector, gs_xh, &
445 n, tstep, dt_controller)
448 if (neko_bcknd_device .eq. 1)
then
449 call device_add2s2(s%x_d, ds%x_d, 1.0_rp, n)
451 call add2s2(s%x, ds%x, 1.0_rp, n)
455 call neko_scratch_registry%relinquish_field(rho_cp_index)
456 call profiler_end_region(trim(this%name), 2)
457 end subroutine scalar_pnpn_step
459 subroutine print_debug(this)
460 class(scalar_pnpn_t),
intent(inout) :: this
461 character(len=LOG_SIZE) :: log_buf
464 n = this%dm_Xh%size()
466 write(log_buf,
'(A, A, E15.7, A, E15.7, A, E15.7)')
'Scalar debug', &
467 ' l2norm s', glsc2(this%s%x, this%s%x, n), &
468 ' slag1', glsc2(this%slag%lf(1)%x, this%slag%lf(1)%x, n), &
469 ' slag2', glsc2(this%slag%lf(2)%x, this%slag%lf(2)%x, n)
470 call neko_log%message(log_buf, lvl = neko_log_debug)
471 write(log_buf,
'(A, A, E15.7, A, E15.7)')
'Scalar debug2', &
472 ' l2norm abx1', glsc2(this%abx1%x, this%abx1%x, n), &
473 ' abx2', glsc2(this%abx2%x, this%abx2%x, n)
474 call neko_log%message(log_buf, lvl = neko_log_debug)
475 end subroutine print_debug
479 subroutine scalar_pnpn_setup_bcs_(this, user)
480 class(scalar_pnpn_t),
target,
intent(inout) :: this
481 type(user_t),
target,
intent(in) :: user
482 integer :: i, j, n_bcs, zone_size, global_zone_size, ierr
483 type(json_core) :: core
484 type(json_value),
pointer :: bc_object
485 type(json_file) :: bc_subdict
486 class(bc_t),
pointer :: bc_i
489 logical,
allocatable :: marked_zones(:)
490 integer,
allocatable :: zone_indices(:)
492 if (this%params%valid_path(
'boundary_conditions'))
then
493 call this%params%info(
'boundary_conditions', &
495 call this%params%get_core(core)
496 call this%params%get(
'boundary_conditions', bc_object, found)
498 call this%bcs%init(n_bcs)
500 allocate(marked_zones(
size(this%msh%labeled_zones)))
501 marked_zones = .false.
505 call json_extract_item(core, bc_object, i, bc_subdict)
510 call json_get(bc_subdict,
"zone_indices", zone_indices)
512 do j = 1,
size(zone_indices)
513 zone_size = this%msh%labeled_zones(zone_indices(j))%size
514 call mpi_allreduce(zone_size, global_zone_size, 1, &
515 mpi_integer, mpi_max, neko_comm, ierr)
517 if (global_zone_size .eq. 0)
then
518 write(error_unit,
'(A, A, I0, A, A, I0, A)') &
519 "*** ERROR ***: ",
"Zone index ", zone_indices(j), &
520 " is invalid as this zone has 0 size, meaning it ", &
521 "does not exist in the mesh. Check scalar boundary ", &
526 if (marked_zones(zone_indices(j)))
then
527 write(error_unit,
'(A, A, I0, A, A, A, A)')
"*** ERROR ***: ", &
528 "Zone with index ", zone_indices(j), &
529 " has already been assigned a boundary condition. ", &
530 "Please check your boundary_conditions entry for the ", &
531 "scalar and make sure that each zone index appears only ",&
532 "in a single boundary condition."
535 marked_zones(zone_indices(j)) = .true.
541 call bc_factory(bc_i, this, bc_subdict, this%c_Xh,
user)
542 call this%bcs%append(bc_i)
546 do i = 1,
size(this%msh%labeled_zones)
547 if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
548 (.not. marked_zones(i)))
then
549 write(error_unit,
'(A, A, I0)')
"*** ERROR ***: ", &
550 "No scalar boundary condition assigned to zone ", i
556 do i = 1,
size(this%msh%labeled_zones)
557 if (this%msh%labeled_zones(i)%size .gt. 0)
then
558 write(error_unit,
'(A, A, A)')
"*** ERROR ***: ", &
559 "No boundary_conditions entry in the case file for scalar ", &
570 end subroutine scalar_pnpn_setup_bcs_
574 subroutine scalar_scheme_apply_strong_bcs(this, time)
575 class(scalar_pnpn_t),
intent(inout) :: this
576 type(time_state_t),
intent(in) :: time
579 class(bc_t),
pointer :: bc_i
583 call this%bcs%apply(this%s, time = time, strong = .true.)
589 call this%gs_Xh%op(this%s, gs_op_min, glb_cmd_event)
590 call device_event_sync(glb_cmd_event)
594 call this%bcs%apply(this%s, time = time, strong = .true.)
597 call this%gs_Xh%op(this%s, gs_op_max, glb_cmd_event)
598 call device_event_sync(glb_cmd_event)
601 do i = 1, this%bcs%size()
602 bc_i => this%bcs%get(i)
603 bc_i%updated = .false.
607 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.
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_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 ...
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_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.
Base abstract type for computing the advection operator.
Base type for a matrix-vector product providing .
Base type for a boundary condition.
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...