ice_evp_step Subroutine

public subroutine ice_evp_step(grid, metrics, f_corner, ice, ms, dt_slow, par, bc, dt_transport, n_trunc)

Gathers mis/mice/ci from the category state (mode-branched, mirrors PR 4b’s IST->CAS dispatch), pulls the one-step-lagged ocean surface velocity, and calls ice_evp_dynamics on ice%u_ice/v_ice/str_d/str_t/str_s/fxoc/fyoc. No-op when the ice slot is not live or dynamics is off (defence-in-depth; the driver already gates this call on ice%dynamics).

DEVIATION from SPEC §4.1’s literal signature: par is an explicit argument here (the spec’s shim signature omits it, but the shim has no other route to &ocean_ice_nml — the driver builds par ONCE via ice_evp_params_from_config and passes it into every call, which is both cheaper and clearer than a hidden module-level singleton).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
real(kind=wp), intent(in) :: f_corner(:,:)

Coriolis parameter at corners, shape (nx+1,ny+1) (coriolis_adv_t%f_corner).

type(ocean_sea_ice_t), intent(inout) :: ice
type(multilayer_state_t), intent(in) :: ms
real(kind=wp), intent(in) :: dt_slow
type(ice_evp_params_t), intent(in) :: par
type(ocean_bc_state_t), intent(in) :: bc

Edge policy: periodic_x/_y (wrap) and has_west/_east/_south/ _north (physical edge vs MPI seam). A ghost band is pinned to land only on a physical, non-periodic edge; on a decomposed axis the halo fills it (see D6 in the module docstring).

real(kind=wp), intent(in), optional :: dt_transport

PR 36: the dt the TRANSPORT step will actually consume (ocean_dyn%therm_dt(dt)), NOT this call’s dt_slow — EVP runs every outer step, transport at thermo cadence. Absent => dt_slow (read only when par%cfl_trunc > 0).

integer, intent(out), optional :: n_trunc

PR 36: count of ice-bearing faces the final CFL clip touched (0 when par%cfl_trunc <= 0). Mirrors ice_transport_step’s ok idiom — the caller (driver) logs, this module does not.


Calls

proc~~ice_evp_step~~CallsGraph proc~ice_evp_step ice_evp_step proc~ice_cell_concentration_impl ice_cell_concentration_impl proc~ice_evp_step->proc~ice_cell_concentration_impl proc~ice_evp_dynamics ice_evp_dynamics proc~ice_evp_step->proc~ice_evp_dynamics proc~ocean_halo_is_decomposed_x ocean_halo_is_decomposed_x proc~ice_evp_step->proc~ocean_halo_is_decomposed_x proc~ocean_halo_is_decomposed_y ocean_halo_is_decomposed_y proc~ice_evp_step->proc~ocean_halo_is_decomposed_y local local proc~ice_cell_concentration_impl->local proc~ice_evp_dynamics_impl ice_evp_dynamics_impl proc~ice_evp_dynamics->proc~ice_evp_dynamics_impl interface~ocean_halo_face_x ocean_halo_face_x proc~ice_evp_dynamics_impl->interface~ocean_halo_face_x interface~ocean_halo_face_y ocean_halo_face_y proc~ice_evp_dynamics_impl->interface~ocean_halo_face_y proc~evp_average_stress_impl evp_average_stress_impl proc~ice_evp_dynamics_impl->proc~evp_average_stress_impl proc~evp_build_masks_impl evp_build_masks_impl proc~ice_evp_dynamics_impl->proc~evp_build_masks_impl proc~evp_copy_u_impl evp_copy_u_impl proc~ice_evp_dynamics_impl->proc~evp_copy_u_impl proc~evp_fill_cell_fields_impl evp_fill_cell_fields_impl proc~ice_evp_dynamics_impl->proc~evp_fill_cell_fields_impl proc~evp_mi_face_impl evp_mi_face_impl proc~ice_evp_dynamics_impl->proc~evp_mi_face_impl proc~evp_pres_mice_impl evp_pres_mice_impl proc~ice_evp_dynamics_impl->proc~evp_pres_mice_impl proc~evp_project_ci_impl evp_project_ci_impl proc~ice_evp_dynamics_impl->proc~evp_project_ci_impl proc~evp_q_and_mi_ratio_impl evp_q_and_mi_ratio_impl proc~ice_evp_dynamics_impl->proc~evp_q_and_mi_ratio_impl proc~evp_sh_dd_dt_impl evp_sh_dd_dt_impl proc~ice_evp_dynamics_impl->proc~evp_sh_dd_dt_impl proc~evp_sh_ds_impl evp_sh_ds_impl proc~ice_evp_dynamics_impl->proc~evp_sh_ds_impl proc~evp_str_s_relax_impl evp_str_s_relax_impl proc~ice_evp_dynamics_impl->proc~evp_str_s_relax_impl proc~evp_stress_relax_impl evp_stress_relax_impl proc~ice_evp_dynamics_impl->proc~evp_stress_relax_impl proc~evp_truncate_final_impl evp_truncate_final_impl proc~ice_evp_dynamics_impl->proc~evp_truncate_final_impl proc~evp_truncate_velocity_impl evp_truncate_velocity_impl proc~ice_evp_dynamics_impl->proc~evp_truncate_velocity_impl proc~evp_u_momentum_impl evp_u_momentum_impl proc~ice_evp_dynamics_impl->proc~evp_u_momentum_impl proc~evp_v_momentum_impl evp_v_momentum_impl proc~ice_evp_dynamics_impl->proc~evp_v_momentum_impl proc~evp_wrap_corner_impl evp_wrap_corner_impl proc~ice_evp_dynamics_impl->proc~evp_wrap_corner_impl proc~evp_zero_massless_velocity_impl evp_zero_massless_velocity_impl proc~ice_evp_dynamics_impl->proc~evp_zero_massless_velocity_impl proc~evp_zero_stress_impl evp_zero_stress_impl proc~ice_evp_dynamics_impl->proc~evp_zero_stress_impl proc~evp_zeta_impl evp_zeta_impl proc~ice_evp_dynamics_impl->proc~evp_zeta_impl proc~ice_limit_stresses ice_limit_stresses proc~ice_evp_dynamics_impl->proc~ice_limit_stresses proc~ocean_periodic_wrap_centre_2d ocean_periodic_wrap_centre_2d proc~ice_evp_dynamics_impl->proc~ocean_periodic_wrap_centre_2d proc~ocean_periodic_wrap_face_x_2d ocean_periodic_wrap_face_x_2d proc~ice_evp_dynamics_impl->proc~ocean_periodic_wrap_face_x_2d proc~ocean_periodic_wrap_face_y_2d ocean_periodic_wrap_face_y_2d proc~ice_evp_dynamics_impl->proc~ocean_periodic_wrap_face_y_2d 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~evp_build_masks_impl->local proc~evp_build_masks_impl->proc~ocean_periodic_wrap_centre_2d proc~evp_pres_mice_impl->local proc~evp_project_ci_impl->local proc~evp_q_and_mi_ratio_impl->local proc~ice_evp_mi_ratio_point ice_evp_mi_ratio_point proc~evp_q_and_mi_ratio_impl->proc~ice_evp_mi_ratio_point proc~evp_sh_ds_impl->local proc~evp_str_s_relax_impl->local proc~evp_truncate_final_impl->local reduce reduce proc~evp_truncate_final_impl->reduce proc~evp_truncate_velocity_impl->local proc~evp_u_momentum_impl->local proc~evp_v_momentum_impl->local proc~evp_zero_massless_velocity_impl->local proc~evp_zeta_impl->local proc~ice_limit_stresses->local 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 comm_irecv_real_sp_array_n comm_irecv_real_sp_array_n proc~ocean_halo_face_x_3d->comm_irecv_real_sp_array_n comm_isend_real_sp_array_n comm_isend_real_sp_array_n proc~ocean_halo_face_x_3d->comm_isend_real_sp_array_n proc~comm_env_compute_comm comm_env_compute_comm proc~ocean_halo_face_x_3d->proc~comm_env_compute_comm proc~ew_rank_east ew_rank_east proc~ocean_halo_face_x_3d->proc~ew_rank_east proc~ew_rank_west ew_rank_west proc~ocean_halo_face_x_3d->proc~ew_rank_west proc~needs_flags needs_flags proc~ocean_halo_face_x_3d->proc~needs_flags proc~ns_rank_north ns_rank_north proc~ocean_halo_face_x_3d->proc~ns_rank_north proc~ns_rank_south ns_rank_south proc~ocean_halo_face_x_3d->proc~ns_rank_south proc~ocean_halo_buffers_ensure_nz ocean_halo_buffers_ensure_nz proc~ocean_halo_face_x_3d->proc~ocean_halo_buffers_ensure_nz proc~ocean_periodic_wrap_face_x_3d ocean_periodic_wrap_face_x_3d proc~ocean_halo_face_x_3d->proc~ocean_periodic_wrap_face_x_3d proc~oh_count_face_x_3d oh_count_face_x_3d proc~ocean_halo_face_x_3d->proc~oh_count_face_x_3d proc~oh_count_msgs oh_count_msgs proc~ocean_halo_face_x_3d->proc~oh_count_msgs waitall waitall proc~ocean_halo_face_x_3d->waitall 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->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->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~ocean_periodic_wrap_face_y_3d ocean_periodic_wrap_face_y_3d proc~ocean_halo_face_y_3d->proc~ocean_periodic_wrap_face_y_3d 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~ocean_halo_face_y_3d->waitall

Called by

proc~~ice_evp_step~~CalledByGraph proc~ice_evp_step ice_evp_step proc~engine_step_ice engine_step_ice proc~engine_step_ice->proc~ice_evp_step proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_step_ice proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step_ice proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean

Variables

Type Visibility Attributes Name Initial
logical, private :: halo_x
logical, private :: halo_y
integer, private :: nx
integer, private :: ny
integer, private :: nz

Source Code

   subroutine ice_evp_step(grid, metrics, f_corner, ice, ms, dt_slow, par, &
                           bc, dt_transport, n_trunc)
      !! Gathers `mis`/`mice`/`ci` from the category state (mode-branched,
      !! mirrors PR 4b's IST->CAS dispatch), pulls the one-step-lagged
      !! ocean surface velocity, and calls `ice_evp_dynamics` on
      !! `ice%u_ice/v_ice/str_d/str_t/str_s/fxoc/fyoc`.  No-op when the
      !! ice slot is not live or `dynamics` is off (defence-in-depth; the
      !! driver already gates this call on `ice%dynamics`).
      !!
      !! DEVIATION from SPEC §4.1's literal signature: `par` is an
      !! explicit argument here (the spec's shim signature omits it, but
      !! the shim has no other route to `&ocean_ice_nml` — the driver
      !! builds `par` ONCE via `ice_evp_params_from_config` and passes it
      !! into every call, which is both cheaper and clearer than a hidden
      !! module-level singleton).
      type(hgrid_t), intent(in) :: grid
      type(ocean_metrics_t), intent(in) :: metrics
      real(wp), intent(in) :: f_corner(:, :)
         !! Coriolis parameter at corners, shape (nx+1,ny+1) (`coriolis_adv_t%f_corner`).
      type(ocean_sea_ice_t), intent(inout) :: ice
      type(multilayer_state_t), intent(in) :: ms
      real(wp), intent(in) :: dt_slow
      type(ice_evp_params_t), intent(in) :: par
      type(ocean_bc_state_t), intent(in) :: bc
         !! Edge policy: `periodic_x/_y` (wrap) and `has_west/_east/_south/
         !! _north` (physical edge vs MPI seam).  A ghost band is pinned to
         !! land only on a physical, non-periodic edge; on a decomposed axis
         !! the halo fills it (see D6 in the module docstring).
      real(wp), intent(in), optional :: dt_transport
         !! PR 36: the dt the TRANSPORT step will actually consume
         !! (`ocean_dyn%therm_dt(dt)`), NOT this call's `dt_slow` — EVP
         !! runs every outer step, transport at thermo cadence. Absent =>
         !! `dt_slow` (read only when `par%cfl_trunc > 0`).
      integer, intent(out), optional :: n_trunc
         !! PR 36: count of ice-bearing faces the final CFL clip touched
         !! (`0` when `par%cfl_trunc <= 0`). Mirrors `ice_transport_step`'s
         !! `ok` idiom — the caller (driver) logs, this module does not.

      integer :: nx, ny, nz
      logical :: halo_x, halo_y

      if (.not. ice%is_init .or. .not. ice%dynamics) then
         if (present(n_trunc)) n_trunc = 0
         return
      end if

      ! An axis split across ranks is the halo's: exchange there, and run
      ! the local periodic wrap only on an axis it does not own.
      halo_x = ocean_halo_is_decomposed_x()
      halo_y = ocean_halo_is_decomposed_y()

      nx = grid%nx_total
      ny = grid%ny_total
      nz = ms%nz_ml

      ! F3: gather into the dedicated INPUT buffers on the workspace slot,
      ! distinct from the `mis_w`/`mice_w`/`ci_w` that `ice_evp_dynamics`
      ! fills from these — no dummy-argument aliasing.
      call ice_cell_concentration_impl(metrics%wet_T, ice%part_size, ice%m_ice, &
                                       ice%m_snow, ice%evp_ws%mis_in_w, ice%evp_ws%mice_in_w, &
                                       ice%evp_ws%ci_in_w, ice%ncat, nx, ny)

      call ice_evp_dynamics(grid, metrics, f_corner, ice%evp_ws%mis_in_w, &
                            ice%evp_ws%mice_in_w, ice%evp_ws%ci_in_w, &
                            ms%u_face_x_layer(:, :, nz), ms%v_face_y_layer(:, :, nz), &
                            ice%tau_a_x, ice%tau_a_y, ice%u_ice, ice%v_ice, &
                            ice%str_d, ice%str_t, ice%str_s, ice%fxoc, ice%fyoc, &
                            dt_slow, par, bc%periodic_x, bc%periodic_y, ice%evp_ws, &
                            dt_transport, n_trunc, halo_x=halo_x, halo_y=halo_y, &
                            land_w=bc%has_west .and. .not. bc%periodic_x, &
                            land_e=bc%has_east .and. .not. bc%periodic_x, &
                            land_s=bc%has_south .and. .not. bc%periodic_y, &
                            land_n=bc%has_north .and. .not. bc%periodic_y)
   end subroutine ice_evp_step