The two cell-centred surface kernels that do NOT route through
the assembler’s Q_heat / Q_salt, with their ice-shelf-cover
dispatch. Shortwave penetration reads a pristine q_sw
component (or moves a lump the masked deposit never added) and
restoring forms its flux in-kernel from the live SST/SSS, so
each needs the cover factor of its own; everything else the
atmosphere contributes is already masked inside
ocean_surface_flux_assemble.
Hoisted into its own routine rather than written inline in
run_stage_split: that routine hosts eight do concurrent
kernels, and handing a state array (metrics%cover_frac) to an
external subroutine from a do concurrent host is the
documented nvfortran escape-analysis pessimisation (CLAUDE.md,
measured at +4.8 % on ocean_continuity). This wrapper has no
do concurrent of its own, so there is nothing to pessimise.
Cavity off (metrics%use_cavity = .false.) ⇒ the original two
calls, byte-identical.
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed
arrows point from an interface to procedures which implement that interface.
This could include the module procedures in a generic interface or the
implementation in a submodule of an interface in a parent module.
Where possible, edges connecting nodes are
given different colours to make them easier to distinguish in
large graphs.
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed
arrows point from an interface to procedures which implement that interface.
This could include the module procedures in a generic interface or the
implementation in a submodule of an interface in a parent module.
Where possible, edges connecting nodes are
given different colours to make them easier to distinguish in
large graphs.
Source Code
subroutine apply_sw_and_restore(grid,metrics,sf,ms,therm_dt,therm_active)!! The two cell-centred surface kernels that do NOT route through!! the assembler's `Q_heat` / `Q_salt`, with their ice-shelf-cover!! dispatch. Shortwave penetration reads a pristine `q_sw`!! component (or moves a lump the masked deposit never added) and!! restoring forms its flux in-kernel from the live SST/SSS, so!! each needs the cover factor of its own; everything else the!! atmosphere contributes is already masked inside!! `ocean_surface_flux_assemble`.!!!! Hoisted into its own routine rather than written inline in!! `run_stage_split`: that routine hosts eight `do concurrent`!! kernels, and handing a state array (`metrics%cover_frac`) to an!! external subroutine from a `do concurrent` host is the!! documented nvfortran escape-analysis pessimisation (CLAUDE.md,!! measured at +4.8 % on `ocean_continuity`). This wrapper has no!! `do concurrent` of its own, so there is nothing to pessimise.!!!! Cavity off (`metrics%use_cavity = .false.`) ⇒ the original two!! calls, byte-identical.type(hgrid_t),intent(in)::gridtype(ocean_metrics_t),intent(in)::metricstype(ocean_surface_flux_t),intent(in),optional::sf!! Forwarded; absent ⇒ both kernels no-op (their own contract).type(multilayer_state_t),intent(inout)::msreal(wp),intent(in)::therm_dtlogical,intent(in)::therm_activeif(metrics%use_cavity)then call ocean_surface_flux_apply_sw_penetration(grid,sf,ms,therm_dt,&active=therm_active,&cover_frac=metrics%cover_frac)call ocean_surface_restore_apply_tracers(grid,sf,ms,therm_dt,&active=therm_active,&cover_frac=metrics%cover_frac)else call ocean_surface_flux_apply_sw_penetration(grid,sf,ms,therm_dt,&active=therm_active)call ocean_surface_restore_apply_tracers(grid,sf,ms,therm_dt,&active=therm_active)end if end subroutine apply_sw_and_restore