drain_update_tracer_x + the closed-budget fill: the SAME increment
written to hTr is accumulated (times w) into budget_adv, so the
console out term sees the horizontal tracer transport the windowed
drain performs. Without this the drain moves tracer that
ms%*_budget_horiz_adv never records, and the Heat/Salt Error
column has to fall back to raw drift (which then reports a live
surface flux as a “leak”). w is
DRAIN_BUDGET_POST_AVERAGE_WEIGHT for every drain call site.
The hTr arithmetic is written EXACTLY as in the budget-free twin,
so a tracer with a budget slot and one without still integrate
bit-identically.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny | |||
| integer, | intent(in) | :: | nz | |||
| real(kind=wp), | intent(in) | :: | iareaT(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | F(nx+1,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | w | |||
| real(kind=wp), | intent(inout) | :: | hTr(nx,ny,nz) | |||
| real(kind=wp), | intent(inout) | :: | budget_adv(nx,ny,nz) |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | i | ||||
| integer, | private | :: | j | ||||
| integer, | private | :: | k |
pure subroutine drain_update_tracer_x_budget(nx, ny, nz, iareaT, F, w, hTr, budget_adv) !! `drain_update_tracer_x` + the closed-budget fill: the SAME increment !! written to `hTr` is accumulated (times `w`) into `budget_adv`, so the !! console `out` term sees the horizontal tracer transport the windowed !! drain performs. Without this the drain moves tracer that !! `ms%*_budget_horiz_adv` never records, and the Heat/Salt `Error` !! column has to fall back to raw drift (which then reports a live !! surface flux as a "leak"). `w` is !! `DRAIN_BUDGET_POST_AVERAGE_WEIGHT` for every drain call site. !! !! The `hTr` arithmetic is written EXACTLY as in the budget-free twin, !! so a tracer with a budget slot and one without still integrate !! bit-identically. integer, intent(in) :: nx, ny, nz real(wp), intent(in) :: iareaT(nx, ny) real(wp), intent(in) :: F(nx + 1, ny, nz) real(wp), intent(in) :: w real(wp), intent(inout) :: hTr(nx, ny, nz) real(wp), intent(inout) :: budget_adv(nx, ny, nz) integer :: i, j, k do concurrent(k=1:nz, j=1:ny, i=1:nx) hTr(i, j, k) = hTr(i, j, k) - (F(i + 1, j, k) - F(i, j, k))*iareaT(i, j) budget_adv(i, j, k) = budget_adv(i, j, k) & - w*(F(i + 1, j, k) - F(i, j, k))*iareaT(i, j) end do end subroutine drain_update_tracer_x_budget