ocean_state_init_from_config Subroutine

private subroutine ocean_state_init_from_config(this, cfg, grid)

Seed the cfg-derived scalars the slot inits read up front (layer count, ideal-age toggle), allocate via init(grid), then override the linear-EOS params (after eos%init has set its defaults). Carries the ocean branch that state_init_from_config held before the coastal / ocean state split — the order (nz_ml + ideal_age before init, eos after) is load-bearing and matches the pre-split behaviour.

Type Bound

ocean_state_t

Arguments

Type IntentOptional Attributes Name
class(ocean_state_t), intent(inout) :: this
type(config_t), intent(in) :: cfg
type(hgrid_t), intent(in) :: grid

Calls

proc~~ocean_state_init_from_config~~CallsGraph proc~ocean_state_init_from_config ocean_state_t%ocean_state_init_from_config proc~ice_hlim_count ice_hlim_count proc~ocean_state_init_from_config->proc~ice_hlim_count proc~ocean_state_init ocean_state_t%ocean_state_init proc~ocean_state_init_from_config->proc~ocean_state_init proc~parse_opgf_variant parse_opgf_variant proc~ocean_state_init_from_config->proc~parse_opgf_variant proc~pgf_nonoverlap_gate_on pgf_nonoverlap_gate_on proc~ocean_state_init_from_config->proc~pgf_nonoverlap_gate_on proc~barotropic_state_init barotropic_state_t%barotropic_state_init proc~ocean_state_init->proc~barotropic_state_init proc~ocean_bc_state_init ocean_bc_state_init proc~ocean_state_init->proc~ocean_bc_state_init proc~ocean_pseudo_salt_register ocean_pseudo_salt_register proc~ocean_state_init->proc~ocean_pseudo_salt_register proc~parse_ocean_vcoord_type parse_ocean_vcoord_type proc~pgf_nonoverlap_gate_on->proc~parse_ocean_vcoord_type error error proc~ocean_pseudo_salt_register->error proc~error_ring_push error_ring_push proc~ocean_pseudo_salt_register->proc~error_ring_push proc~multilayer_register_passive_tracer multilayer_state_t%multilayer_register_passive_tracer proc~ocean_pseudo_salt_register->proc~multilayer_register_passive_tracer proc~parse_vcoord_type parse_vcoord_type proc~parse_ocean_vcoord_type->proc~parse_vcoord_type proc~multilayer_register_passive_tracer->error proc~multilayer_register_passive_tracer->proc~error_ring_push proc~tracer_init tracer_t%tracer_init proc~multilayer_register_passive_tracer->proc~tracer_init

Called by

proc~~ocean_state_init_from_config~~CalledByGraph proc~ocean_state_init_from_config ocean_state_t%ocean_state_init_from_config proc~engine_setup engine_setup proc~engine_setup->proc~ocean_state_init_from_config 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 ocean_state_init_from_config(this, cfg, grid)
      !! Seed the cfg-derived scalars the slot inits read up front (layer
      !! count, ideal-age toggle), allocate via init(grid), then override the
      !! linear-EOS params (after eos%init has set its defaults).  Carries the
      !! ocean branch that state_init_from_config held before the coastal /
      !! ocean state split — the order (nz_ml + ideal_age before init, eos
      !! after) is load-bearing and matches the pre-split behaviour.
      class(ocean_state_t), intent(inout) :: this
      type(config_t), intent(in) :: cfg
      type(hgrid_t), intent(in) :: grid

      this%multilayer%nz_ml = cfg%nz_layers
      this%enable_ideal_age = cfg%ocean%tracers%enable_ideal_age
      this%enable_pseudo_salt = cfg%ocean%tracers%enable_pseudo_salt

      ! Enable flags govern CONDITIONAL ALLOCATION (ocean_state_init gates
      ! each default-off closure's array allocation on its `enable`), so
      ! they must be latched BEFORE init(grid).  The full per-closure knob
      ! copy still runs after init (below) and re-sets these idempotently;
      ! MEKE and Fox-Kemper/MLE otherwise get their enable only in the
      ! later configure_ocean_* pass, so they are seeded from cfg here too.
      ! Windowed tracer advection (Phase 2/6b): its 13-array workspace
      ! (~3.7 GiB at 600²x100) is only consumed at ratio > 1, so the
      ! allocation gate latches here like the closures below.
      this%continuity%windowed_advection = cfg%ocean%vmix%dt_tracer_advect_ratio > 1
      ! Pressure-force scratch: 11 of the 16 buffers are FV_MOM6- or
      ! in-layer-reconstruction-only (~3.5 GB at 1000x800x50) and are
      ! unreachable on the shipped gprime / montgomery / fv_lite envelope.
      ! `variant` + `reconstruct_for_pressure` therefore latch HERE, ahead
      ! of init(grid), and `scratch_gated` turns the per-variant gate on;
      ! `configure_ocean_pgf` re-sets both idempotently later.  Direct
      ! `pgf%init(...)` call sites leave `scratch_gated = .false.` and keep
      ! the allocate-everything behaviour.
      this%pressure_force%variant = parse_opgf_variant(cfg%ocean%pgf%form)
      this%pressure_force%reconstruct_for_pressure = cfg%ocean%pgf%reconstruct_for_pressure
      ! Grounded-layer PGF gate: for FV_MOM6 the `z_centre` buffer exists only
      ! to feed this gate, so the flag has to be known BEFORE the allocation
      ! gate runs.  It is a pure config-time decision, so latch it here next to
      ! `variant`; `configure_ocean_pgf` recomputes it (and error-stops if the
      ! latch drifted) for the FV_LITE / FV_WRIGHT paths too.
      this%pressure_force%skip_nonoverlap = &
         pgf_nonoverlap_gate_on(cfg, this%pressure_force%variant)
      this%pressure_force%scratch_gated = .true.
      ! Ice-shelf cavity geometry: `use_cavity` gates the allocation of
      ! the three static metrics fields (`z_draft`, `cover_frac`,
      ! `p_ice_ref`), so it latches HERE — and it has to be earlier than
      ! most: the draft is filled inside `ocean_state_seed_from_cfg`,
      ! which is the first thing the engine does after this, long before
      ! any `configure_ocean_*` pass.  Off ⇒ three `(1,1)` placeholders.
      this%metrics%use_cavity = cfg%ocean%cavity_dyn%enable
      ! Ice-shelf basal melt: the melt slot's own gate, latched here for
      ! the same reason (its `init` sizes eleven 2-D arrays off it).
      this%cavity_flux%enable = cfg%ocean%cavity_melt%enable
      ! Ice-shelf top drag: same gate discipline — its `init` sizes the
      ! two face scratch buffers and five 2-D fields off `enable`.
      this%tdrag%enable = cfg%ocean%tdrag%enable
      this%epbl%enable = cfg%ocean%epbl%enable
      this%kshear%enable = cfg%ocean%kshear%enable
      this%vmix_tidal%enable = cfg%ocean%tidal_mixing%enable
      this%slopes%enable = cfg%ocean%slopes%enable
      this%gm%enable = cfg%ocean%gm%enable
      this%redi%enable = cfg%ocean%redi%enable
      this%varmix%enable = cfg%ocean%varmix%enable
      this%meke%enable = cfg%ocean%meke%enable
      this%mle%enable = cfg%ocean%foxkemper%enable
      ! Sea ice (PR 0 scaffold): enable gates the slot's init +
      ! enter_data/exit_data; ncat/nk_ice size the per-category arrays
      ! once PR 3+ allocates them, so all three latch before init like
      ! the closures above.
      this%ice%enable = cfg%ocean%ice%enable
      this%ice%ncat = cfg%ocean%ice%ncat
      this%ice%nk_ice = cfg%ocean%ice%nk_ice
      ! PR 4b: transport latches before init too (gates the workspace
      ! allocation, memory Rule 2 — see rdb_ice_state%init).
      this%ice%transport = cfg%ocean%ice%transport
      ! PR 5: EVP dynamics master flag (gates the driver's ice_evp_step
      ! call + the transport sampler skip; no per-slot allocation gate —
      ! str_d/str_t/str_s/tau_a_*/fxoc/fyoc are unconditional whenever the
      ! ice slot is live, same contract as u_ice/v_ice).
      this%ice%dynamics = cfg%ocean%ice%dynamics
      ! PR-23: enable gates the sponge's (potentially large, 4-D
      ! nx*ny*nz*n_tracers) reference-state allocation, so it latches
      ! before init like the closures above (`ocean_sponge_init` is only
      ! called when `this%sponge%enable`, see below).
      this%sponge%enable = cfg%ocean%sponge%enable
      ! PR-58: hlim latches before init (ice_itd_category_bounds runs
      ! inside ice%init). Unallocated => the hardcoded SIS2 default table.
      block
         integer :: n_hlim
         n_hlim = ice_hlim_count(cfg%ocean%ice%hlim)
         if (n_hlim > 0) this%ice%hlim_cfg = cfg%ocean%ice%hlim(1:n_hlim)  ! allocate-on-assign
      end block
      ! PR 26: snowfall's host-side dispatch gate — latches before init
      ! like transport/dynamics above (no per-slot allocation gate;
      ! atm_fprec/snow_part_ocn/fprec_ocn_diag are unconditional whenever
      ! the ice slot is live, same contract as u_ice/v_ice). This is what
      ! makes `snowfall=0` byte-identical BY CONSTRUCTION.
      this%ice%has_snowfall = (cfg%ocean%ice%snowfall /= 0.0_wp)
      ! PR 27: Archimedes snow-ice flood master flag — latches before
      ! init like has_snowfall/transport/dynamics above (no per-slot
      ! allocation gate; snow_to_ice is unconditional whenever the ice
      ! slot is live, same contract as sw_thru). This is what makes
      ! `snow_ice=.false.` byte-identical BY CONSTRUCTION.
      this%ice%snow_ice = cfg%ocean%ice%snow_ice

      call this%init(grid)
#ifndef RDB_NO_NETCDF
      ! `this%init(grid)` above already built a default-sized (16 slot,
      ! quiet) reader — safe to re-run with the real config now, since
      ! nothing can have been registered between the two calls (grid
      ! init happens before any consumer registration, and registration
      ! itself only happens after this returns — see the seam contract
      ! in rdb_ocean_data_input's module docstring).
      call this%data_input%init(cfg%ocean%data)
#endif
      ! Linear-EOS reference state, all five members off `&ocean_ic_nml`.
      ! This runs before `ocean_state_enter_data` AND before the
      ! `configure_ocean_*` pass that copies the whole flat-POD handle
      ! onto the closure slots that carry their own copy
      ! (`vmix%eos`, `epbl%eos`, `kshear%eos`, `tidal_mixing%eos` —
      ! `rdb_ocean_setup.F90`), so every rider and every device kernel
      ! that takes `eos_t` by value sees the configured values.  Defaults
      ! equal the `eos_t` component defaults ⇒ bit-identical.
      this%eos%alpha_T = cfg%ocean%ic%alpha_T
      this%eos%beta_S = cfg%ocean%ic%beta_S
      this%eos%T_ref = cfg%ocean%ic%T_ref
      this%eos%S_ref = cfg%ocean%ic%S_ref
      this%eos%rho0 = cfg%ocean%ic%rho_0
      ! EPBL master switch is read here (before the configure_ocean_*
      ! pass) because diag registration — which gates the MLD_EPBL /
      ! Kd_EPBL variables on it — runs before configure in the driver.
      this%epbl%enable = cfg%ocean%epbl%enable
      this%wavespeed%enable = cfg%ocean%wavespeed%enable
      this%kshear%enable = cfg%ocean%kshear%enable
      this%slopes%enable = cfg%ocean%slopes%enable
      this%slopes%kd_smooth = cfg%ocean%slopes%kd_smooth
      this%slopes%min_dz_for_n2 = cfg%ocean%slopes%min_dz_for_n2
      this%slopes%rho0 = cfg%ocean%ic%rho_0
      this%gm%enable = cfg%ocean%gm%enable
      this%gm%khth = cfg%ocean%gm%khth
      this%gm%khth_max_cfl = cfg%ocean%gm%khth_max_cfl
      this%gm%khth_slope_max = cfg%ocean%gm%khth_slope_max
      this%gm%rho0 = cfg%ocean%ic%rho_0
      this%redi%enable = cfg%ocean%redi%enable
      this%redi%continuous = cfg%ocean%redi%continuous
      this%redi%khtr = cfg%ocean%redi%khtr
      this%varmix%enable = cfg%ocean%varmix%enable
      this%varmix%use_visbeck = cfg%ocean%varmix%use_visbeck
      this%varmix%resoln_scaled_khth = cfg%ocean%varmix%resoln_scaled_khth
      this%varmix%resoln_scaled_khtr = cfg%ocean%varmix%resoln_scaled_khtr
      this%varmix%gill_equatorial_ld = cfg%ocean%varmix%gill_equatorial_ld
      this%varmix%interpolate_res_fn = cfg%ocean%varmix%interpolate_res_fn
      this%varmix%kh_res_fn_power = cfg%ocean%varmix%kh_res_fn_power
      this%varmix%kh_res_scale_coef = cfg%ocean%varmix%kh_res_scale_coef
      this%varmix%khth = cfg%ocean%varmix%khth
      this%varmix%khtr = cfg%ocean%varmix%khtr
      this%varmix%khth_slope_cff = cfg%ocean%varmix%khth_slope_cff
      this%varmix%khtr_slope_cff = cfg%ocean%varmix%khtr_slope_cff
      this%varmix%khth_min = cfg%ocean%varmix%khth_min
      this%varmix%khth_max = cfg%ocean%varmix%khth_max
      this%varmix%khtr_min = cfg%ocean%varmix%khtr_min
      this%varmix%khtr_max = cfg%ocean%varmix%khtr_max
      this%varmix%visbeck_l_scale = cfg%ocean%varmix%visbeck_l_scale
      this%varmix%visbeck_max_slope = cfg%ocean%varmix%visbeck_max_slope

      ! ---- MEKE (capability [5]) ----
      this%meke%enable = cfg%ocean%meke%enable
      this%meke%gmcoeff = cfg%ocean%meke%gmcoeff
      this%meke%frcoeff = cfg%ocean%meke%frcoeff
      ! Turn the hvisc KE-dissipation diagnostic on ONLY when MEKE's
      ! frictional source is active; otherwise the viscous apply skips it
      ! (zero extra work, bit-identical).
      this%hvisc%compute_ke_diss = cfg%ocean%meke%enable .and. &
                                   (cfg%ocean%meke%frcoeff >= 0.0_wp)
      this%meke%bgsrc = cfg%ocean%meke%bgsrc
      this%meke%damping = cfg%ocean%meke%damping
      this%meke%kh = cfg%ocean%meke%kh
      this%meke%k4 = cfg%ocean%meke%k4
      this%meke%khcoeff = cfg%ocean%meke%khcoeff
      this%meke%cd_scale = cfg%ocean%meke%cd_scale
      this%meke%cb = cfg%ocean%meke%cb
      this%meke%ct = cfg%ocean%meke%ct
      this%meke%min_gamma2 = cfg%ocean%meke%min_gamma2
      this%meke%uscale = cfg%ocean%meke%uscale
      this%meke%use_bbl_drag = cfg%ocean%meke%use_bbl_drag
      this%meke%dtscale = cfg%ocean%meke%dtscale
      this%meke%khth_fac = cfg%ocean%meke%khth_fac
      this%meke%khtr_fac = cfg%ocean%meke%khtr_fac
      this%meke%backscatter = cfg%ocean%meke%backscatter
      this%meke%visc_coeff_ku = cfg%ocean%meke%backscatter_visc_coeff_ku
      this%meke%khmeke_fac = cfg%ocean%meke%khmeke_fac
      this%meke%advection_factor = cfg%ocean%meke%advection_factor
      this%meke%alpha_deform = cfg%ocean%meke%alpha_deform
      this%meke%alpha_rhines = cfg%ocean%meke%alpha_rhines
      this%meke%alpha_eady = cfg%ocean%meke%alpha_eady
      this%meke%alpha_frict = cfg%ocean%meke%alpha_frict
      this%meke%alpha_grid = cfg%ocean%meke%alpha_grid
      ! cdrag: prefer the side-drag coefficient if set (> 0), else the
      ! MEKE-specific knob default.
      if (cfg%ocean%bdrag%cdrag_side > 0.0_wp) then
         this%meke%cdrag = cfg%ocean%bdrag%cdrag_side
      else
         this%meke%cdrag = cfg%ocean%meke%cdrag
      end if
      this%vmix_tidal%enable = cfg%ocean%tidal_mixing%enable
      this%tides%enable = cfg%ocean%tides%enable
      this%p_surf%enable = cfg%ocean%psurf%enable
      this%p_surf%in_eos = cfg%ocean%psurf%in_eos
   end subroutine ocean_state_init_from_config