gm_compute_transports Subroutine

public subroutine gm_compute_transports(grid, metrics, this, slopes, ms, dt, khth_ext_u, khth_ext_v)

Fill uhD/vhD (m^3/s) with the GM bolus thickness transport and gm_src with the PE release, from the CURRENT ms%h_layer and the stored slopes. Run every outer step AFTER the dynamics, and immediately followed by continuity_gm_apply with the SAME dt and the same, untouched h_layer: the availability cap A·(h − H_VANISHED)/(4·dt) bounds that h and no other (see the module docstring). No-op when disabled, uninitialised, or the slopes slot is absent/disabled.

khth_ext_u/khth_ext_v (optional): spatially-varying PRE-CFL base KhTh face field from VarMix. When present the per-face CFL clamp uses it instead of the scalar khth; when absent, falls back to the constant khth (byte-identical to the pre-VarMix path).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(ocean_gm_t), intent(inout) :: this
type(ocean_slopes_t), intent(in) :: slopes
type(multilayer_state_t), intent(in) :: ms
real(kind=wp), intent(in) :: dt
real(kind=wp), intent(in), optional :: khth_ext_u(:,:)
real(kind=wp), intent(in), optional :: khth_ext_v(:,:)

Calls

proc~~gm_compute_transports~~CallsGraph proc~gm_compute_transports gm_compute_transports proc~gm_compute_impl gm_compute_impl proc~gm_compute_transports->proc~gm_compute_impl proc~gm_clamp_khth gm_clamp_khth proc~gm_compute_impl->proc~gm_clamp_khth proc~gm_column_x gm_column_x proc~gm_compute_impl->proc~gm_column_x proc~gm_column_y gm_column_y proc~gm_compute_impl->proc~gm_column_y proc~gm_pe_release gm_pe_release proc~gm_compute_impl->proc~gm_pe_release local local proc~gm_clamp_khth->local proc~gm_column_x->local proc~gm_block_below_bed gm_block_below_bed proc~gm_column_x->proc~gm_block_below_bed proc~gm_h_frac gm_h_frac proc~gm_column_x->proc~gm_h_frac rdb_vl_is_live rdb_vl_is_live proc~gm_column_x->rdb_vl_is_live proc~gm_column_y->local proc~gm_column_y->proc~gm_block_below_bed proc~gm_column_y->proc~gm_h_frac proc~gm_column_y->rdb_vl_is_live proc~gm_pe_release->local proc~gm_clamp_slope gm_clamp_slope proc~gm_pe_release->proc~gm_clamp_slope proc~gm_pos_n2 gm_pos_n2 proc~gm_pe_release->proc~gm_pos_n2

Called by

proc~~gm_compute_transports~~CalledByGraph proc~gm_compute_transports gm_compute_transports proc~run_gm_step run_gm_step proc~run_gm_step->proc~gm_compute_transports proc~ocean_dyn_step_split ocean_dyn_step_split proc~ocean_dyn_step_split->proc~run_gm_step proc~engine_step engine_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

Variables

Type Visibility Attributes Name Initial
integer, private :: nx
integer, private :: ny
integer, private :: nz
logical, private :: use_ext
logical, private :: use_open

Source Code

   subroutine gm_compute_transports(grid, metrics, this, slopes, ms, dt, &
                                    khth_ext_u, khth_ext_v)
      !! Fill `uhD`/`vhD` (m^3/s) with the GM bolus thickness transport and
      !! `gm_src` with the PE release, from the CURRENT `ms%h_layer` and the
      !! stored slopes.  Run every outer step AFTER the dynamics, and
      !! immediately followed by `continuity_gm_apply` with the SAME `dt`
      !! and the same, untouched `h_layer`: the availability cap
      !! `A·(h − H_VANISHED)/(4·dt)` bounds that `h` and no other (see the
      !! module docstring).  No-op when disabled, uninitialised, or the
      !! slopes slot is absent/disabled.
      !!
      !! `khth_ext_u/khth_ext_v` (optional): spatially-varying PRE-CFL base
      !! KhTh face field from VarMix.  When present the per-face CFL clamp
      !! uses it instead of the scalar `khth`; when absent, falls back to
      !! the constant `khth` (byte-identical to the pre-VarMix path).
      type(hgrid_t), intent(in) :: grid
      type(ocean_metrics_t), intent(in) :: metrics
      type(ocean_gm_t), intent(inout) :: this
      type(ocean_slopes_t), intent(in) :: slopes
      type(multilayer_state_t), intent(in) :: ms
      real(wp), intent(in) :: dt
      real(wp), intent(in), optional :: khth_ext_u(:, :)
      real(wp), intent(in), optional :: khth_ext_v(:, :)

      integer :: nx, ny, nz
      logical :: use_ext, use_open

      if (.not. this%is_init) return
      if (.not. this%enable) return
      if (.not. slopes%is_init) return
      if (.not. allocated(ms%h_layer)) return
      if (.not. allocated(slopes%slope_x)) return

      nx = grid%nx_total
      ny = grid%ny_total
      nz = ms%nz_ml
      if (this%nz_ml /= nz) return
      if (slopes%nz_ml /= nz) return

      use_ext = present(khth_ext_u) .and. present(khth_ext_v)
      use_open = metrics%use_closed_faces

      ! Explicit-shape flat-impl: pass the top-level allocatables so NVHPC
      ! does not descriptor-walk per launch.  When the external VarMix base
      ! is absent, pass `this%khth_u/khth_v` as a harmless placeholder for
      ! the `khth_ext_*` dummy and gate it off with `use_ext`.
      !
      ! The z-level open masks follow the continuity convention (the
      ! `open_f` dummy of the barotropic renormaliser): with the knob OFF
      ! they are `(1,1,1)` placeholders, and NVHPC derives an explicit-shape
      ! dummy's present-check extent from its DECLARED bounds, so handing
      ! over the placeholder aborts `mem:separate` ("partially present")
      ! even though `use_open = .false.` never indexes it.  The knob-off
      ! calls therefore pass the slopes' own read-only `slope_x`/`slope_y`
      ! as the inert stand-in: `(nx+1,ny,nz+1)`/`(nx,ny+1,nz+1)`, i.e. at
      ! least the `(..,nz)` the dummy declares, already device-mapped, and
      ! only ever read here.
      if (use_open) then
         if (use_ext) then
            call gm_compute_impl(nx, ny, nz, dt, this%khth, this%khth_max_cfl, &
                                 this%khth_slope_max, this%rho0, use_ext, use_open, &
                                 metrics%dy_cu, metrics%dx_cv, metrics%idxCu, &
                                 metrics%idyCv, metrics%idyCu, metrics%idxCv, &
                                 metrics%areaT, metrics%wet_u, metrics%wet_v, &
                                 ms%h_layer, slopes%bathy, slopes%slope_x, slopes%slope_y, &
                                 slopes%n2_u, slopes%n2_v, khth_ext_u, khth_ext_v, &
                                 metrics%open_u, metrics%open_v, &
                                 this%khth_u, this%khth_v, &
                                 this%uhD, this%vhD, this%gm_src)
         else
            call gm_compute_impl(nx, ny, nz, dt, this%khth, this%khth_max_cfl, &
                                 this%khth_slope_max, this%rho0, use_ext, use_open, &
                                 metrics%dy_cu, metrics%dx_cv, metrics%idxCu, &
                                 metrics%idyCv, metrics%idyCu, metrics%idxCv, &
                                 metrics%areaT, metrics%wet_u, metrics%wet_v, &
                                 ms%h_layer, slopes%bathy, slopes%slope_x, slopes%slope_y, &
                                 slopes%n2_u, slopes%n2_v, this%khth_u, this%khth_v, &
                                 metrics%open_u, metrics%open_v, &
                                 this%khth_u, this%khth_v, &
                                 this%uhD, this%vhD, this%gm_src)
         end if
      else if (use_ext) then
         call gm_compute_impl(nx, ny, nz, dt, this%khth, this%khth_max_cfl, &
                              this%khth_slope_max, this%rho0, use_ext, use_open, &
                              metrics%dy_cu, metrics%dx_cv, metrics%idxCu, &
                              metrics%idyCv, metrics%idyCu, metrics%idxCv, &
                              metrics%areaT, metrics%wet_u, metrics%wet_v, &
                              ms%h_layer, slopes%bathy, slopes%slope_x, slopes%slope_y, &
                              slopes%n2_u, slopes%n2_v, khth_ext_u, khth_ext_v, &
                              slopes%slope_x, slopes%slope_y, &
                              this%khth_u, this%khth_v, &
                              this%uhD, this%vhD, this%gm_src)
      else
         call gm_compute_impl(nx, ny, nz, dt, this%khth, this%khth_max_cfl, &
                              this%khth_slope_max, this%rho0, use_ext, use_open, &
                              metrics%dy_cu, metrics%dx_cv, metrics%idxCu, &
                              metrics%idyCv, metrics%idyCu, metrics%idxCv, &
                              metrics%areaT, metrics%wet_u, metrics%wet_v, &
                              ms%h_layer, slopes%bathy, slopes%slope_x, slopes%slope_y, &
                              slopes%n2_u, slopes%n2_v, this%khth_u, this%khth_v, &
                              slopes%slope_x, slopes%slope_y, &
                              this%khth_u, this%khth_v, &
                              this%uhD, this%vhD, this%gm_src)
      end if
   end subroutine gm_compute_transports