Copy the &ocean_conv_nml knobs onto ocean_state%vmix – every
field, no dead-config gaps. Convective adjustment adds no new
slot / allocatable (it lives on the already-unconditionally-
allocated vmix), so unlike configure_ocean_tidal_mixing there
is no separate enable latch to set on a distinct sub-object;
vmix%conv_enable IS the latch. No mutual exclusion with
KPP / EPBL: convection masks against whichever BL depth is live
this stage (rdb_ocean_dyn.F90 vmix_apply_in_stage).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(config_t), | intent(in) | :: | cfg | |||
| type(ocean_state_t), | intent(inout) | :: | ocean_state | |||
| integer, | intent(in) | :: | compute_rank | |||
| integer, | intent(out), | optional | :: | ierr |
Non-zero on a convective-adjustment configuration conflict when
present; absent behaves as today ( |
subroutine configure_ocean_conv(cfg, ocean_state, compute_rank, ierr) !! Copy the `&ocean_conv_nml` knobs onto `ocean_state%vmix` -- every !! field, no dead-config gaps. Convective adjustment adds no new !! slot / allocatable (it lives on the already-unconditionally- !! allocated `vmix`), so unlike `configure_ocean_tidal_mixing` there !! is no separate `enable` latch to set on a distinct sub-object; !! `vmix%conv_enable` IS the latch. No mutual exclusion with !! KPP / EPBL: convection masks against whichever BL depth is live !! this stage (`rdb_ocean_dyn.F90 vmix_apply_in_stage`). type(config_t), intent(in) :: cfg type(ocean_state_t), intent(inout) :: ocean_state integer, intent(in) :: compute_rank integer, intent(out), optional :: ierr !! Non-zero on a convective-adjustment configuration conflict when !! present; absent behaves as today (`error stop`). associate (vmix => ocean_state%vmix, ccfg => cfg%ocean%conv) ! `conv_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 failure returns. if (.not. ccfg%enable) then vmix%conv_enable = .false. if (present(ierr)) ierr = OCEAN_STATUS_OK return end if vmix%conv_kd = ccfg%kd_conv vmix%conv_prandtl = ccfg%prandtl_conv vmix%conv_n2_thresh = ccfg%n2_thresh ! Validation. if (.not. cfg%ocean%vmix%use_closure) then call fail("ocean_conv_nml: enable=.true. requires "// & "ocean_vmix_nml use_closure=.true. (convection "// & "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_conv_nml: enable=.true. requires "// & "active thermodynamics (convection reads rho_layer, "// & "which is only refreshed by the EOS)", ierr, OCEAN_STATUS_ERR_SETUP) return end if if (ccfg%kd_conv < 0.0_wp) then call fail("ocean_conv_nml: kd_conv must be >= 0", ierr, OCEAN_STATUS_ERR_SETUP) return end if if (ccfg%prandtl_conv <= 0.0_wp) then call fail("ocean_conv_nml: prandtl_conv must be > 0", ierr, OCEAN_STATUS_ERR_SETUP) return end if if (compute_rank == 0) then call logger%info("Convection: interior closure enabled "// & "(kd_conv="//to_string(ccfg%kd_conv)//" m^2/s "// & "n2_thresh="//to_string(ccfg%n2_thresh)//" s^-2)") end if vmix%conv_enable = .true. end associate if (present(ierr)) ierr = OCEAN_STATUS_OK end subroutine configure_ocean_conv