Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
scalar_pnpn.f90
Go to the documentation of this file.
1! Copyright (c) 2022-2026, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
34
36 use num_types, only : rp, dp
38 rhs_maker_ext_fctry, rhs_maker_bdf_fctry, rhs_maker_oifs_fctry
41 use checkpoint, only : chkp_t
42 use field, only : field_t
44 use mesh, only : mesh_t
45 use coefs, only : coef_t
48 use gather_scatter, only : gs_t, gs_op_add, gs_op_min, gs_op_max
49 use scalar_residual, only : scalar_residual_t, scalar_residual_factory
50 use ax_product, only : ax_t, ax_helm_allocator
51 use ax_helm_svv, only : ax_helm_svv_t
54 use krylov, only : ksp_monitor_t
57 use projection, only : projection_t
58 use math, only : glsc2, col2, add2s2
62 use advection, only : advection_t, advection_factory
65 use json_module, only : json_file, json_core, json_value
66 use user_intf, only : user_t
69 use time_state, only : time_state_t
70 use utils, only : neko_error
71 use bc, only : bc_t, bc_dirichlet
72 use utils, only : neko_varname_len
73 use comm, only : neko_comm
74 use mpi_f08, only : mpi_allreduce, mpi_integer, mpi_max
75 implicit none
76 private
77
78
79 type, public, extends(scalar_scheme_t) :: scalar_pnpn_t
80
82 type(field_t) :: s_res
83
85 type(field_t) :: ds
86
88 class(ax_t), allocatable :: ax
89
91 type(projection_t) :: proj_s
92
94 type(scalar_bc_projector_t) :: bc_projector
95
97 class(advection_t), allocatable :: adv
98
99 ! Time interpolation scheme
100 logical :: oifs
101
102 ! Advection terms for the oifs method
103 type(field_t) :: advs
104
106 class(scalar_residual_t), allocatable :: res
107
109 class(rhs_maker_ext_t), allocatable :: makeext
110
112 class(rhs_maker_bdf_t), allocatable :: makebdf
113
115 class(rhs_maker_oifs_t), allocatable :: makeoifs
116
118 type(field_t) :: abx1, abx2
119
121 type(field_series_t), pointer :: ulag => null()
122 type(field_series_t), pointer :: vlag => null()
123 type(field_series_t), pointer :: wlag => null()
124
125 contains
127 procedure, pass(this) :: init => scalar_pnpn_init
129 procedure, pass(this) :: restart => scalar_pnpn_restart
131 procedure, pass(this) :: register_checkpoint => &
134 procedure, pass(this) :: free => scalar_pnpn_free
136 procedure, pass(this) :: step => scalar_pnpn_step
138 procedure, pass(this) :: apply_strong_bcs => scalar_scheme_apply_strong_bcs
140 procedure, pass(this) :: setup_bcs_ => scalar_pnpn_setup_bcs_
141 end type scalar_pnpn_t
142
143 interface
144
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
156 type(user_t), intent(in) :: user
157 end subroutine scalar_pnpn_bc_factory
158 end interface
159
160 interface
161
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
168 end interface
169
170 !
171 ! Machinery for injecting user-defined types
172 !
173
177 abstract interface
178 subroutine scalar_pnpn_bc_allocate(obj)
179 import bc_t
180 class(bc_t), pointer, intent(inout) :: obj
181 end subroutine scalar_pnpn_bc_allocate
182 end interface
183
184 interface
185
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
192 end interface
193
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
199
201 type(scalar_pnpn_bc_allocator_entry), allocatable, private :: &
202 scalar_pnpn_bc_registry(:)
203
205 integer, private :: scalar_pnpn_bc_registry_size = 0
206
207 public :: scalar_pnpn_bc_allocator, scalar_pnpn_bc_allocate, &
208 register_scalar_pnpn_bc
209
210contains
211
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
234 type(field_series_t), target, intent(in) :: ulag, vlag, wlag
235 type(time_scheme_controller_t), target, intent(in) :: time_scheme
236 type(field_t), target, intent(in) :: rho
237 integer :: i
238 class(bc_t), pointer :: bc_i
239 character(len=15), parameter :: scheme = 'Modular (Pn/Pn)'
240 logical :: advection
241 real(kind=dp), pointer :: tlag(:), dtlag(:)
242
243 call this%free()
244
245 ! Initiliaze base type.
246 call this%scheme_init(msh, coef, gs, params, scheme, user, rho)
247
248 ! Setup backend dependent Ax routines
249 if (this%svv_enabled) then
250 call ax_helm_allocator(this%ax, type_name = "standard_svv")
251 select type (operator => this%ax)
252 class is (ax_helm_svv_t)
253 operator%svv => this%svv
254 end select
255 else
256 call ax_helm_allocator(this%ax, type_name = "standard")
257 end if
258
259 ! Setup backend dependent scalar residual routines
260 call scalar_residual_factory(this%res)
261
262 ! Setup backend dependent summation of extrapolation scheme
263 call rhs_maker_ext_fctry(this%makeext)
264
265 ! Setup backend dependent contributions to F from lagged BD terms
266 call rhs_maker_bdf_fctry(this%makebdf)
267
268 ! Setup backend dependent contributions of the OIFS scheme
269 call rhs_maker_oifs_fctry(this%makeoifs)
270
271 ! Initialize variables specific to this plan
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)
274
275 call this%s_res%init(dm_xh, "s_res")
276
277 call this%abx1%init(dm_xh, trim(this%name) // "_abx1")
278
279 call this%abx2%init(dm_xh, trim(this%name) // "_abx2")
280
281 call this%advs%init(dm_xh, "advs")
282
283 call this%ds%init(dm_xh, 'ds')
284
285 end associate
286
287 ! Set up boundary conditions
288 call this%setup_bcs_(user)
289
290 do i = 1, this%bcs%size()
291 if (this%bcs%bc_type(i) .eq. bc_dirichlet) then
292 bc_i => this%bcs%get(i)
293 call this%bc_projector%mark(bc_i)
294 end if
295 end do
296
297 ! Initialize projection space
298 call this%proj_s%init(this%dm_Xh%size(), this%projection_dim, &
299 this%projection_activ_step)
300
301 ! Determine the time-interpolation scheme
302 call json_get_or_default(numerics_params, 'oifs', this%oifs, .false.)
303 ! Point to case checkpoint
304 this%chkp => chkp
305 ! Initialize advection factory
306 call json_get_or_default(params, 'advection', advection, .true.)
307 ! OIFS integrates the advection term. With advection disabled, fall back to
308 ! the standard BDF history assembly.
309 this%oifs = this%oifs .and. advection
310
311 this%ulag => ulag
312 this%vlag => vlag
313 this%wlag => wlag
314
315 call chkp%get_time_history(tlag, dtlag)
316 call advection_factory(this%adv, numerics_params, this%c_Xh, &
317 ulag, vlag, wlag, dtlag, &
318 tlag, time_scheme, .not. advection, &
319 this%slag)
320 end subroutine scalar_pnpn_init
321
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
327
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)
333
334 end subroutine scalar_pnpn_register_checkpoint
335
336 ! Restarts the scalar from a checkpoint
337 subroutine scalar_pnpn_restart(this, chkp)
338 class(scalar_pnpn_t), target, intent(inout) :: this
339 type(chkp_t), intent(inout) :: chkp
340 integer :: i, n
341 class(bc_t), pointer :: bc_i
342 logical :: interpolated
343
344 n = this%s%dof%size()
345
346 ! Lag fields are restored through the checkpoint's fsp mechanism
347
348 ! The restored fields are continuous unless the checkpoint was written
349 ! on another mesh or at another polynomial order and was interpolated
350 ! on the way in. Only then do the copies of a node shared between
351 ! elements need averaging: scale by the inverse multiplicity, then sum
352 ! the copies with a gather-scatter. On a plain restart that is the
353 ! identity in exact arithmetic but not in floating point, and would put
354 ! about one ulp of error on every shared node. Same guard as the fluid.
355 interpolated = allocated(chkp%previous_mesh%elements) .or. &
356 chkp%previous_Xh%lx .ne. this%Xh%lx
357
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)
362 end if
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.)
376 end if
377
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)
382 end if
383
384 ! Restore scalar bcs that need it. This is a no op in most bcs.
385 do i = 1, this%bcs%size()
386 bc_i => this%bcs%get(i)
387 call bc_i%restart(this%s, this%slag)
388 end do
389
390 nullify(bc_i)
391
392 end subroutine scalar_pnpn_restart
393
394 subroutine scalar_pnpn_free(this)
395 class(scalar_pnpn_t), intent(inout) :: this
396
397 ! Release operator references before scheme_free deallocates their targets.
398 if (allocated(this%Ax)) then
399 call this%Ax%free()
400 deallocate(this%Ax)
401 end if
402
403 !Deallocate scalar field
404 call this%scheme_free()
405
406 call this%bc_projector%free()
407 call this%proj_s%free()
408
409 call this%s_res%free()
410
411 call this%ds%free()
412
413 call this%abx1%free()
414 call this%abx2%free()
415
416 call this%advs%free()
417
418 if (allocated(this%adv)) then
419 call this%adv%free()
420 deallocate(this%adv)
421 end if
422
423 nullify(this%ulag)
424 nullify(this%vlag)
425 nullify(this%wlag)
426
427 if (allocated(this%res)) then
428 deallocate(this%res)
429 end if
430
431 if (allocated(this%makeext)) then
432 deallocate(this%makeext)
433 end if
434
435 if (allocated(this%makebdf)) then
436 deallocate(this%makebdf)
437 end if
438
439 if (allocated(this%makeoifs)) then
440 deallocate(this%makeoifs)
441 end if
442
443 end subroutine scalar_pnpn_free
444
445 subroutine scalar_pnpn_step(this, time, ext_bdf, dt_controller, &
446 ksp_results)
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
454 ! Number of degrees of freedom
455 integer :: n
456
457 if (this%freeze) return
458
459 n = this%dm_Xh%size()
460 call neko_scratch_registry%request_field(rho_cp, rho_cp_index, .false.)
461
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, &
465 ds => this%ds, &
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)
474
475 ! Logs extra information the log level is NEKO_LOG_DEBUG or above.
476 call print_debug(this)
477
478 ! Update material properties and their pointwise product.
479 call this%update_material_properties(time)
480 call field_col3(rho_cp, rho, cp, n)
481
482 ! Update the SVV coefficient if SVV is enabled.
483 if (this%svv_enabled) then
484 call this%svv%update(rho_cp, tstep)
485 end if
486
487 ! Compute the source terms
488 call this%source_term%compute(time)
489
490 if (oifs) then
491 ! The fluid step has already advanced u, v, and w to the new time.
492 ! Its first lag fields contain the velocity at tlag(1), which is the
493 ! latest time represented by the OIFS interpolation history.
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())
497 else
498 ! Add the advection operators to the right-hand side.
499 call this%adv%compute_scalar(u, v, w, s, f_xh, &
500 xh, this%c_Xh, dm_xh%size())
501 end if
502
503 ! Scale the volumetric source and advection terms by rho * cp.
504 call field_col2(f_xh, rho_cp, n)
505
506 ! Add weak boundary fluxes without scaling them by rho * cp.
507 call this%bcs%apply_scalar(f_xh%x, n, time, .false.)
508
509 ! Extrapolate the already scaled explicit right-hand side.
510 call makeext%compute_scalar(this%abx1, this%abx2, f_xh%x, &
511 ext_bdf%advection_coeffs%x, n)
512
513 if (oifs) then
514 call makeoifs%compute_scalar(this%advs%x, f_xh%x, &
515 rho_cp, real(dt, kind=rp), n)
516 else
517
518 ! Add the RHS contributions coming from the BDF scheme.
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, &
521 ext_bdf%ndiff, n)
522 end if
523
524 call slag%update()
525
527 call this%apply_strong_bcs(time)
528
529 ! Compute scalar residual.
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())
534
535 call gs_xh%op(s_res, gs_op_add)
536
537 ! Zero-out residual at Dirichlet nodes before solving.
538 call this%bc_projector%apply(s_res%x, dm_xh%size())
539
540 call profiler_end_region(trim(this%name) // '_residual', 20)
541
542 call this%proj_s%pre_solving(s_res%x, tstep, c_xh, n, dt_controller)
543
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)
550
551 call this%proj_s%post_solving(ds%x, ax, c_xh, this%bc_projector, gs_xh, &
552 n, tstep, dt_controller)
553
554 ! Update the solution
555 if (neko_bcknd_device .eq. 1) then
556 call device_add2s2(s%x_d, ds%x_d, 1.0_rp, n)
557 else
558 call add2s2(s%x, ds%x, 1.0_rp, n)
559 end if
560
561 end associate
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
565
566 subroutine print_debug(this)
567 class(scalar_pnpn_t), intent(inout) :: this
568 character(len=LOG_SIZE) :: log_buf
569 integer :: n
570
571 n = this%dm_Xh%size()
572
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
583
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
594 logical :: found
595 ! Monitor which boundary zones have been marked
596 logical, allocatable :: marked_zones(:)
597 integer, allocatable :: zone_indices(:)
598 character(len=256) :: error_msg
599
600 if (this%params%valid_path('boundary_conditions')) then
601 call this%params%info('boundary_conditions', &
602 n_children = n_bcs)
603 call this%params%get_core(core)
604 call this%params%get('boundary_conditions', bc_object, found)
605
606 call this%bcs%init(n_bcs)
607
608 allocate(marked_zones(size(this%msh%labeled_zones)))
609 marked_zones = .false.
610
611 do i = 1, n_bcs
612 ! Create a new json containing just the subdict for this bc
613 call json_extract_item(core, bc_object, i, bc_subdict)
614
615 ! Check that we are not trying to assing a bc to zone, for which one
616 ! has already been assigned and that the zone has more than 0 size
617 ! in the mesh.
618 call json_get(bc_subdict, "zone_indices", zone_indices)
619
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)
624
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 ", &
630 "condition ", i, "."
631 call neko_error(error_msg)
632 error stop
633 end if
634
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)
643 error stop
644 else
645 marked_zones(zone_indices(j)) = .true.
646 end if
647 end do
648
649 bc_i => null()
650
651 call scalar_pnpn_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
652 call this%bcs%append(bc_i)
653 end do
654
655 ! Make sure all labeled zones with non-zero size have been marked
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)
662 error stop
663 end if
664 end do
665 else
666 ! Check that there are no labeled zones, i.e. all are periodic.
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 ", &
671 this%s%name
672 call neko_error(error_msg)
673 error stop
674 end if
675 end do
676
677 ! For a pure periodic case, we still need to initilise the bc lists
678 ! to a zero size to avoid issues with apply() in step()
679 call this%bcs%init()
680
681 end if
682 end subroutine scalar_pnpn_setup_bcs_
683
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
689
690 integer :: i
691 class(bc_t), pointer :: bc_i
692 bc_i => null()
693
694 ! First apply call, sets the Dirichlet value, let's call it d.
695 call this%bcs%apply(this%s, time = time, strong = .true.)
696 ! If we now have local nodes sharing the same global node, and with
697 ! some nodes not masked as Dirichlet, the node which *is* masked
698 ! will have the value d, and the the other ones just some value u.
699 ! Take a nodewise minimum between the local nodes.
700 ! Now, all local nodes store m = min(d, u)
701 call this%gs_Xh%op(this%s, gs_op_min, glb_cmd_event)
702 call device_event_sync(glb_cmd_event)
703
704 ! Second apply call, so Dirichlet nodes again store d, the rest still store
705 ! m, where m < d by construction.
706 call this%bcs%apply(this%s, time = time, strong = .true.)
707 ! Now apply a max, which guarantees that d wins and gets stored in all the
708 ! local nodes.
709 call this%gs_Xh%op(this%s, gs_op_max, glb_cmd_event)
710 call device_event_sync(glb_cmd_event)
711
712 ! Reset updated flags
713 do i = 1, this%bcs%size()
714 bc_i => this%bcs%get(i)
715 bc_i%updated = .false.
716 end do
717 nullify(bc_i)
718
719 end subroutine scalar_scheme_apply_strong_bcs
720
721
722end module scalar_pnpn
double real
Copy data between host and device (or device and device)
Definition device.F90:72
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.
Definition advection.f90:34
Base type for an SVV Helmholtz operator.
Defines a Matrix-vector product.
Definition ax.f90:34
Defines a boundary condition.
Definition bc.f90:34
integer, parameter, public bc_dirichlet
Supported boundary condition types. The values are set in order of precedence for global resolution....
Definition bc.f90:67
Format-independent checkpoint payloads.
Defines format-independent checkpoint registration and restart state.
Coefficients.
Definition coef.f90:34
Definition comm.F90:1
type(mpi_comm), public neko_comm
MPI communicator.
Definition comm.F90:46
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.
Definition device.F90:34
subroutine, public device_event_sync(event)
Synchronize an event.
Definition device.F90:1667
integer, parameter, public host_to_device
Definition device.F90:48
type(c_ptr), bind(C), public glb_cmd_event
Event for the global command queue.
Definition device.F90:63
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.
Defines a field.
Definition field.f90:34
Gather-scatter.
Utilities for retrieving parameters from the case files.
Implements the base abstract type for Krylov solvers plus helper types.
Definition krylov.f90:34
Logging routines.
Definition log.f90:34
integer, parameter, public neko_log_debug
Debug.
Definition log.f90:56
type(log_t), public neko_log
Global log stream.
Definition log.f90:91
integer, parameter, public log_size
Definition log.f90:46
Definition math.f90:60
real(kind=rp) function, public glsc2(a, b, n)
Weighted inner product .
Definition math.f90:1305
subroutine, public col2(a, b, n)
Vector multiplication .
Definition math.f90:1085
subroutine, public add2s2(a, b, c1, n)
Vector addition with scalar multiplication (multiplication on second argument)
Definition math.f90:1037
Defines a mesh.
Definition mesh.f90:34
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public dp
Definition num_types.f90:10
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Profiling interface.
Definition profiler.F90:34
subroutine, public profiler_start_region(name, region_id)
Started a named (name) profiler region.
Definition profiler.F90:79
subroutine, public profiler_end_region(name, region_id)
End the most recently started profiler region.
Definition profiler.F90:116
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 ...
Definition rhs_maker.f90:38
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.
Definition user_intf.f90:34
Utilities.
Definition utils.f90:35
integer, parameter, public neko_varname_len
Definition utils.f90:43
Base abstract type for computing the advection operator.
Definition advection.f90:46
Helmholtz operator carrying a non-owning SVV object.
Base type for a matrix-vector product providing .
Definition ax.f90:43
Base type for a boundary condition.
Definition bc.f90:73
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,...
Definition coef.f90:135
Dirichlet condition in facet normal direction.
Stores a series (sequence) of fields, logically connected to a base field, and arranged according to ...
Gather-scatter kernel.
Type for storing initial and final residuals in a Krylov solver.
Definition krylov.f90:57
Abstract type to add contributions to F from lagged BD terms.
Definition rhs_maker.f90:59
Abstract type to sum up contributions to kth order extrapolation scheme.
Definition rhs_maker.f90:52
Abstract type to add contributions of kth order OIFS scheme.
Definition rhs_maker.f90:66
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.
A type collecting all the overridable user routines and flag to suppress type injection from custom m...