ocean_porous_refresh Subroutine

public subroutine ocean_porous_refresh(grid, metrics, ms)

Recompute the porous-barrier layer-averaged open-area fractions from the current layer thicknesses. No-op (and untouched placeholder arrays) when &ocean_porous_nml enable is off.

Cadence: ONCE PER OUTER STEP, before the RK2 stages — the fractions are then held fixed across both stages. That is MOM6’s cadence (porous_widths_layer runs in step_MOM ahead of the dynamics call and the porous type enters the split-RK2 driver intent(in)), and it keeps the widths consistent between the two stages’ continuity and Coriolis transports.

Device-side do concurrent: every array it touches is already mapped by ocean_metrics_enter_data / the multilayer state, so there is no host round-trip and nothing to allocate.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(inout) :: metrics
type(multilayer_state_t), intent(in) :: ms

Calls

proc~~ocean_porous_refresh~~CallsGraph proc~ocean_porous_refresh ocean_porous_refresh proc~closed_faces_update_bt_widths closed_faces_update_bt_widths proc~ocean_porous_refresh->proc~closed_faces_update_bt_widths proc~porous_update_face_areas porous_update_face_areas proc~ocean_porous_refresh->proc~porous_update_face_areas local local proc~closed_faces_update_bt_widths->local proc~porous_update_face_areas->local proc~clamp_fraction clamp_fraction proc~porous_update_face_areas->proc~clamp_fraction proc~porous_cum_area porous_cum_area proc~porous_update_face_areas->proc~porous_cum_area proc~porous_eta_face porous_eta_face proc~porous_update_face_areas->proc~porous_eta_face

Called by

proc~~ocean_porous_refresh~~CalledByGraph proc~ocean_porous_refresh ocean_porous_refresh proc~engine_step engine_step proc~engine_step->proc~ocean_porous_refresh 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 ocean_porous_refresh(grid, metrics, ms)
      !! Recompute the porous-barrier layer-averaged open-area fractions
      !! from the current layer thicknesses.  No-op (and untouched
      !! placeholder arrays) when `&ocean_porous_nml enable` is off.
      !!
      !! Cadence: ONCE PER OUTER STEP, before the RK2 stages — the
      !! fractions are then held fixed across both stages.  That is
      !! MOM6's cadence (`porous_widths_layer` runs in `step_MOM` ahead
      !! of the dynamics call and the porous type enters the split-RK2
      !! driver `intent(in)`), and it keeps the widths consistent between
      !! the two stages' continuity and Coriolis transports.
      !!
      !! Device-side `do concurrent`: every array it touches is already
      !! mapped by `ocean_metrics_enter_data` / the multilayer state, so
      !! there is no host round-trip and nothing to allocate.
      type(hgrid_t), intent(in) :: grid
      type(ocean_metrics_t), intent(inout) :: metrics
      type(multilayer_state_t), intent(in) :: ms

      if (metrics%use_porous) then
         call porous_update_face_areas(grid%nx_total, grid%ny_total, ms%nz_ml, &
                                       metrics%porous_eta_interp, &
                                       metrics%porous_mask_depth, &
                                       metrics%por_bed, ms%h_layer, &
                                       metrics%por_dmin_u, metrics%por_dmax_u, &
                                       metrics%por_davg_u, &
                                       metrics%por_dmin_v, metrics%por_dmax_v, &
                                       metrics%por_davg_v, &
                                       metrics%dy_cu, metrics%dx_cv, &
                                       metrics%por_face_area_u, &
                                       metrics%por_face_area_v, &
                                       metrics%dy_cu_bt, metrics%dx_cv_bt)
      end if

      ! z-level closed faces: refresh the BAROTROPIC widths from the LIVE
      ! `h` at the same (per-outer-step) cadence.  AFTER the porous write,
      ! which it SUPERSEDES rather than multiplies — the combined
      ! thickness-weighted fraction it computes already contains the
      ! porous one.  See `closed_faces_update_bt_widths`.
      if (metrics%use_closed_faces) then
         ! Two branches, one per porous state: with porous OFF the
         ! `por_face_area_*` arrays are the `(1,1,1)` placeholder and must
         ! NOT reach the callee's explicit-shape dummy (see its `use_por`
         ! docstring -- the GPU build aborts, the CPU builds do not).  The
         ! mask itself is the inert stand-in: right shape, already mapped,
         ! `intent(in)` at both dummies so the double association is legal.
         if (metrics%use_porous) then
            call closed_faces_update_bt_widths(grid%nx_total, grid%ny_total, ms%nz_ml, &
                                               .true., &
                                               metrics%dy_cu, metrics%dx_cv, &
                                               ms%h_layer, &
                                               metrics%por_face_area_u, &
                                               metrics%por_face_area_v, &
                                               metrics%open_u, metrics%open_v, &
                                               metrics%dy_cu_bt, metrics%dx_cv_bt)
         else
            call closed_faces_update_bt_widths(grid%nx_total, grid%ny_total, ms%nz_ml, &
                                               .false., &
                                               metrics%dy_cu, metrics%dx_cv, &
                                               ms%h_layer, &
                                               metrics%open_u, metrics%open_v, &
                                               metrics%open_u, metrics%open_v, &
                                               metrics%dy_cu_bt, metrics%dx_cv_bt)
         end if
      end if
   end subroutine ocean_porous_refresh