ocean_cavity_flux_step Subroutine

public subroutine ocean_cavity_flux_step(grid, cav, metrics, ms, eos, sf, active)

Uses

  • proc~~ocean_cavity_flux_step~~UsesGraph proc~ocean_cavity_flux_step ocean_cavity_flux_step module~rdb_error_ring rdb_error_ring proc~ocean_cavity_flux_step->module~rdb_error_ring module~rdb_ocean_status rdb_ocean_status proc~ocean_cavity_flux_step->module~rdb_ocean_status pic_logger pic_logger proc~ocean_cavity_flux_step->pic_logger pic_strings pic_strings proc~ocean_cavity_flux_step->pic_strings module~rdb_error_ring->pic_logger

One cavity basal-melt update: sample the far field, solve the three-equation interface on every covered column, deliver the two owned surface-flux components, and account for the solver status.

CADENCE + PLACEMENT. Called once per outer step at THERMO cadence from engine_step_finalize, immediately BEFORE ocean_surface_flux_assemble — the assembler must see the components this routine writes. The tracers then integrate the assembled Q_heat/Q_salt on the NEXT outer step, which is the same one-step lag the sea-ice coupler documents.

NON-pure, and it is the only non-pure procedure this module adds: it logs (n_not_converged warnings) and it FAILS LOUD on a non-finite column. Its three kernels are all pure.

mem:separate: every array read or written here is mapped by its owning slot’s enter_data. ms%tracers(idx)%hTr is dereferenced on the HOST before the kernels (the outer-shim rule for the array-of-derived-types registry).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid

Horizontal grid (for nx_total/ny_total).

type(ocean_cavity_flux_t), intent(inout) :: cav

The cavity-melt slot.

type(ocean_metrics_t), intent(in) :: metrics

Reads cover_frac only.

type(multilayer_state_t), intent(in) :: ms

Reads h_layer, the S/T tracer loads, the face velocities, p_top (THE interface pressure) and wet_mask.

type(eos_t), intent(in) :: eos

Shared EOS handle — the liquidus. Flat POD, by value.

type(ocean_surface_flux_t), intent(inout) :: sf

Writes heat_cavity/salt_cavity and latches has_heat/has_salt host-side.

logical, intent(in), optional :: active

Thermo-cadence gate. Present-and-false ⇒ early return; absent ⇒ run (the ocean_surface_flux_assemble convention).


Calls

proc~~ocean_cavity_flux_step~~CallsGraph proc~ocean_cavity_flux_step ocean_cavity_flux_step proc~cavity_far_field_impl cavity_far_field_impl proc~ocean_cavity_flux_step->proc~cavity_far_field_impl proc~cavity_flux_fill_impl cavity_flux_fill_impl proc~ocean_cavity_flux_step->proc~cavity_flux_fill_impl proc~cavity_melt_columns_2d cavity_melt_columns_2d proc~ocean_cavity_flux_step->proc~cavity_melt_columns_2d proc~cavity_melt_status_is_fatal cavity_melt_status_is_fatal proc~ocean_cavity_flux_step->proc~cavity_melt_status_is_fatal proc~cavity_status_counts_impl cavity_status_counts_impl proc~ocean_cavity_flux_step->proc~cavity_status_counts_impl proc~fail fail proc~ocean_cavity_flux_step->proc~fail to_string to_string proc~ocean_cavity_flux_step->to_string warning warning proc~ocean_cavity_flux_step->warning local local proc~cavity_far_field_impl->local proc~cavity_melt_columns_2d->local proc~cavity_melt_point_gamma_f cavity_melt_point_gamma_f proc~cavity_melt_columns_2d->proc~cavity_melt_point_gamma_f proc~cavity_ustar cavity_ustar proc~cavity_melt_columns_2d->proc~cavity_ustar reduce reduce proc~cavity_status_counts_impl->reduce error error proc~fail->error proc~error_ring_push error_ring_push proc~fail->proc~error_ring_push proc~cavity_solve_melt_f cavity_solve_melt_f proc~cavity_melt_point_gamma_f->proc~cavity_solve_melt_f proc~cavity_heat_fluxes cavity_heat_fluxes proc~cavity_solve_melt_f->proc~cavity_heat_fluxes proc~cavity_law_is_implicit cavity_law_is_implicit proc~cavity_solve_melt_f->proc~cavity_law_is_implicit proc~cavity_obukhov_length cavity_obukhov_length proc~cavity_solve_melt_f->proc~cavity_obukhov_length proc~cavity_outer_residual cavity_outer_residual proc~cavity_solve_melt_f->proc~cavity_outer_residual proc~cavity_safe_state cavity_safe_state proc~cavity_solve_melt_f->proc~cavity_safe_state proc~cavity_solution_reset cavity_solution_reset proc~cavity_solve_melt_f->proc~cavity_solution_reset proc~cavity_state_at_x cavity_state_at_x proc~cavity_solve_melt_f->proc~cavity_state_at_x proc~eos_freezing_point eos_freezing_point proc~cavity_solve_melt_f->proc~eos_freezing_point proc~cavity_ice_terms cavity_ice_terms proc~cavity_heat_fluxes->proc~cavity_ice_terms proc~cavity_t_ice cavity_t_ice proc~cavity_heat_fluxes->proc~cavity_t_ice proc~cavity_l_plus_is_neutral cavity_l_plus_is_neutral proc~cavity_outer_residual->proc~cavity_l_plus_is_neutral proc~cavity_safe_state->proc~eos_freezing_point proc~cavity_state_at_x->proc~cavity_safe_state proc~cavity_buoyancy_flux cavity_buoyancy_flux proc~cavity_state_at_x->proc~cavity_buoyancy_flux proc~cavity_exchange_velocities_f cavity_exchange_velocities_f proc~cavity_state_at_x->proc~cavity_exchange_velocities_f proc~cavity_l_plus_from_state cavity_l_plus_from_state proc~cavity_state_at_x->proc~cavity_l_plus_from_state proc~cavity_three_equation cavity_three_equation proc~cavity_state_at_x->proc~cavity_three_equation

Called by

proc~~ocean_cavity_flux_step~~CalledByGraph proc~ocean_cavity_flux_step ocean_cavity_flux_step proc~engine_step_finalize engine_step_finalize proc~engine_step_finalize->proc~ocean_cavity_flux_step proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_step_finalize proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step_finalize proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean

Variables

Type Visibility Attributes Name Initial
integer, private :: idx_s
integer, private :: idx_t
integer, private :: nx
integer, private :: ny
integer, private :: nz

Source Code

   subroutine ocean_cavity_flux_step(grid, cav, metrics, ms, eos, sf, active)
      !! One cavity basal-melt update: sample the far field, solve the
      !! three-equation interface on every covered column, deliver the
      !! two owned surface-flux components, and account for the solver
      !! status.
      !!
      !! CADENCE + PLACEMENT.  Called once per outer step at THERMO
      !! cadence from `engine_step_finalize`, immediately BEFORE
      !! `ocean_surface_flux_assemble` — the assembler must see the
      !! components this routine writes.  The tracers then integrate the
      !! assembled `Q_heat`/`Q_salt` on the NEXT outer step, which is the
      !! same one-step lag the sea-ice coupler documents.
      !!
      !! NON-`pure`, and it is the only non-pure procedure this module
      !! adds: it logs (`n_not_converged` warnings) and it FAILS LOUD on
      !! a non-finite column.  Its three kernels are all `pure`.
      !!
      !! `mem:separate`: every array read or written here is mapped by
      !! its owning slot's `enter_data`.  `ms%tracers(idx)%hTr` is
      !! dereferenced on the HOST before the kernels (the outer-shim
      !! rule for the array-of-derived-types registry).
      use pic_logger, only: global_logger
      use pic_strings, only: to_string
      use rdb_error_ring, only: fail
      use rdb_ocean_status, only: OCEAN_STATUS_ERR_SETUP
      type(hgrid_t), intent(in) :: grid
         !! Horizontal grid (for `nx_total`/`ny_total`).
      type(ocean_cavity_flux_t), intent(inout) :: cav
         !! The cavity-melt slot.
      type(ocean_metrics_t), intent(in) :: metrics
         !! Reads `cover_frac` only.
      type(multilayer_state_t), intent(in) :: ms
         !! Reads `h_layer`, the S/T tracer loads, the face velocities,
         !! `p_top` (THE interface pressure) and `wet_mask`.
      type(eos_t), intent(in) :: eos
         !! Shared EOS handle — the liquidus.  Flat POD, by value.
      type(ocean_surface_flux_t), intent(inout) :: sf
         !! Writes `heat_cavity`/`salt_cavity` and latches
         !! `has_heat`/`has_salt` host-side.
      logical, intent(in), optional :: active
         !! Thermo-cadence gate.  Present-and-false ⇒ early return;
         !! absent ⇒ run (the `ocean_surface_flux_assemble` convention).
      integer :: nx, ny, nz, idx_t, idx_s

      if (.not. cav%is_init) return
      if (.not. cav%enable) return
      if (present(active)) then
         if (.not. active) return
      end if
      if (.not. allocated(ms%tracers)) return
      idx_t = ms%idx_temperature
      idx_s = ms%idx_salinity
      if (idx_t <= 0 .or. idx_s <= 0) return

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

      call cavity_far_field_impl(nx, ny, nz, cav%far_field_depth, &
                                 metrics%cover_frac, ms%wet_mask, ms%h_layer, &
                                 ms%tracers(idx_t)%hTr, ms%tracers(idx_s)%hTr, &
                                 ms%u_face_x_layer, ms%v_face_y_layer, &
                                 cav%active, cav%t_far, cav%s_far, cav%u_far, cav%v_far)

      call cavity_melt_columns_2d(nx, ny, cav%active, cav%t_far, cav%s_far, ms%p_top, &
                                  cav%u_far, cav%v_far, cav%s_ice, cav%f_cor, &
                                  cav%cdrag_top, cav%u_tide, cav%ustar_min, &
                                  cav%par, cav%ice, eos, cav%const, &
                                  cav%ustar, cav%t_b, cav%s_b, cav%melt, cav%q_ocean, &
                                  cav%gamma_t, cav%gamma_s, cav%status)

      call cavity_flux_fill_impl(nx, ny, cav%s_ice, cav%active, cav%melt, cav%q_ocean, &
                                 cav%s_far, sf%heat_cavity, sf%salt_cavity)

      ! The filler's own obligations (PR-12 fill contract): latch the
      ! has_* flags HOST-side, never from a device reduction.  They stay
      ! latched for the rest of the run — the melt rate can legitimately
      ! pass through zero, and un-latching there would change the
      ! apply-path operand count mid-run.
      sf%has_heat = .true.
      sf%has_salt = .true.

      call cavity_status_counts_impl(nx, ny, cav%active, cav%status, &
                                     cav%n_nonfinite_step, cav%n_not_converged_step, &
                                     cav%n_no_root_step, cav%n_other_step)
      cav%n_not_converged_total = cav%n_not_converged_total &
                                  + int(cav%n_not_converged_step, int64)
      cav%n_no_root_total = cav%n_no_root_total + int(cav%n_no_root_step, int64)
      cav%n_other_total = cav%n_other_total + int(cav%n_other_step, int64)

      if (cavity_melt_status_is_fatal(cav%n_nonfinite_step)) then
         call fail("&ocean_cavity_melt_nml: "//to_string(cav%n_nonfinite_step)// &
                   " ice-covered column(s) fed the basal-melt solver a non-finite "// &
                   "far-field temperature, salinity, velocity or interface pressure "// &
                   "(CAVITY_MELT_NONFINITE_*).  The kernel's safe state is zero melt, "// &
                   "which would hide an already-corrupt column behind a plausible "// &
                   "run, so this is fatal.  NOT_CONVERGED / NO_PHYSICAL_ROOT are "// &
                   "counted and warned instead.", code=OCEAN_STATUS_ERR_SETUP)
      end if

      if (cav%n_not_converged_step > 0 .or. cav%n_no_root_step > 0 .or. &
          cav%n_other_step > 0) then
         call global_logger%warning("cavity melt: zero melt applied on "// &
                                    to_string(cav%n_not_converged_step)// &
                                    " non-converged, "//to_string(cav%n_no_root_step)// &
                                    " no-physical-root and "// &
                                    to_string(cav%n_other_step)// &
                                    " otherwise-refused column(s) this step")
      end if
   end subroutine ocean_cavity_flux_step