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_factory(this%ax, full_formulation = .false.)
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")
213 call neko_registry%add_field(dm_xh, trim(this%name)//
"_abx1", ignore_existing = .true.)
215 call this%abx2%init(dm_xh, trim(this%name)//
"_abx2")
216 call neko_registry%add_field(dm_xh, trim(this%name)//
"_abx2", ignore_existing = .true.)
218 call this%advs%init(dm_xh,
"advs")
220 call this%ds%init(dm_xh,
'ds')
225 call this%setup_bcs_(
user)
228 call this%bc_res%init(this%c_Xh, params)
229 do i = 1, this%bcs%size()
230 if (this%bcs%strong(i))
then
231 bc_i => this%bcs%get(i)
232 call this%bc_res%mark_facets(bc_i%marked_facet)
237 call this%bc_res%finalize()
239 call this%bclst_ds%init()
240 call this%bclst_ds%append(this%bc_res)
244 call this%proj_s%init(this%dm_Xh%size(), this%projection_dim, &
245 this%projection_activ_step)
254 call advection_factory(this%adv, numerics_params, this%c_Xh, &
255 ulag, vlag, wlag, this%chkp%dtlag, &
261 subroutine scalar_pnpn_restart(this, chkp)
262 class(scalar_pnpn_t),
target,
intent(inout) :: this
263 type(chkp_t),
intent(inout) :: chkp
264 real(kind=rp) :: dtlag(10), tlag(10)
266 type(field_t),
pointer :: temp_field
270 n = this%s%dof%size()
274 call col2(this%s%x, this%c_Xh%mult, n)
275 call col2(this%slag%lf(1)%x, this%c_Xh%mult, n)
276 call col2(this%slag%lf(2)%x, this%c_Xh%mult, n)
277 if (neko_bcknd_device .eq. 1)
then
278 call device_memcpy(this%s%x, this%s%x_d, &
279 n, host_to_device, sync = .false.)
280 call device_memcpy(this%slag%lf(1)%x, this%slag%lf(1)%x_d, &
281 n, host_to_device, sync = .false.)
282 call device_memcpy(this%slag%lf(2)%x, this%slag%lf(2)%x_d, &
283 n, host_to_device, sync = .false.)
284 call device_memcpy(this%abx1%x, this%abx1%x_d, &
285 n, host_to_device, sync = .false.)
286 call device_memcpy(this%abx2%x, this%abx2%x_d, &
287 n, host_to_device, sync = .false.)
288 call device_memcpy(this%advs%x, this%advs%x_d, &
289 n, host_to_device, sync = .false.)
292 call this%gs_Xh%op(this%s, gs_op_add)
293 call this%gs_Xh%op(this%slag%lf(1), gs_op_add)
294 call this%gs_Xh%op(this%slag%lf(2), gs_op_add)
344 subroutine scalar_pnpn_step(this, time, ext_bdf, dt_controller, &
346 class(scalar_pnpn_t),
intent(inout) :: this
347 type(time_state_t),
intent(in) :: time
348 type(time_scheme_controller_t),
intent(in) :: ext_bdf
349 type(time_step_controller_t),
intent(in) :: dt_controller
350 type(ksp_monitor_t),
intent(inout) :: ksp_results
354 if (this%freeze)
return
356 n = this%dm_Xh%size()
358 call profiler_start_region(trim(this%name), 2)
359 associate(u => this%u, v => this%v, w => this%w, s => this%s, &
360 cp => this%cp, rho => this%rho, lambda_tot => this%lambda_tot, &
362 s_res => this%s_res, &
363 ax => this%Ax, f_xh => this%f_Xh, xh => this%Xh, &
364 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
365 slag => this%slag, oifs => this%oifs, &
366 projection_dim => this%projection_dim, &
367 msh => this%msh, res => this%res, makeoifs => this%makeoifs, &
368 makeext => this%makeext, makebdf => this%makebdf, &
369 t => time%t, tstep => time%tstep, dt => time%dt)
372 call print_debug(this)
374 call this%source_term%compute(time)
377 call this%bcs%apply_scalar(this%f_Xh%x, dm_xh%size(), time, .false.)
381 call this%adv%compute_scalar(u, v, w, s, this%advs, &
382 xh, this%c_Xh, dm_xh%size())
384 call makeext%compute_scalar(this%abx1, this%abx2, f_xh%x, &
385 rho%x(1,1,1,1), ext_bdf%advection_coeffs, n)
387 call makeoifs%compute_scalar(this%advs%x, f_xh%x, rho%x(1,1,1,1), dt,&
391 call this%adv%compute_scalar(u, v, w, s, f_xh, &
392 xh, this%c_Xh, dm_xh%size())
398 call makeext%compute_scalar(this%abx1, this%abx2, f_xh%x, &
399 rho%x(1,1,1,1), ext_bdf%advection_coeffs, n)
402 call makebdf%compute_scalar(slag, f_xh%x, s, c_xh%B, rho%x(1,1,1,1), &
403 dt, ext_bdf%diffusion_coeffs, ext_bdf%ndiff, n)
409 call this%bcs%apply_scalar(this%s%x, this%dm_Xh%size(), time, .true.)
412 call this%update_material_properties(time)
415 call profiler_start_region(trim(this%name) //
'_residual', 20)
416 call res%compute(ax, s, s_res, f_xh, c_xh, msh, xh, lambda_tot, &
417 rho%x(1,1,1,1)*cp%x(1,1,1,1), ext_bdf%diffusion_coeffs(1), dt, &
420 call gs_xh%op(s_res, gs_op_add)
423 call this%bclst_ds%apply_scalar(s_res%x, dm_xh%size())
425 call profiler_end_region(trim(this%name) //
'_residual', 20)
427 call this%proj_s%pre_solving(s_res%x, tstep, c_xh, n, dt_controller)
429 call this%pc%update()
430 call profiler_start_region(trim(this%name) //
'_solve', 21)
431 ksp_results = this%ksp%solve(ax, ds, s_res%x, n, &
432 c_xh, this%bclst_ds, gs_xh)
433 ksp_results%name = trim(this%name)
434 call profiler_end_region(trim(this%name) //
'_solve', 21)
436 call this%proj_s%post_solving(ds%x, ax, c_xh, this%bclst_ds, gs_xh, &
437 n, tstep, dt_controller)
440 if (neko_bcknd_device .eq. 1)
then
441 call device_add2s2(s%x_d, ds%x_d, 1.0_rp, n)
443 call add2s2(s%x, ds%x, 1.0_rp, n)
447 call profiler_end_region(trim(this%name), 2)
470 subroutine scalar_pnpn_setup_bcs_(this, user)
471 class(scalar_pnpn_t),
intent(inout) :: this
472 type(user_t),
target,
intent(in) :: user
473 integer :: i, j, n_bcs, zone_size, global_zone_size, ierr
474 type(json_core) :: core
475 type(json_value),
pointer :: bc_object
476 type(json_file) :: bc_subdict
477 class(bc_t),
pointer :: bc_i
480 logical,
allocatable :: marked_zones(:)
481 integer,
allocatable :: zone_indices(:)
483 if (this%params%valid_path(
'boundary_conditions'))
then
484 call this%params%info(
'boundary_conditions', &
486 call this%params%get_core(core)
487 call this%params%get(
'boundary_conditions', bc_object, found)
489 call this%bcs%init(n_bcs)
491 allocate(marked_zones(
size(this%msh%labeled_zones)))
492 marked_zones = .false.
496 call json_extract_item(core, bc_object, i, bc_subdict)
501 call json_get(bc_subdict,
"zone_indices", zone_indices)
503 do j = 1,
size(zone_indices)
504 zone_size = this%msh%labeled_zones(zone_indices(j))%size
505 call mpi_allreduce(zone_size, global_zone_size, 1, &
506 mpi_integer, mpi_max, neko_comm, ierr)
508 if (global_zone_size .eq. 0)
then
509 write(error_unit,
'(A, A, I0, A, A, I0, A)')
"*** ERROR ***: ",&
510 "Zone index ", zone_indices(j), &
511 " is invalid as this zone has 0 size, meaning it ", &
512 "does not exist in the mesh. Check scalar boundary condition ", &
517 if (marked_zones(zone_indices(j)) .eqv. .true.)
then
518 write(error_unit,
'(A, A, I0, A, A, A, A)')
"*** ERROR ***: ", &
519 "Zone with index ", zone_indices(j), &
520 " has already been assigned a boundary condition. ", &
521 "Please check your boundary_conditions entry for the ", &
522 "scalar and make sure that each zone index appears only ",&
523 "in a single boundary condition."
526 marked_zones(zone_indices(j)) = .true.
532 call bc_factory(bc_i, this, bc_subdict, this%c_Xh,
user)
533 call this%bcs%append(bc_i)
537 do i = 1,
size(this%msh%labeled_zones)
538 if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
539 (marked_zones(i) .eqv. .false.))
then
540 write(error_unit,
'(A, A, I0)')
"*** ERROR ***: ", &
541 "No scalar boundary condition assigned to zone ", i
547 do i = 1,
size(this%msh%labeled_zones)
548 if (this%msh%labeled_zones(i)%size .gt. 0)
then
549 write(error_unit,
'(A, A, A)')
"*** ERROR ***: ", &
550 "No boundary_conditions entry in the case file for scalar ", &