configure_ocean_epbl Subroutine

private subroutine configure_ocean_epbl(cfg, ocean_state, grid, compute_rank, ierr)

Copy the &ocean_epbl_nml knobs onto the EPBL slot — every field, end to end (don’t repeat the KPP ri_crit/c_vt2 dead-config gap). Also fills f_centre from the same beta-plane parameters the Coriolis slot uses, copies the EOS hookup, validates the configuration, and resolves the EPBL-vs-KPP mutual exclusion.

Arguments

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

Non-zero on an EPBL configuration conflict when present; absent behaves as today (error stop).


Calls

proc~~configure_ocean_epbl~~CallsGraph proc~configure_ocean_epbl configure_ocean_epbl info info proc~configure_ocean_epbl->info proc~fail fail proc~configure_ocean_epbl->proc~fail proc~fill_coriolis_centre fill_coriolis_centre proc~configure_ocean_epbl->proc~fill_coriolis_centre proc~parse_epbl_combine parse_epbl_combine proc~configure_ocean_epbl->proc~parse_epbl_combine proc~parse_epbl_lt_scheme parse_epbl_lt_scheme proc~configure_ocean_epbl->proc~parse_epbl_lt_scheme proc~parse_epbl_mstar_scheme parse_epbl_mstar_scheme proc~configure_ocean_epbl->proc~parse_epbl_mstar_scheme proc~parse_epbl_vstar_scheme parse_epbl_vstar_scheme proc~configure_ocean_epbl->proc~parse_epbl_vstar_scheme to_string to_string proc~configure_ocean_epbl->to_string error error proc~fail->error proc~error_ring_push error_ring_push proc~fail->proc~error_ring_push proc~metrics_fill_coriolis metrics_fill_coriolis proc~fill_coriolis_centre->proc~metrics_fill_coriolis proc~parse_coriolis_scheme parse_coriolis_scheme proc~fill_coriolis_centre->proc~parse_coriolis_scheme

Called by

proc~~configure_ocean_epbl~~CalledByGraph proc~configure_ocean_epbl configure_ocean_epbl proc~configure_ocean_lateral configure_ocean_lateral proc~configure_ocean_lateral->proc~configure_ocean_epbl proc~engine_setup engine_setup proc~engine_setup->proc~configure_ocean_lateral 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

Source Code

   subroutine configure_ocean_epbl(cfg, ocean_state, grid, compute_rank, ierr)
      !! Copy the `&ocean_epbl_nml` knobs onto the EPBL slot — every
      !! field, end to end (don't repeat the KPP ri_crit/c_vt2
      !! dead-config gap).  Also fills `f_centre` from the same
      !! beta-plane parameters the Coriolis slot uses, copies the EOS
      !! hookup, validates the configuration, and resolves the
      !! EPBL-vs-KPP mutual exclusion.
      type(config_t), intent(in) :: cfg
      type(ocean_state_t), intent(inout) :: ocean_state
      type(hgrid_t), intent(in) :: grid
      integer, intent(in) :: compute_rank
      integer, intent(out), optional :: ierr
         !! Non-zero on an EPBL configuration conflict when present; absent
         !! behaves as today (`error stop`).

      associate (epbl => ocean_state%epbl, ecfg => cfg%ocean%epbl)
         ! `enable` is flipped LAST, only once every validation below has
         ! passed (P0.1 review F9 — `configure_ocean_porous` is the
         ! pattern): setting it up front left a half-configured slot
         ! flagged enabled on any of this routine's many failure returns.
         if (.not. ecfg%enable) then
            epbl%enable = .false.
            if (present(ierr)) ierr = OCEAN_STATUS_OK
            return
         end if

         epbl%mstar_scheme = parse_epbl_mstar_scheme(ecfg%mstar_scheme)
         if (epbl%mstar_scheme < 0) then
            call fail("ocean_epbl_nml: unknown mstar_scheme '"// &
                      trim(ecfg%mstar_scheme)//"' (constant/om4/rh18)", ierr, OCEAN_STATUS_ERR_SETUP)
            return
         end if
         epbl%vstar_scheme = parse_epbl_vstar_scheme(ecfg%vel_scale_scheme)
         if (epbl%vstar_scheme < 0) then
            call fail("ocean_epbl_nml: unknown vel_scale_scheme '"// &
                      trim(ecfg%vel_scale_scheme)//"' (cube_root/rh18)", ierr, OCEAN_STATUS_ERR_SETUP)
            return
         end if
         epbl%combine_mode = parse_epbl_combine(ecfg%combine)
         if (epbl%combine_mode < 0) then
            call fail("ocean_epbl_nml: unknown combine '"// &
                      trim(ecfg%combine)//"' (add/max)", ierr, OCEAN_STATUS_ERR_SETUP)
            return
         end if

         epbl%mstar_const = ecfg%mstar
         epbl%mstar_cap = ecfg%mstar_cap
         epbl%mstar_coef1 = ecfg%mstar_coef1
         epbl%c_ek = ecfg%c_ek
         epbl%mstar_conv_adj = ecfg%mstar_conv_adj
         epbl%rh18_cn1 = ecfg%rh18_cn1
         epbl%rh18_cn2 = ecfg%rh18_cn2
         epbl%rh18_cn3 = ecfg%rh18_cn3
         epbl%rh18_cs1 = ecfg%rh18_cs1
         epbl%rh18_cs2 = ecfg%rh18_cs2
         epbl%nstar = ecfg%nstar
         epbl%tke_decay = ecfg%tke_decay
         epbl%wstar_ustar_coef = ecfg%wstar_ustar_coef
         epbl%vstar_scale_fac = ecfg%vstar_scale_fac
         epbl%vstar_surf_fac = ecfg%vstar_surf_fac
         epbl%von_karman = ecfg%von_karman
         epbl%ekman_scale_coef = ecfg%ekman_scale_coef
         epbl%min_mix_len = ecfg%min_mix_len
         epbl%mixlen_exponent = ecfg%mixlen_exponent
         epbl%translay_scale = ecfg%translay_scale
         epbl%mld_iteration = ecfg%mld_iteration
         epbl%mld_tol = ecfg%mld_tol
         epbl%mld_max_its = ecfg%mld_max_its
         epbl%mld_bisection = ecfg%mld_bisection
         epbl%mld_use_prev_guess = ecfg%mld_use_prev_guess
         epbl%omega = ecfg%omega
         epbl%omega_frac = ecfg%omega_frac
         epbl%prandtl = ecfg%prandtl
         epbl%tke_diags = ecfg%tke_diags
         ! (PR-21) Penetrating-SW TKE ledger switch lives on
         ! &ocean_thermo_nml (shared with KPP), not &ocean_epbl_nml.
         epbl%epbl_sw_ctke = cfg%ocean%thermo%epbl_sw_ctke

         ! Langmuir (LF17 wind-only path).
         epbl%use_lt = ecfg%use_lt
         if (ecfg%use_lt) then
            epbl%lt_scheme = parse_epbl_lt_scheme(ecfg%lt_scheme)
            if (epbl%lt_scheme < 0) then
               call fail("ocean_epbl_nml: unknown lt_scheme '"// &
                         trim(ecfg%lt_scheme)//"' (rescale/additive)", ierr, OCEAN_STATUS_ERR_SETUP)
               return
            end if
            epbl%lt_enhance_coef = ecfg%lt_enhance_coef
            epbl%lt_enhance_exp = ecfg%lt_enhance_exp
            epbl%lt_max_enhance = ecfg%lt_max_enhance
            epbl%la_frac_hbl = ecfg%la_frac_hbl
            epbl%lt_lac1 = ecfg%lt_lac1
            epbl%lt_lac2 = ecfg%lt_lac2
            epbl%lt_lac3 = ecfg%lt_lac3
            epbl%lt_lac4 = ecfg%lt_lac4
            epbl%lt_lac5 = ecfg%lt_lac5
            if (compute_rank == 0) then
               call logger%info("EPBL Langmuir:    LF17 wind-only, scheme="// &
                                trim(ecfg%lt_scheme)//"  coef="// &
                                to_string(ecfg%lt_enhance_coef)//"  exp="// &
                                to_string(ecfg%lt_enhance_exp))
            end if
         end if

         ! EOS hookup: the EPBL energy weights use the SAME EOS handle
         ! the dyn-core runs (shared flat-POD copy — one source of
         ! truth, no scalar copies that can drift).
         epbl%eos = ocean_state%eos
         epbl%rho0 = ocean_state%eos%rho0

         ! (E3) Top-of-column pressure in the IN-SITU EOS arguments AND
         ! in the PE weight.  `&ocean_psurf_nml in_eos` is the single
         ! gate for the whole `ms%p_top` seam; assigned HERE, at
         ! configure, so it is latched before `ocean_state_enter_data`
         ! and the kernel reads it by value (host scalar -- no
         ! `!$acc update device` owed).  Off (default) ⇒ the stack
         ! starts at 0 Pa, bit-identically.  NOTE this is NOT redundant
         ! with `p_top` being zero: a cavity fills `p_top` with the ice
         ! load whether or not `in_eos` is set.
         epbl%in_eos = cfg%ocean%psurf%in_eos

         ! |f| at cell centres, same scheme the Coriolis slot uses (D7).
         call fill_coriolis_centre(cfg, ocean_state%metrics, grid, epbl%f_centre)

         ! Validation.
         if (.not. cfg%ocean%vmix%use_closure) then
            call fail("ocean_epbl_nml: enable=.true. requires "// &
                      "ocean_vmix_nml use_closure=.true. (EPBL folds "// &
                      "into the interior closure's kv/kt)", ierr, OCEAN_STATUS_ERR_SETUP)
            return
         end if
         if (.not. cfg%ocean%thermo%enable_thermodynamics) then
            call fail("ocean_epbl_nml: enable=.true. requires "// &
                      "active thermodynamics (EPBL reads T, S)", ierr, OCEAN_STATUS_ERR_SETUP)
            return
         end if
         if (epbl%mld_iteration .and. &
             (epbl%translay_scale < 0.0_wp .or. epbl%translay_scale >= 1.0_wp)) then
            call fail("ocean_epbl_nml: translay_scale must be in "// &
                      "[0,1) when mld_iteration is on", ierr, OCEAN_STATUS_ERR_SETUP)
            return
         end if
         ! KPP mutual exclusion: EPBL replaces the overlay.  use_kpp
         ! defaults on, so override with a log line rather than abort.
         if (ocean_state%vmix%use_kpp) then
            ocean_state%vmix%use_kpp = .false.
            if (compute_rank == 0) then
               call logger%info("EPBL enabled: KPP overlay disabled "// &
                                "(mutually exclusive surface schemes)")
            end if
         end if

         if (compute_rank == 0) then
            call logger%info("EPBL:             mstar="//trim(ecfg%mstar_scheme)// &
                             "  nstar="//to_string(ecfg%nstar)// &
                             "  tke_decay="//to_string(ecfg%tke_decay)// &
                             "  vstar="//trim(ecfg%vel_scale_scheme)// &
                             "  combine="//trim(ecfg%combine))
         end if
         epbl%enable = .true.
      end associate
      if (present(ierr)) ierr = OCEAN_STATUS_OK
   end subroutine configure_ocean_epbl