refuse_open_zfixed_staircase Subroutine

private subroutine refuse_open_zfixed_staircase(ocean_state, grid, ierr)

The zfixed_closed_faces = .false. leg of configure_ocean_closed_faces: refuse vcoord_type = "z_fixed" with OPEN staircase faces over a STEPPED bed.

A face where the two columns’ bed falls in different nominal z_fixed layers pairs a live layer with a bed filler. Left open, the FV pressure gradient across that step drives |ρ′|·g·Δz_step/(ρ₀·dx) out of rest whatever the filler thickness — measured on the 1° Southern Ocean: u ≈ 250 m/s by step 3, 4e9 m/s on the filler faces, h → −2e9, the first non-finite in post_bt, with or without any closure. That is the case the closed-face mask exists for, so the combination fails loud here instead of blowing up three steps in.

A flat or step-free bed is ACCEPTED untouched (no state is written, so it stays bit-identical), and so is every coordinate but z_fixed. Top-side (ice-draft) steps are not counted.

MPI: each rank counts its OWNED faces off the same GHOST-FILLED bt_H_ref / z_top the mask builder reads (so a tile-seam step is seen by exactly one rank) and the count is summed over the compute communicator, so every rank takes the same decision. Every early return is on rank-uniform state, so either all ranks reach the collective or none does.

Arguments

Type IntentOptional Attributes Name
type(ocean_state_t), intent(in) :: ocean_state
type(hgrid_t), intent(in) :: grid
integer, intent(out), optional :: ierr

Calls

proc~~refuse_open_zfixed_staircase~~CallsGraph proc~refuse_open_zfixed_staircase refuse_open_zfixed_staircase proc~fail fail proc~refuse_open_zfixed_staircase->proc~fail proc~halo_allreduce_sum halo_allreduce_sum proc~refuse_open_zfixed_staircase->proc~halo_allreduce_sum proc~ocean_vcoord_count_bed_steps ocean_vcoord_count_bed_steps proc~refuse_open_zfixed_staircase->proc~ocean_vcoord_count_bed_steps proc~ocean_vcoord_z_fixed_target ocean_vcoord_z_fixed_target proc~refuse_open_zfixed_staircase->proc~ocean_vcoord_z_fixed_target to_string to_string proc~refuse_open_zfixed_staircase->to_string error error proc~fail->error proc~error_ring_push error_ring_push proc~fail->proc~error_ring_push allreduce allreduce proc~halo_allreduce_sum->allreduce proc~comm_env_compute_comm comm_env_compute_comm proc~halo_allreduce_sum->proc~comm_env_compute_comm none~bed_layer bed_layer proc~ocean_vcoord_count_bed_steps->none~bed_layer local local proc~ocean_vcoord_z_fixed_target->local comm_world comm_world proc~comm_env_compute_comm->comm_world

Called by

proc~~refuse_open_zfixed_staircase~~CalledByGraph proc~refuse_open_zfixed_staircase refuse_open_zfixed_staircase proc~configure_ocean_closed_faces configure_ocean_closed_faces proc~configure_ocean_closed_faces->proc~refuse_open_zfixed_staircase proc~engine_setup engine_setup proc~engine_setup->proc~configure_ocean_closed_faces proc~complete_ocean_create complete_ocean_create proc~complete_ocean_create->proc~engine_setup proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_setup proc~driver_validate driver_validate proc~driver_validate->proc~engine_setup proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean proc~rdb_ocean_create_finalize rdb_ocean_create_finalize proc~rdb_ocean_create_finalize->proc~complete_ocean_create proc~rdb_ocean_create_from_string rdb_ocean_create_from_string proc~rdb_ocean_create_from_string->proc~complete_ocean_create

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private, allocatable :: eta0(:,:)
real(kind=wp), private :: h_nominal
integer, private :: n_local
integer, private :: ng
integer, private :: nx
integer, private :: ny
integer, private :: nz
real(kind=wp), private :: steps_global
real(kind=wp), private :: steps_local
real(kind=wp), private, allocatable :: tgt(:,:,:)

Source Code

   subroutine refuse_open_zfixed_staircase(ocean_state, grid, ierr)
      !! The `zfixed_closed_faces = .false.` leg of
      !! `configure_ocean_closed_faces`: refuse `vcoord_type = "z_fixed"`
      !! with OPEN staircase faces over a STEPPED bed.
      !!
      !! A face where the two columns' bed falls in different nominal
      !! `z_fixed` layers pairs a live layer with a bed filler.  Left
      !! open, the FV pressure gradient across that step drives
      !! `|ρ′|·g·Δz_step/(ρ₀·dx)` out of rest whatever the filler
      !! thickness — measured on the 1° Southern Ocean: u ≈ 250 m/s by
      !! step 3, 4e9 m/s on the filler faces, `h → −2e9`, the first
      !! non-finite in `post_bt`, with or without any closure.  That is
      !! the case the closed-face mask exists for, so the combination
      !! fails loud here instead of blowing up three steps in.
      !!
      !! A flat or step-free bed is ACCEPTED untouched (no state is
      !! written, so it stays bit-identical), and so is every coordinate
      !! but `z_fixed`.  Top-side (ice-draft) steps are not counted.
      !!
      !! MPI: each rank counts its OWNED faces off the same GHOST-FILLED
      !! `bt_H_ref` / `z_top` the mask builder reads (so a tile-seam
      !! step is seen by exactly one rank) and the count is summed over
      !! the compute communicator, so every rank takes the same decision.
      !! Every early return is on rank-uniform state, so either all
      !! ranks reach the collective or none does.
      type(ocean_state_t), intent(in) :: ocean_state
      type(hgrid_t), intent(in) :: grid
      integer, intent(out), optional :: ierr

      integer :: nx, ny, nz, ng, n_local
      real(wp) :: h_nominal, steps_local, steps_global
      real(wp), allocatable :: tgt(:, :, :), eta0(:, :)

      if (present(ierr)) ierr = OCEAN_STATUS_OK
      if (.not. ocean_state%multilayer%is_init) return
      if (ocean_state%vcoord%coord_type /= VCOORD_Z_FIXED) return
      if (ocean_state%vcoord%z_fixed_h_ref <= 0.0_wp) return
      if (.not. ocean_state%dyn%bt_work%is_init) return

      nx = grid%nx_total
      ny = grid%ny_total
      ng = grid%nghost
      nz = ocean_state%multilayer%nz_ml
      h_nominal = ocean_state%vcoord%z_fixed_h_ref/real(nz, wp)

      allocate (tgt(nx, ny, nz), source=0.0_wp)
      allocate (eta0(nx, ny), source=0.0_wp)
      call ocean_vcoord_z_fixed_target(tgt, ocean_state%dyn%bt_work%bt_H_ref, &
                                       eta0, ocean_state%vcoord%z_top, &
                                       nx, ny, nz, h_nominal, &
                                       ocean_state%vcoord%z_fixed_use_profile, &
                                       ocean_state%vcoord%z_fixed_zi, &
                                       ocean_state%vcoord%z_fixed_dz, &
                                       ocean_state%vcoord%zstar_h_min)
      n_local = ocean_vcoord_count_bed_steps(tgt, ocean_state%dyn%bt_work%bt_H_ref, &
                                             ocean_state%metrics%dy_cu, &
                                             ocean_state%metrics%dx_cv, &
                                             nx, ny, nz, ng + 1, ng + grid%nx_phys, &
                                             ng + 1, ng + grid%ny_phys, H_VANISHED)
      deallocate (tgt, eta0)

      ! An integer count rides the real64 sum exactly (far below 2**53).
      steps_local = real(n_local, wp)
      call halo_allreduce_sum(steps_local, steps_global)
      if (steps_global < 0.5_wp) return

      call fail("&vcoord_nml zfixed_closed_faces = .false. is refused with "// &
                "vcoord_type='z_fixed' over a stepped bed: "// &
                to_string(nint(steps_global))//" wet faces join columns whose "// &
                "bed lies in different nominal z_fixed layers, so an open face "// &
                "pairs a live layer with a bed filler and the pressure gradient "// &
                "across the open staircase step drives flow from rest (blows "// &
                "up within steps).  Set &vcoord_nml zfixed_closed_faces = .true.", &
                ierr, OCEAN_STATUS_ERR_SETUP)
   end subroutine refuse_open_zfixed_staircase