WENO analogue of drain_swept_flux_x: swept-average zonal face flux
from the concentration field tr using the WENO rung ladder.
recon is TRACER_RECON_WENO5/7/9 (1/2/3); the internal rung_max is
recon + 1 (WENO5→2, WENO7→3, WENO9→4).
periodic: on a periodic axis the ghost band is a wrapped copy of
the interior, so the full-rung stencil is valid everywhere — force
full rung (no position-based degradation). This keeps the two
images of a wrapped seam face bit-identical, so the interior flux
telescopes and Σ(areaT·hTr) is conserved. The per-rung nghost
minimum (fail-loud at configure) guarantees the full-rung reads at
the seam faces stay in [1, nx]. On a non-periodic (wall) axis the
position ladder degrades toward the array edge; wall faces carry no
transport, so a reduced-rung reconstruction there costs no accuracy.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nghost | |||
| logical, | intent(in) | :: | periodic | |||
| real(kind=wp), | intent(in) | :: | areaT(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | uhh(nx+1,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | hprev(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | tr(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | wet_T(nx,ny) | |||
| integer, | intent(in) | :: | recon | |||
| real(kind=wp), | intent(inout) | :: | F(nx+1,ny,nz) |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | avail_down | ||||
| integer, | private | :: | avail_up | ||||
| real(kind=wp), | private | :: | cfl | ||||
| real(kind=wp), | private | :: | conc | ||||
| integer, | private | :: | i | ||||
| integer, | private | :: | j | ||||
| integer, | private | :: | k | ||||
| integer, | private | :: | rung_max | ||||
| real(kind=wp), | private | :: | u | ||||
| real(kind=wp), | private | :: | vol |
pure subroutine drain_swept_flux_x_weno(nx, ny, nz, nghost, periodic, areaT, uhh, & hprev, tr, wet_T, recon, F) !! WENO analogue of drain_swept_flux_x: swept-average zonal face flux !! from the concentration field `tr` using the WENO rung ladder. !! `recon` is TRACER_RECON_WENO5/7/9 (1/2/3); the internal rung_max is !! recon + 1 (WENO5→2, WENO7→3, WENO9→4). !! !! `periodic`: on a periodic axis the ghost band is a wrapped copy of !! the interior, so the full-rung stencil is valid everywhere — force !! full rung (no position-based degradation). This keeps the two !! images of a wrapped seam face bit-identical, so the interior flux !! telescopes and Σ(areaT·hTr) is conserved. The per-rung nghost !! minimum (fail-loud at configure) guarantees the full-rung reads at !! the seam faces stay in [1, nx]. On a non-periodic (wall) axis the !! position ladder degrades toward the array edge; wall faces carry no !! transport, so a reduced-rung reconstruction there costs no accuracy. integer, intent(in) :: nx, ny, nz, nghost, recon logical, intent(in) :: periodic real(wp), intent(in) :: areaT(nx, ny) real(wp), intent(in) :: uhh(nx + 1, ny, nz) real(wp), intent(in) :: hprev(nx, ny, nz) real(wp), intent(in) :: tr(nx, ny, nz) real(wp), intent(in) :: wet_T(nx, ny) real(wp), intent(inout) :: F(nx + 1, ny, nz) integer :: i, j, k, rung_max, avail_up, avail_down real(wp) :: u, cfl, vol, conc rung_max = recon + 1 do concurrent(k=1:nz, j=1:ny) F(1, j, k) = 0.0_wp F(nx + 1, j, k) = 0.0_wp end do do concurrent(k=1:nz, j=1:ny, i=2:nx) local(u, cfl, vol, conc, avail_up, avail_down) u = uhh(i, j, k) if (u > 0.0_wp) then ! donor = cell i-1, downwind = +i vol = max(areaT(i - 1, j)*hprev(i - 1, j, k), DRAIN_MIN_VOL) cfl = min(u/vol, 1.0_wp) if (periodic) then avail_up = nx avail_down = nx else avail_up = i - nghost avail_down = nx - nghost - i + 2 end if conc = weno_face_conc_x(nx, ny, nz, tr, wet_T, i - 1, j, k, 1, & avail_up, avail_down, rung_max, cfl) F(i, j, k) = u*conc else if (u < 0.0_wp) then ! donor = cell i, downwind = -i vol = max(areaT(i, j)*hprev(i, j, k), DRAIN_MIN_VOL) cfl = min(-u/vol, 1.0_wp) if (periodic) then avail_up = nx avail_down = nx else avail_up = nx - nghost - i + 2 avail_down = i - nghost end if conc = weno_face_conc_x(nx, ny, nz, tr, wet_T, i, j, k, -1, & avail_up, avail_down, rung_max, cfl) F(i, j, k) = u*conc else F(i, j, k) = 0.0_wp end if end do end subroutine drain_swept_flux_x_weno