Ice-shelf-cover twin of apply_sw_penetration_impl: the
open-water factor 1 - cover_frac composes multiplicatively
with wet_mask into the column irradiance I0, so a fully
covered column neither removes the surface lump nor deposits a
profile — it is left EXACTLY untouched. Separate _impl, not
an in-loop present() test (house idiom, see
apply_surface_src_2d_dyn_impl) — the cover-off path keeps the
original kernel byte-identical.
The additive-correction conservation identity
-I0 + Σ_k I0·(T_top - T_bot) = 0 holds for ANY I0, and
I0 = 0 is the degenerate case of it, so scaling the source
cannot break column heat conservation.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | hTr(nx,ny,nz) | |||
| real(kind=wp), | intent(inout) | :: | budget(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| integer, | intent(in) | :: | k_bot(nx,ny) |
|
||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | cover_frac(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | sw_src(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | inv_scale | |||
| real(kind=wp), | intent(in) | :: | sw_pen_frac | |||
| real(kind=wp), | intent(in) | :: | R | |||
| real(kind=wp), | intent(in) | :: | zeta1 | |||
| real(kind=wp), | intent(in) | :: | zeta2 | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=wp), | private | :: | absorbed | ||||
| real(kind=wp), | private | :: | add | ||||
| real(kind=wp), | private | :: | d_bot | ||||
| real(kind=wp), | private | :: | d_top | ||||
| integer, | private | :: | i | ||||
| real(kind=wp), | private | :: | i0col | ||||
| integer, | private | :: | j | ||||
| integer, | private | :: | k | ||||
| real(kind=wp), | private | :: | trans_bot | ||||
| real(kind=wp), | private | :: | trans_top |
pure subroutine apply_sw_penetration_cover_impl(hTr, budget, h_layer, k_bot, wet_mask, & cover_frac, sw_src, inv_scale, & sw_pen_frac, R, zeta1, zeta2, nz, nx, ny) !! Ice-shelf-cover twin of `apply_sw_penetration_impl`: the !! open-water factor `1 - cover_frac` composes multiplicatively !! with `wet_mask` into the column irradiance `I0`, so a fully !! covered column neither removes the surface lump nor deposits a !! profile — it is left EXACTLY untouched. Separate `_impl`, not !! an in-loop `present()` test (house idiom, see !! `apply_surface_src_2d_dyn_impl`) — the cover-off path keeps the !! original kernel byte-identical. !! !! The additive-correction conservation identity !! `-I0 + Σ_k I0·(T_top - T_bot) = 0` holds for ANY `I0`, and !! `I0 = 0` is the degenerate case of it, so scaling the source !! cannot break column heat conservation. integer, intent(in) :: nz, nx, ny real(wp), intent(inout) :: hTr(nx, ny, nz) real(wp), intent(inout) :: budget(nx, ny, nz) real(wp), intent(in) :: h_layer(nx, ny, nz) integer, intent(in) :: k_bot(nx, ny) !! `ms%k_bot` — the first LIVE layer counting up from the bed. The !! opaque-bed residual lands HERE, not on `k = 1`: under `z_fixed` !! the layers below are inert fillers (`1` elsewhere ⇒ unchanged). real(wp), intent(in) :: wet_mask(nx, ny) real(wp), intent(in) :: cover_frac(nx, ny) real(wp), intent(in) :: sw_src(nx, ny) real(wp), intent(in) :: inv_scale, sw_pen_frac, R, zeta1, zeta2 integer :: i, j, k real(wp) :: i0col, d_top, d_bot, trans_top, trans_bot, absorbed, add do concurrent(j=1:ny, i=1:nx) local(i0col, d_top, d_bot, trans_top, & trans_bot, absorbed, add, k) i0col = sw_pen_frac*sw_src(i, j)*wet_mask(i, j)*(1.0_wp - cover_frac(i, j)) d_top = 0.0_wp do k = nz, k_bot(i, j), -1 d_bot = d_top + h_layer(i, j, k) trans_top = sw_transmission(d_top, R, zeta1, zeta2) if (k > k_bot(i, j)) then trans_bot = sw_transmission(d_bot, R, zeta1, zeta2) else trans_bot = 0.0_wp ! bed opaque: column absorbs all of I0 end if absorbed = i0col*(trans_top - trans_bot) add = inv_scale*absorbed if (k == nz) add = add - inv_scale*i0col ! remove the surface lump hTr(i, j, k) = hTr(i, j, k) + add budget(i, j, k) = budget(i, j, k) + add d_top = d_bot end do end do end subroutine apply_sw_penetration_cover_impl