Refresh the ocean-surface shortwave from the ice slot’s
sw_thru_diag (PR 31) — the shortwave that penetrated the ice to
the water below (W/m^2, >= 0, POSITIVE DOWN into the ocean).
q_sw is the shortwave SHARE OF the net surface heat flux
(Q_heat CONTAINS q_sw, it is not Q_heat + q_sw), so the
delivery is BRANCH-DEPENDENT and this routine owns exactly ONE
path in each mode — the energy reaches Q_heat once, never twice:
Components on (sf%use_components, PR-12): full-array
overwrite of the q_sw COMPONENT (no _const term — the
assembler adds none for shortwave; q_sw IS the whole shortwave
summand it folds into Q_heat). heat_flux_diag (which the
heat coupler routed to heat_added) carries only the non-SW
heat, so there is no overlap. Sets has_q_sw.
Components off (default): q_sw is unallocated and no
assembler runs, so the shortwave is ADDED into Q_heat here.
MUST run AFTER ice_ocean_heat_flux (driver mandated order),
which full-overwrote Q_heat = Q_heat_const + heat_flux_diag
this window — so the net is Q_heat_const + heat_flux_diag +
sw_thru_diag, recomputed fresh each thermo window (no
accumulation drift). has_heat is already latched by the heat
coupler, so the apply-tracers kernel fires; has_q_sw is left
untouched (its backing array is unallocated in this mode, and
nothing consumes it — PR-21’s penetration reader is components-on).
No new validate_config guard is needed: the q_sw write is
reached ONLY under use_components, so an ice-on / components-off
run never touches the unallocated q_sw array.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_surface_flux_t), | intent(inout) | :: | sf | |||
| type(ocean_sea_ice_t), | intent(in) | :: | ice |
pure subroutine ice_ocean_sw_flux(sf, ice) !! Refresh the ocean-surface shortwave from the ice slot's !! `sw_thru_diag` (PR 31) — the shortwave that penetrated the ice to !! the water below (W/m^2, >= 0, POSITIVE DOWN into the ocean). !! !! `q_sw` is the shortwave SHARE OF the net surface heat flux !! (`Q_heat` CONTAINS `q_sw`, it is not `Q_heat + q_sw`), so the !! delivery is BRANCH-DEPENDENT and this routine owns exactly ONE !! path in each mode — the energy reaches `Q_heat` once, never twice: !! !! **Components on** (`sf%use_components`, PR-12): full-array !! overwrite of the `q_sw` COMPONENT (no `_const` term — the !! assembler adds none for shortwave; `q_sw` IS the whole shortwave !! summand it folds into `Q_heat`). `heat_flux_diag` (which the !! heat coupler routed to `heat_added`) carries only the non-SW !! heat, so there is no overlap. Sets `has_q_sw`. !! !! **Components off** (default): `q_sw` is unallocated and no !! assembler runs, so the shortwave is ADDED into `Q_heat` here. !! MUST run AFTER `ice_ocean_heat_flux` (driver mandated order), !! which full-overwrote `Q_heat = Q_heat_const + heat_flux_diag` !! this window — so the net is `Q_heat_const + heat_flux_diag + !! sw_thru_diag`, recomputed fresh each thermo window (no !! accumulation drift). `has_heat` is already latched by the heat !! coupler, so the apply-tracers kernel fires; `has_q_sw` is left !! untouched (its backing array is unallocated in this mode, and !! nothing consumes it — PR-21's penetration reader is components-on). !! !! No new `validate_config` guard is needed: the `q_sw` write is !! reached ONLY under `use_components`, so an ice-on / components-off !! run never touches the unallocated `q_sw` array. type(ocean_surface_flux_t), intent(inout) :: sf type(ocean_sea_ice_t), intent(in) :: ice if (sf%use_components) then sf%has_q_sw = .true. call ice_ocean_sw_flux_components_impl(sf%q_sw, ice%sw_thru_diag, & ice%nx_total, ice%ny_total) else call ice_ocean_sw_flux_add_impl(sf%Q_heat, ice%sw_thru_diag, & ice%nx_total, ice%ny_total) end if end subroutine ice_ocean_sw_flux