gm_compute_impl Subroutine

private subroutine gm_compute_impl(nx, ny, nz, dt, khth, khth_max_cfl, slope_max, rho0, use_ext, use_open, dy_cu, dx_cv, idxCu, idyCv, idyCu, idxCv, areaT, wet_u, wet_v, h_layer, bathy, slope_x, slope_y, n2_u, n2_v, khth_ext_u, khth_ext_v, open_u, open_v, khth_u, khth_v, uhD, vhD, gm_src)

Flat-impl GM kernel. Passes: CFL-clamp the 2D face KhTh, the u-face and v-face column recurrences into uhD/vhD, the gm_src PE release. Each face’s column sweep is serial in k (the uhtot recurrence) but faces parallelise over (i,j).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: nz
real(kind=wp), intent(in) :: dt
real(kind=wp), intent(in) :: khth
real(kind=wp), intent(in) :: khth_max_cfl
real(kind=wp), intent(in) :: slope_max
real(kind=wp), intent(in) :: rho0
logical, intent(in) :: use_ext
logical, intent(in) :: use_open

z-level closed faces active (metrics%use_closed_faces). .false. ⇒ open_u/open_v are never indexed.

real(kind=wp), intent(in) :: dy_cu(nx+1,ny)
real(kind=wp), intent(in) :: dx_cv(nx,ny+1)
real(kind=wp), intent(in) :: idxCu(nx+1,ny)
real(kind=wp), intent(in) :: idyCv(nx,ny+1)
real(kind=wp), intent(in) :: idyCu(nx+1,ny)
real(kind=wp), intent(in) :: idxCv(nx,ny+1)
real(kind=wp), intent(in) :: areaT(nx,ny)
real(kind=wp), intent(in) :: wet_u(nx+1,ny)
real(kind=wp), intent(in) :: wet_v(nx,ny+1)
real(kind=wp), intent(in) :: h_layer(nx,ny,nz)
real(kind=wp), intent(in) :: bathy(nx,ny)

Bed depth D (m, positive down; slopes%bathy): the bed of each column is at z = −D for the bottom-blocking limiter.

real(kind=wp), intent(in) :: slope_x(nx+1,ny,nz+1)
real(kind=wp), intent(in) :: slope_y(nx,ny+1,nz+1)
real(kind=wp), intent(in) :: n2_u(nx+1,ny,nz+1)
real(kind=wp), intent(in) :: n2_v(nx,ny+1,nz+1)
real(kind=wp), intent(in) :: khth_ext_u(nx+1,ny)
real(kind=wp), intent(in) :: khth_ext_v(nx,ny+1)
real(kind=wp), intent(in) :: open_u(nx+1,ny,nz)

Per-layer 0/1 u-face open mask (metrics%open_u), read only when use_open; an inert device-present stand-in otherwise.

real(kind=wp), intent(in) :: open_v(nx,ny+1,nz)

v-face twin of open_u.

real(kind=wp), intent(out) :: khth_u(nx+1,ny)
real(kind=wp), intent(out) :: khth_v(nx,ny+1)
real(kind=wp), intent(out) :: uhD(nx+1,ny,nz)
real(kind=wp), intent(out) :: vhD(nx,ny+1,nz)
real(kind=wp), intent(out) :: gm_src(nx,ny)

Calls

proc~~gm_compute_impl~~CallsGraph proc~gm_compute_impl 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_impl~~CalledByGraph proc~gm_compute_impl gm_compute_impl proc~gm_compute_transports gm_compute_transports proc~gm_compute_transports->proc~gm_compute_impl 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

Variables

Type Visibility Attributes Name Initial
integer, private :: i
real(kind=wp), private :: i4dt
real(kind=wp), private :: i_smax2
integer, private :: j
integer, private :: k

Source Code

   subroutine gm_compute_impl(nx, ny, nz, dt, khth, khth_max_cfl, slope_max, &
                              rho0, use_ext, use_open, dy_cu, dx_cv, idxCu, &
                              idyCv, idyCu, idxCv, areaT, wet_u, wet_v, h_layer, &
                              bathy, slope_x, slope_y, &
                              n2_u, n2_v, khth_ext_u, khth_ext_v, open_u, open_v, &
                              khth_u, khth_v, uhD, vhD, gm_src)
      !! Flat-impl GM kernel.  Passes: CFL-clamp the 2D face KhTh, the
      !! u-face and v-face column recurrences into `uhD`/`vhD`, the
      !! `gm_src` PE release.  Each face's column sweep is serial in k (the
      !! `uhtot` recurrence) but faces parallelise over (i,j).
      integer, intent(in) :: nx, ny, nz
      real(wp), intent(in) :: dt, khth, khth_max_cfl, slope_max, rho0
      logical, intent(in) :: use_ext
      logical, intent(in) :: use_open
         !! z-level closed faces active (`metrics%use_closed_faces`).
         !! `.false.` ⇒ `open_u`/`open_v` are never indexed.
      real(wp), intent(in) :: dy_cu(nx + 1, ny)
      real(wp), intent(in) :: dx_cv(nx, ny + 1)
      real(wp), intent(in) :: idxCu(nx + 1, ny)
      real(wp), intent(in) :: idyCv(nx, ny + 1)
      real(wp), intent(in) :: idyCu(nx + 1, ny)
      real(wp), intent(in) :: idxCv(nx, ny + 1)
      real(wp), intent(in) :: areaT(nx, ny)
      real(wp), intent(in) :: wet_u(nx + 1, ny)
      real(wp), intent(in) :: wet_v(nx, ny + 1)
      real(wp), intent(in) :: h_layer(nx, ny, nz)
      real(wp), intent(in) :: bathy(nx, ny)
         !! Bed depth `D` (m, positive down; `slopes%bathy`): the bed of each
         !! column is at `z = −D` for the bottom-blocking limiter.
      real(wp), intent(in) :: slope_x(nx + 1, ny, nz + 1)
      real(wp), intent(in) :: slope_y(nx, ny + 1, nz + 1)
      real(wp), intent(in) :: n2_u(nx + 1, ny, nz + 1)
      real(wp), intent(in) :: n2_v(nx, ny + 1, nz + 1)
      real(wp), intent(in) :: khth_ext_u(nx + 1, ny)
      real(wp), intent(in) :: khth_ext_v(nx, ny + 1)
      real(wp), intent(in) :: open_u(nx + 1, ny, nz)
         !! Per-layer 0/1 u-face open mask (`metrics%open_u`), read only
         !! when `use_open`; an inert device-present stand-in otherwise.
      real(wp), intent(in) :: open_v(nx, ny + 1, nz)
         !! v-face twin of `open_u`.
      real(wp), intent(out) :: khth_u(nx + 1, ny)
      real(wp), intent(out) :: khth_v(nx, ny + 1)
      real(wp), intent(out) :: uhD(nx + 1, ny, nz)
      real(wp), intent(out) :: vhD(nx, ny + 1, nz)
      real(wp), intent(out) :: gm_src(nx, ny)

      real(wp) :: i_smax2, i4dt
      integer :: i, j, k

      i_smax2 = 1.0_wp/(slope_max*slope_max)
      i4dt = 1.0_wp/(4.0_wp*dt)

      ! ---- 1. CFL-clamp the constant KhTh onto the 2D face fields, using
      ! native face metrics (idxCu/idyCu at u-faces, idxCv/idyCv at
      ! v-faces) — exact on curvilinear grids.  Wall faces -> 0.
      call gm_clamp_khth(nx, ny, dt, khth, khth_max_cfl, use_ext, &
                         khth_ext_u, khth_ext_v, idxCu, idyCu, &
                         idxCv, idyCv, wet_u, wet_v, khth_u, khth_v)

      ! ---- 2. u-face bolus transport (column recurrence).
      do concurrent(k=1:nz, j=1:ny)
         uhD(1, j, k) = 0.0_wp
         uhD(nx + 1, j, k) = 0.0_wp
      end do
      call gm_column_x(nx, ny, nz, i_smax2, i4dt, use_open, &
                       dy_cu, areaT, h_layer, bathy, slope_x, khth_u, open_u, uhD)

      ! ---- 3. v-face bolus transport (mirror).
      do concurrent(k=1:nz, i=1:nx)
         vhD(i, 1, k) = 0.0_wp
         vhD(i, ny + 1, k) = 0.0_wp
      end do
      call gm_column_y(nx, ny, nz, i_smax2, i4dt, use_open, &
                       dx_cv, areaT, h_layer, bathy, slope_y, khth_v, open_v, vhD)

      ! ---- 4. gm_src PE release (cell centres).
      call gm_pe_release(nx, ny, nz, slope_max, rho0, h_layer, &
                         slope_x, slope_y, n2_u, n2_v, khth_u, khth_v, gm_src)
   end subroutine gm_compute_impl