run_gm_step Subroutine

private subroutine run_gm_step(grid, metrics, dyn, ct, va, ms, dt, gm, slopes, varmix, wavespeed, vcoord, bc)

Gent-McWilliams thickness diffusion as its OWN sequential operator, run once per outer step AFTER the dynamics (the stage loop and, under ssp_rk2, the stage average) — where MOM6 calls thickness_diffuse after step_MOM_dyn_split_RK2, every dynamics step:

  1. gm_compute_transports fills uhD/vhD + gm_src from the thickness the dynamics LEFT, with the stored slopes and the VarMix/MEKE base KhTh refreshed at the top of the step;
  2. continuity_gm_apply moves h_layer and every tracer by them with the same dt — so the per-face availability cap A·(h − H_VANISHED)/(4·dt) bounds what is actually there;
  3. eulerian_z only: the bolus divergence is cancelled per layer by the vertical advection, exactly as the resolved one is;
  4. the h / tracer ghosts are refreshed (exchange, periodic wrap, fold), as after the resolved continuity.

Until 2026-10 the transports were computed at the top of the step from the stage-entry thickness and FOLDED into the resolved continuity sweeps; the cap then bounded the wrong h and a partial bed cell on an open z* step was driven negative (rdb_ocean_gm).

Cadence: every outer step, with the outer dt (MOM6: every dynamics step). The fold path applied GM on thermo steps only, so under dt_therm_ratio > 1 it ran at 1/ratio of its strength. No-op when GM is absent / disabled, the slopes slot is absent, or thermodynamics is off.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(ocean_dyn_t), intent(inout) :: dyn
type(continuity_t), intent(inout) :: ct
type(ocean_vertical_advection_t), intent(inout) :: va
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: dt
type(ocean_gm_t), intent(inout), optional :: gm
type(ocean_slopes_t), intent(inout), optional :: slopes
type(ocean_varmix_t), intent(inout), optional :: varmix
type(ocean_wave_speed_t), intent(inout), optional :: wavespeed
type(ocean_vcoord_t), intent(in), optional :: vcoord
type(ocean_bc_state_t), intent(inout), optional :: bc

Calls

proc~~run_gm_step~~CallsGraph proc~run_gm_step run_gm_step proc~check_h_positive_or_die check_h_positive_or_die proc~run_gm_step->proc~check_h_positive_or_die proc~compute_w_from_continuity compute_w_from_continuity proc~run_gm_step->proc~compute_w_from_continuity proc~continuity_gm_apply continuity_gm_apply proc~run_gm_step->proc~continuity_gm_apply proc~gm_compute_transports gm_compute_transports proc~run_gm_step->proc~gm_compute_transports proc~ocean_budget_stage_weight ocean_budget_stage_weight proc~run_gm_step->proc~ocean_budget_stage_weight proc~ocean_fold_wrap_state ocean_fold_wrap_state proc~run_gm_step->proc~ocean_fold_wrap_state proc~ocean_halo_exchange_ml_state ocean_halo_exchange_ml_state proc~run_gm_step->proc~ocean_halo_exchange_ml_state proc~ocean_halo_is_decomposed_x ocean_halo_is_decomposed_x proc~run_gm_step->proc~ocean_halo_is_decomposed_x proc~ocean_halo_is_decomposed_y ocean_halo_is_decomposed_y proc~run_gm_step->proc~ocean_halo_is_decomposed_y proc~ocean_periodic_wrap_state ocean_periodic_wrap_state proc~run_gm_step->proc~ocean_periodic_wrap_state proc~probe_ds probe_dS proc~run_gm_step->proc~probe_ds proc~profiler_start profiler_start proc~run_gm_step->proc~profiler_start proc~profiler_stop profiler_stop proc~run_gm_step->proc~profiler_stop proc~tracer_advect_vertical tracer_advect_vertical proc~run_gm_step->proc~tracer_advect_vertical proc~continuity_gm_apply->proc~ocean_halo_is_decomposed_x proc~continuity_gm_apply->proc~ocean_halo_is_decomposed_y proc~continuity_gm_apply->proc~profiler_start proc~continuity_gm_apply->proc~profiler_stop interface~ocean_fold_north_v_face ocean_fold_north_v_face proc~continuity_gm_apply->interface~ocean_fold_north_v_face interface~ocean_halo_centre ocean_halo_centre proc~continuity_gm_apply->interface~ocean_halo_centre local local proc~continuity_gm_apply->local proc~drain_copy_3d drain_copy_3d proc~continuity_gm_apply->proc~drain_copy_3d proc~drain_rescale_htr drain_rescale_hTr proc~continuity_gm_apply->proc~drain_rescale_htr proc~drain_rescale_htr_budget drain_rescale_hTr_budget proc~continuity_gm_apply->proc~drain_rescale_htr_budget proc~gm_tracer_advect_x gm_tracer_advect_x proc~continuity_gm_apply->proc~gm_tracer_advect_x proc~gm_tracer_advect_y gm_tracer_advect_y proc~continuity_gm_apply->proc~gm_tracer_advect_y proc~ocean_bc_outer_face_tag ocean_bc_outer_face_tag proc~continuity_gm_apply->proc~ocean_bc_outer_face_tag proc~ocean_fold_wrap_centre_3d_state ocean_fold_wrap_centre_3d_state proc~continuity_gm_apply->proc~ocean_fold_wrap_centre_3d_state proc~ocean_periodic_wrap_centre_3d ocean_periodic_wrap_centre_3d proc~continuity_gm_apply->proc~ocean_periodic_wrap_centre_3d proc~gm_compute_impl gm_compute_impl proc~gm_compute_transports->proc~gm_compute_impl interface~fold_north_centre fold_north_centre proc~ocean_fold_wrap_state->interface~fold_north_centre interface~fold_north_u_face fold_north_u_face proc~ocean_fold_wrap_state->interface~fold_north_u_face interface~fold_north_v_face fold_north_v_face proc~ocean_fold_wrap_state->interface~fold_north_v_face interface~ocean_fold_pack ocean_fold_pack proc~ocean_fold_wrap_state->interface~ocean_fold_pack interface~ocean_fold_unpack ocean_fold_unpack proc~ocean_fold_wrap_state->interface~ocean_fold_unpack proc~n_tracers n_tracers proc~ocean_fold_wrap_state->proc~n_tracers proc~ocean_fold_begin ocean_fold_begin proc~ocean_fold_wrap_state->proc~ocean_fold_begin proc~ocean_fold_end ocean_fold_end proc~ocean_fold_wrap_state->proc~ocean_fold_end proc~ocean_fold_exchange ocean_fold_exchange proc~ocean_fold_wrap_state->proc~ocean_fold_exchange proc~ocean_fold_is_distributed ocean_fold_is_distributed proc~ocean_fold_wrap_state->proc~ocean_fold_is_distributed proc~ocean_halo_exchange_ml_state->proc~profiler_start proc~ocean_halo_exchange_ml_state->proc~profiler_stop proc~ocean_halo_exchange_ml_state->interface~ocean_halo_centre interface~ocean_halo_face_x ocean_halo_face_x proc~ocean_halo_exchange_ml_state->interface~ocean_halo_face_x interface~ocean_halo_face_y ocean_halo_face_y proc~ocean_halo_exchange_ml_state->interface~ocean_halo_face_y proc~oh_count_ml_state oh_count_ml_state proc~ocean_halo_exchange_ml_state->proc~oh_count_ml_state proc~oh_count_suppress_off oh_count_suppress_off proc~ocean_halo_exchange_ml_state->proc~oh_count_suppress_off proc~oh_count_suppress_on oh_count_suppress_on proc~ocean_halo_exchange_ml_state->proc~oh_count_suppress_on proc~ocean_periodic_wrap_state->proc~ocean_periodic_wrap_centre_3d proc~ocean_periodic_wrap_face_x_3d ocean_periodic_wrap_face_x_3d proc~ocean_periodic_wrap_state->proc~ocean_periodic_wrap_face_x_3d proc~ocean_periodic_wrap_face_y_3d ocean_periodic_wrap_face_y_3d proc~ocean_periodic_wrap_state->proc~ocean_periodic_wrap_face_y_3d proc~find_or_create_region find_or_create_region proc~profiler_start->proc~find_or_create_region proc~get_wall_time get_wall_time proc~profiler_start->proc~get_wall_time proc~nvtx_range_push nvtx_range_push proc~profiler_start->proc~nvtx_range_push proc~profiler_stop->proc~get_wall_time proc~nvtx_range_pop nvtx_range_pop proc~profiler_stop->proc~nvtx_range_pop proc~apply_w_to_h_layer apply_w_to_h_layer proc~tracer_advect_vertical->proc~apply_w_to_h_layer proc~tracer_advect_vertical_one_impl tracer_advect_vertical_one_impl proc~tracer_advect_vertical->proc~tracer_advect_vertical_one_impl proc~fold_north_centre_2d fold_north_centre_2d interface~fold_north_centre->proc~fold_north_centre_2d proc~fold_north_centre_3d fold_north_centre_3d interface~fold_north_centre->proc~fold_north_centre_3d proc~fold_north_u_face_2d fold_north_u_face_2d interface~fold_north_u_face->proc~fold_north_u_face_2d proc~fold_north_u_face_3d fold_north_u_face_3d interface~fold_north_u_face->proc~fold_north_u_face_3d proc~fold_north_v_face_2d fold_north_v_face_2d interface~fold_north_v_face->proc~fold_north_v_face_2d proc~fold_north_v_face_3d fold_north_v_face_3d interface~fold_north_v_face->proc~fold_north_v_face_3d proc~fold_v_2d fold_v_2d interface~ocean_fold_north_v_face->proc~fold_v_2d proc~fold_v_3d fold_v_3d interface~ocean_fold_north_v_face->proc~fold_v_3d proc~ocean_fold_pack_2d ocean_fold_pack_2d interface~ocean_fold_pack->proc~ocean_fold_pack_2d proc~ocean_fold_pack_3d ocean_fold_pack_3d interface~ocean_fold_pack->proc~ocean_fold_pack_3d proc~ocean_fold_unpack_2d ocean_fold_unpack_2d interface~ocean_fold_unpack->proc~ocean_fold_unpack_2d proc~ocean_fold_unpack_3d ocean_fold_unpack_3d interface~ocean_fold_unpack->proc~ocean_fold_unpack_3d proc~ocean_halo_centre_2d ocean_halo_centre_2d interface~ocean_halo_centre->proc~ocean_halo_centre_2d proc~ocean_halo_centre_3d ocean_halo_centre_3d interface~ocean_halo_centre->proc~ocean_halo_centre_3d proc~ocean_halo_face_x_2d ocean_halo_face_x_2d interface~ocean_halo_face_x->proc~ocean_halo_face_x_2d proc~ocean_halo_face_x_3d ocean_halo_face_x_3d interface~ocean_halo_face_x->proc~ocean_halo_face_x_3d proc~ocean_halo_face_y_2d ocean_halo_face_y_2d interface~ocean_halo_face_y->proc~ocean_halo_face_y_2d proc~ocean_halo_face_y_3d ocean_halo_face_y_3d interface~ocean_halo_face_y->proc~ocean_halo_face_y_3d proc~drain_rescale_htr_budget->local 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 proc~tracer_advect_zonal_one_impl tracer_advect_zonal_one_impl proc~gm_tracer_advect_x->proc~tracer_advect_zonal_one_impl proc~tracer_advect_meridional_one_impl tracer_advect_meridional_one_impl proc~gm_tracer_advect_y->proc~tracer_advect_meridional_one_impl proc~grow_buffers grow_buffers proc~ocean_fold_begin->proc~grow_buffers to_string to_string proc~ocean_fold_begin->to_string warning warning proc~ocean_fold_begin->warning comm_irecv_real_sp_array_n comm_irecv_real_sp_array_n proc~ocean_fold_exchange->comm_irecv_real_sp_array_n comm_isend_real_sp_array_n comm_isend_real_sp_array_n proc~ocean_fold_exchange->comm_isend_real_sp_array_n proc~comm_env_compute_comm comm_env_compute_comm proc~ocean_fold_exchange->proc~comm_env_compute_comm waitall waitall proc~ocean_fold_exchange->waitall proc~ocean_fold_wrap_centre_3d_state->interface~fold_north_centre proc~ocean_fold_wrap_centre_3d_state->interface~ocean_fold_pack proc~ocean_fold_wrap_centre_3d_state->interface~ocean_fold_unpack proc~ocean_fold_wrap_centre_3d_state->proc~n_tracers proc~ocean_fold_wrap_centre_3d_state->proc~ocean_fold_begin proc~ocean_fold_wrap_centre_3d_state->proc~ocean_fold_end proc~ocean_fold_wrap_centre_3d_state->proc~ocean_fold_exchange proc~ocean_fold_wrap_centre_3d_state->proc~ocean_fold_is_distributed proc~tracer_advect_vertical_one_impl->local comm_world comm_world proc~comm_env_compute_comm->comm_world proc~fold_north_v_face_2d->local proc~fold_north_v_face_3d->local proc~fold_v_2d->interface~fold_north_v_face proc~fold_v_2d->interface~ocean_fold_pack proc~fold_v_2d->interface~ocean_fold_unpack proc~fold_v_2d->proc~ocean_fold_begin proc~fold_v_2d->proc~ocean_fold_end proc~fold_v_2d->proc~ocean_fold_exchange proc~fold_v_2d->proc~ocean_fold_is_distributed proc~fold_stagger_nrows fold_stagger_nrows proc~fold_v_2d->proc~fold_stagger_nrows proc~fold_v_3d->interface~fold_north_v_face proc~fold_v_3d->interface~ocean_fold_pack proc~fold_v_3d->interface~ocean_fold_unpack proc~fold_v_3d->proc~ocean_fold_begin proc~fold_v_3d->proc~ocean_fold_end proc~fold_v_3d->proc~ocean_fold_exchange proc~fold_v_3d->proc~ocean_fold_is_distributed proc~fold_v_3d->proc~fold_stagger_nrows 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 proc~ocean_fold_pack_2d->proc~ocean_fold_pack_3d proc~fold_stagger_family fold_stagger_family proc~ocean_fold_pack_3d->proc~fold_stagger_family proc~ocean_fold_pack_3d->proc~fold_stagger_nrows proc~ocean_fold_unpack_2d->proc~ocean_fold_unpack_3d proc~ocean_fold_unpack_3d->proc~fold_stagger_family proc~ocean_fold_unpack_3d->proc~fold_stagger_nrows proc~ocean_halo_centre_2d_impl ocean_halo_centre_2d_impl proc~ocean_halo_centre_2d->proc~ocean_halo_centre_2d_impl proc~oh_count_centre_2d oh_count_centre_2d proc~ocean_halo_centre_2d->proc~oh_count_centre_2d proc~ocean_halo_centre_3d->proc~ocean_periodic_wrap_centre_3d proc~ocean_halo_centre_3d->comm_irecv_real_sp_array_n proc~ocean_halo_centre_3d->comm_isend_real_sp_array_n proc~ocean_halo_centre_3d->proc~comm_env_compute_comm proc~ocean_halo_centre_3d->waitall proc~ew_rank_east ew_rank_east proc~ocean_halo_centre_3d->proc~ew_rank_east proc~ew_rank_west ew_rank_west proc~ocean_halo_centre_3d->proc~ew_rank_west proc~needs_flags needs_flags proc~ocean_halo_centre_3d->proc~needs_flags proc~ns_rank_north ns_rank_north proc~ocean_halo_centre_3d->proc~ns_rank_north proc~ns_rank_south ns_rank_south proc~ocean_halo_centre_3d->proc~ns_rank_south proc~ocean_halo_buffers_ensure_nz ocean_halo_buffers_ensure_nz proc~ocean_halo_centre_3d->proc~ocean_halo_buffers_ensure_nz proc~oh_count_centre_3d oh_count_centre_3d proc~ocean_halo_centre_3d->proc~oh_count_centre_3d proc~oh_count_msgs oh_count_msgs proc~ocean_halo_centre_3d->proc~oh_count_msgs proc~ocean_halo_face_x_2d_impl ocean_halo_face_x_2d_impl proc~ocean_halo_face_x_2d->proc~ocean_halo_face_x_2d_impl proc~oh_count_face_x_2d oh_count_face_x_2d proc~ocean_halo_face_x_2d->proc~oh_count_face_x_2d proc~ocean_halo_face_x_3d->proc~ocean_periodic_wrap_face_x_3d proc~ocean_halo_face_x_3d->comm_irecv_real_sp_array_n proc~ocean_halo_face_x_3d->comm_isend_real_sp_array_n proc~ocean_halo_face_x_3d->proc~comm_env_compute_comm proc~ocean_halo_face_x_3d->waitall proc~ocean_halo_face_x_3d->proc~ew_rank_east proc~ocean_halo_face_x_3d->proc~ew_rank_west proc~ocean_halo_face_x_3d->proc~needs_flags proc~ocean_halo_face_x_3d->proc~ns_rank_north proc~ocean_halo_face_x_3d->proc~ns_rank_south proc~ocean_halo_face_x_3d->proc~ocean_halo_buffers_ensure_nz proc~oh_count_face_x_3d oh_count_face_x_3d proc~ocean_halo_face_x_3d->proc~oh_count_face_x_3d proc~ocean_halo_face_x_3d->proc~oh_count_msgs proc~ocean_halo_face_y_2d_impl ocean_halo_face_y_2d_impl proc~ocean_halo_face_y_2d->proc~ocean_halo_face_y_2d_impl proc~oh_count_face_y_2d oh_count_face_y_2d proc~ocean_halo_face_y_2d->proc~oh_count_face_y_2d proc~ocean_halo_face_y_3d->proc~ocean_periodic_wrap_face_y_3d proc~ocean_halo_face_y_3d->comm_irecv_real_sp_array_n proc~ocean_halo_face_y_3d->comm_isend_real_sp_array_n proc~ocean_halo_face_y_3d->proc~comm_env_compute_comm proc~ocean_halo_face_y_3d->waitall proc~ocean_halo_face_y_3d->proc~ew_rank_east proc~ocean_halo_face_y_3d->proc~ew_rank_west proc~ocean_halo_face_y_3d->proc~needs_flags proc~ocean_halo_face_y_3d->proc~ns_rank_north proc~ocean_halo_face_y_3d->proc~ns_rank_south proc~ocean_halo_face_y_3d->proc~ocean_halo_buffers_ensure_nz proc~oh_count_face_y_3d oh_count_face_y_3d proc~ocean_halo_face_y_3d->proc~oh_count_face_y_3d proc~ocean_halo_face_y_3d->proc~oh_count_msgs proc~tracer_advect_meridional_one_impl->local proc~ppm_cell_limiter ppm_cell_limiter proc~tracer_advect_meridional_one_impl->proc~ppm_cell_limiter proc~ppm_limited_slope ppm_limited_slope proc~tracer_advect_meridional_one_impl->proc~ppm_limited_slope proc~ppm_mirror_h ppm_mirror_h proc~tracer_advect_meridional_one_impl->proc~ppm_mirror_h proc~tracer_advect_zonal_one_impl->local proc~tracer_advect_zonal_one_impl->proc~ppm_cell_limiter proc~tracer_advect_zonal_one_impl->proc~ppm_limited_slope proc~tracer_advect_zonal_one_impl->proc~ppm_mirror_h proc~decomp_rank_from_coords decomp_rank_from_coords proc~ew_rank_east->proc~decomp_rank_from_coords proc~ew_rank_west->proc~decomp_rank_from_coords proc~ns_rank_north->proc~decomp_rank_from_coords proc~ns_rank_south->proc~decomp_rank_from_coords proc~ocean_halo_buffers_ensure_nz->to_string proc~ocean_halo_buffers_ensure_nz->warning proc~ocean_halo_centre_2d_impl->comm_irecv_real_sp_array_n proc~ocean_halo_centre_2d_impl->comm_isend_real_sp_array_n proc~ocean_halo_centre_2d_impl->proc~comm_env_compute_comm proc~ocean_halo_centre_2d_impl->waitall proc~ocean_halo_centre_2d_impl->proc~ew_rank_east proc~ocean_halo_centre_2d_impl->proc~ew_rank_west proc~ocean_halo_centre_2d_impl->proc~needs_flags proc~ocean_halo_centre_2d_impl->proc~ns_rank_north proc~ocean_halo_centre_2d_impl->proc~ns_rank_south proc~ocean_halo_centre_2d_impl->proc~oh_count_msgs proc~ocean_periodic_wrap_centre_2d ocean_periodic_wrap_centre_2d proc~ocean_halo_centre_2d_impl->proc~ocean_periodic_wrap_centre_2d proc~ocean_halo_face_x_2d_impl->comm_irecv_real_sp_array_n proc~ocean_halo_face_x_2d_impl->comm_isend_real_sp_array_n proc~ocean_halo_face_x_2d_impl->proc~comm_env_compute_comm proc~ocean_halo_face_x_2d_impl->waitall proc~ocean_halo_face_x_2d_impl->proc~ew_rank_east proc~ocean_halo_face_x_2d_impl->proc~ew_rank_west proc~ocean_halo_face_x_2d_impl->proc~needs_flags proc~ocean_halo_face_x_2d_impl->proc~ns_rank_north proc~ocean_halo_face_x_2d_impl->proc~ns_rank_south proc~ocean_halo_face_x_2d_impl->proc~oh_count_msgs proc~ocean_periodic_wrap_face_x_2d ocean_periodic_wrap_face_x_2d proc~ocean_halo_face_x_2d_impl->proc~ocean_periodic_wrap_face_x_2d proc~ocean_halo_face_y_2d_impl->comm_irecv_real_sp_array_n proc~ocean_halo_face_y_2d_impl->comm_isend_real_sp_array_n proc~ocean_halo_face_y_2d_impl->proc~comm_env_compute_comm proc~ocean_halo_face_y_2d_impl->waitall proc~ocean_halo_face_y_2d_impl->proc~ew_rank_east proc~ocean_halo_face_y_2d_impl->proc~ew_rank_west proc~ocean_halo_face_y_2d_impl->proc~needs_flags proc~ocean_halo_face_y_2d_impl->proc~ns_rank_north proc~ocean_halo_face_y_2d_impl->proc~ns_rank_south proc~ocean_halo_face_y_2d_impl->proc~oh_count_msgs proc~ocean_periodic_wrap_face_y_2d ocean_periodic_wrap_face_y_2d proc~ocean_halo_face_y_2d_impl->proc~ocean_periodic_wrap_face_y_2d

Called by

proc~~run_gm_step~~CalledByGraph proc~run_gm_step run_gm_step 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
real(kind=wp), private :: budget_w
logical, private :: is_eulerian
integer, private :: tr_mode
logical, private :: use_ext

Source Code

   subroutine run_gm_step(grid, metrics, dyn, ct, va, ms, dt, gm, slopes, varmix, &
                          wavespeed, vcoord, bc)
      !! Gent-McWilliams thickness diffusion as its OWN sequential operator,
      !! run once per outer step AFTER the dynamics (the stage loop and, under
      !! ssp_rk2, the stage average) — where MOM6 calls `thickness_diffuse`
      !! after `step_MOM_dyn_split_RK2`, every dynamics step:
      !!
      !!   1. `gm_compute_transports` fills `uhD`/`vhD` + `gm_src` from the
      !!      thickness the dynamics LEFT, with the stored slopes and the
      !!      VarMix/MEKE base KhTh refreshed at the top of the step;
      !!   2. `continuity_gm_apply` moves `h_layer` and every tracer by them
      !!      with the same `dt` — so the per-face availability cap
      !!      `A·(h − H_VANISHED)/(4·dt)` bounds what is actually there;
      !!   3. `eulerian_z` only: the bolus divergence is cancelled per layer by
      !!      the vertical advection, exactly as the resolved one is;
      !!   4. the h / tracer ghosts are refreshed (exchange, periodic wrap,
      !!      fold), as after the resolved continuity.
      !!
      !! Until 2026-10 the transports were computed at the top of the step
      !! from the stage-entry thickness and FOLDED into the resolved
      !! continuity sweeps; the cap then bounded the wrong `h` and a partial
      !! bed cell on an open z* step was driven negative (`rdb_ocean_gm`).
      !!
      !! Cadence: every outer step, with the outer `dt` (MOM6: every
      !! dynamics step).  The fold path applied GM on thermo steps only, so
      !! under `dt_therm_ratio > 1` it ran at 1/ratio of its strength.
      !! No-op when GM is absent / disabled, the slopes slot is absent, or
      !! thermodynamics is off.
      type(hgrid_t), intent(in) :: grid
      type(ocean_metrics_t), intent(in) :: metrics
      type(ocean_dyn_t), intent(inout) :: dyn
      type(continuity_t), intent(inout) :: ct
      type(ocean_vertical_advection_t), intent(inout) :: va
      type(multilayer_state_t), intent(inout) :: ms
      real(wp), intent(in) :: dt
      type(ocean_gm_t), intent(inout), optional :: gm
      type(ocean_slopes_t), intent(inout), optional :: slopes
      type(ocean_varmix_t), intent(inout), optional :: varmix
      type(ocean_wave_speed_t), intent(inout), optional :: wavespeed
      type(ocean_vcoord_t), intent(in), optional :: vcoord
      type(ocean_bc_state_t), intent(inout), optional :: bc

      integer :: tr_mode
      logical :: use_ext, is_eulerian
      real(wp) :: budget_w

      if (.not. present(gm)) return
      if (.not. present(slopes)) return
      if (.not. gm%enable) return
      if (.not. dyn%enable_thermodynamics) return

      call profiler_start("ocean_gm")
      use_ext = .false.
      if (present(varmix) .and. present(wavespeed)) use_ext = varmix%enable
      if (use_ext) then
         call gm_compute_transports(grid, metrics, gm, slopes, ms, dt, &
                                    khth_ext_u=varmix%khth_u, khth_ext_v=varmix%khth_v)
      else
         call gm_compute_transports(grid, metrics, gm, slopes, ms, dt)
      end if

      tr_mode = TR_MODE_ADVECT
      if (dyn%dt_tracer_advect_ratio > 1) tr_mode = TR_MODE_ACCUMULATE
      ! Post-average budget weight: the console multiplies the heat/salt
      ! accumulators by `ocean_budget_stage_weight` (0.5 ssp_rk2, 1
      ! pred_corr); this operator runs once, after the average.
      budget_w = 1.0_wp/ocean_budget_stage_weight(dyn%split_scheme == SPLIT_SCHEME_PRED_CORR)
      is_eulerian = .false.
      if (present(vcoord)) is_eulerian = vcoord%coord_type == VCOORD_EULERIAN_Z
      if (present(bc)) then
         call continuity_gm_apply(grid, metrics, ct, ms, gm, dt, budget_w, tr_mode, bc=bc, &
                                  set_flux_h=is_eulerian)
      else
         call continuity_gm_apply(grid, metrics, ct, ms, gm, dt, budget_w, tr_mode, &
                                  set_flux_h=is_eulerian)
      end if
      if (is_eulerian) then
         ! Pin the Eulerian layers: the vertical w-divergence cancels the
         ! bolus divergence `continuity_gm_apply` left in `flux_h_layer`,
         ! carrying the tracers with it.  Column-local, so it runs BEFORE
         ! the ghost refresh below: a ghost column's `flux_h_layer` is the
         ! tile's own (the outermost ghost face carries no bolus), not its
         ! owner's, so a ghost advanced here and NOT refreshed afterwards
         ! made the step depend on where the seam fell (eulerian_z cells of
         ! the compatibility matrix's DECOMP leg).
         call compute_w_from_continuity(grid, va, ms)
         call tracer_advect_vertical(grid, va, ms, dt)
      end if
      call ocean_halo_exchange_ml_state(ms)
      if (present(bc)) then
         call ocean_periodic_wrap_state(grid, bc, ms, skip_x=ocean_halo_is_decomposed_x(), &
                                        skip_y=ocean_halo_is_decomposed_y())
         call ocean_fold_wrap_state(grid, bc, ms)
      end if
      if (dyn%check_h_positive) then
         call check_h_positive_or_die(grid, ms, "after the GM operator", 3, &
                                      dyn%outer_step_count + 1, check_layers=.true.)
      end if
      call profiler_stop("ocean_gm")
      call probe_dS(grid, ms, "after GM", 3, dyn%outer_step_count + 1)
   end subroutine run_gm_step