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 | Intent | Optional | 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(:,:) |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | nx | ||||
| integer, | private | :: | ny | ||||
| integer, | private | :: | nz | ||||
| logical, | private | :: | use_ext | ||||
| logical, | private | :: | use_open |
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