apply_sw_and_restore Subroutine

private 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.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(ocean_surface_flux_t), intent(in), optional :: sf

Forwarded; absent ⇒ both kernels no-op (their own contract).

type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: therm_dt
logical, intent(in) :: therm_active

Calls

proc~~apply_sw_and_restore~~CallsGraph proc~apply_sw_and_restore apply_sw_and_restore proc~ocean_surface_flux_apply_sw_penetration ocean_surface_flux_apply_sw_penetration proc~apply_sw_and_restore->proc~ocean_surface_flux_apply_sw_penetration proc~ocean_surface_restore_apply_tracers ocean_surface_restore_apply_tracers proc~apply_sw_and_restore->proc~ocean_surface_restore_apply_tracers proc~apply_sw_penetration_cover_impl apply_sw_penetration_cover_impl proc~ocean_surface_flux_apply_sw_penetration->proc~apply_sw_penetration_cover_impl proc~apply_sw_penetration_impl apply_sw_penetration_impl proc~ocean_surface_flux_apply_sw_penetration->proc~apply_sw_penetration_impl proc~apply_surface_restore_2d_cover_impl apply_surface_restore_2d_cover_impl proc~ocean_surface_restore_apply_tracers->proc~apply_surface_restore_2d_cover_impl proc~apply_surface_restore_2d_impl apply_surface_restore_2d_impl proc~ocean_surface_restore_apply_tracers->proc~apply_surface_restore_2d_impl local local proc~apply_surface_restore_2d_cover_impl->local proc~apply_surface_restore_2d_impl->local proc~apply_sw_penetration_cover_impl->local proc~sw_transmission sw_transmission proc~apply_sw_penetration_cover_impl->proc~sw_transmission proc~apply_sw_penetration_impl->local proc~apply_sw_penetration_impl->proc~sw_transmission

Called by

proc~~apply_sw_and_restore~~CalledByGraph proc~apply_sw_and_restore apply_sw_and_restore proc~run_stage run_stage proc~run_stage->proc~apply_sw_and_restore proc~run_stage_split run_stage_split proc~run_stage_split->proc~apply_sw_and_restore proc~ocean_dyn_step ocean_dyn_step proc~ocean_dyn_step->proc~run_stage proc~ocean_dyn_step_split ocean_dyn_step_split proc~ocean_dyn_step_split->proc~run_stage_split proc~engine_step engine_step proc~engine_step->proc~ocean_dyn_step proc~engine_step->proc~ocean_dyn_step_split proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_step proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean

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) :: grid
      type(ocean_metrics_t), intent(in) :: metrics
      type(ocean_surface_flux_t), intent(in), optional :: sf
         !! Forwarded; absent ⇒ both kernels no-op (their own contract).
      type(multilayer_state_t), intent(inout) :: ms
      real(wp), intent(in) :: therm_dt
      logical, intent(in) :: therm_active

      if (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