ocean_state_init Subroutine

private subroutine ocean_state_init(this, grid)

Construct the ocean god state. Each slot’s init allocates its own arrays; the DEFAULT-OFF closures (EPBL, kappa-shear, tidal mixing, GM, Redi, MLE/Fox-Kemper, VarMix, MEKE, isopycnal slopes) are gated on their enable flag so a plain run does not pay their multi-GB footprint. This requires the enable flags to be set BEFORE init — ocean_state_init_from_config hoists them above its call this%init(grid) for exactly this reason. The gated closures’ runtime kernels already early-return on .not. enable (and enter_data/exit_data are gated in the parent walk), so a gated-off slot is never touched with unallocated arrays.

Type Bound

ocean_state_t

Arguments

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

Calls

proc~~ocean_state_init~~CallsGraph proc~ocean_state_init ocean_state_t%ocean_state_init 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 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~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~~CalledByGraph proc~ocean_state_init ocean_state_t%ocean_state_init proc~ocean_state_init_from_config ocean_state_t%ocean_state_init_from_config proc~ocean_state_init_from_config->proc~ocean_state_init 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

Variables

Type Visibility Attributes Name Initial
logical, private :: need_slopes

Source Code

   subroutine ocean_state_init(this, grid)
      !! Construct the ocean god state.  Each slot's `init` allocates its
      !! own arrays; the DEFAULT-OFF closures (EPBL, kappa-shear, tidal
      !! mixing, GM, Redi, MLE/Fox-Kemper, VarMix, MEKE, isopycnal slopes)
      !! are gated on their `enable` flag so a plain run does not pay their
      !! multi-GB footprint.  This requires the enable flags to be set
      !! BEFORE `init` — `ocean_state_init_from_config` hoists them above
      !! its `call this%init(grid)` for exactly this reason.  The gated
      !! closures' runtime kernels already early-return on `.not. enable`
      !! (and `enter_data`/`exit_data` are gated in the parent walk), so a
      !! gated-off slot is never touched with unallocated arrays.
      class(ocean_state_t), intent(inout) :: this
      type(hgrid_t), intent(in) :: grid

      logical :: need_slopes

      ! Isopycnal slopes feed GM (and the standalone slope diffusivity);
      ! Redi and MLE compute their own coefficients and do NOT read slopes.
      need_slopes = this%slopes%enable .or. this%gm%enable

      call this%barotropic%init(grid)
      call this%metrics%init(grid)
      if (this%use_multilayer) then
         call this%multilayer%init(grid, with_ideal_age=this%enable_ideal_age)
         ! Pseudo-salt registration MUST happen here — after multilayer%init
         ! (so the registry exists), before enter_data (registry_locked
         ! guard) and, critically, before ocean_bc_state_init below sizes
         ! bc%n_tracers (§2.5 of the plan: registering after that call
         ! silently skips the new tracer at OBC-clamped edges).
         if (this%enable_pseudo_salt) call ocean_pseudo_salt_register(this%multilayer, grid)
         call this%dyn%init(grid, nz_ml=this%multilayer%nz_ml)
      else
         call this%dyn%init(grid)
      end if
      ! the ocean is always multilayer
      if (this%use_multilayer) then
         call this%continuity%init(grid, nz_ml=this%multilayer%nz_ml)
         call this%coriolis_adv%init(grid, nz_ml=this%multilayer%nz_ml)
         call this%pressure_force%init(grid, nz_ml=this%multilayer%nz_ml)
         call this%hvisc%init(grid, nz_ml=this%multilayer%nz_ml)
         call this%bdrag%init(grid, nz_ml=this%multilayer%nz_ml)
         call this%tdrag%init(grid, nz_ml=this%multilayer%nz_ml)
         call this%surface_stress%init(grid, nz_ml=this%multilayer%nz_ml)
         call this%surface_flux%init(grid)
         call this%cavity_flux%init(grid)
         call this%vert_advect%init(grid, nz_ml=this%multilayer%nz_ml)
         call this%hdiff_tracer%init(grid, nz_ml=this%multilayer%nz_ml)
         call this%vdiff%init(grid, nz_ml=this%multilayer%nz_ml)
      else
         call this%continuity%init(grid)
         call this%coriolis_adv%init(grid)
         call this%pressure_force%init(grid)
         call this%hvisc%init(grid)
         call this%bdrag%init(grid)
         call this%tdrag%init(grid)
         call this%surface_stress%init(grid)
         call this%surface_flux%init(grid)
         call this%cavity_flux%init(grid)
         call this%vert_advect%init(grid)
         call this%hdiff_tracer%init(grid)
         call this%vdiff%init(grid)
      end if
      ! Always-on vertical mixing (PP81/KPP base) + horizontal viscosity
      ! (harmonic/biharmonic) back the production envelope, so they are
      ! unconditional.  The eddy/alternative closures below are gated.
      if (this%use_multilayer) then
         call this%vmix%init(grid, nz_ml=this%multilayer%nz_ml)
         call this%lateral_mix%init(grid, nz_ml=this%multilayer%nz_ml)
         if (this%epbl%enable) call this%epbl%init(grid, nz_ml=this%multilayer%nz_ml)
         if (this%kshear%enable) call this%kshear%init(grid, nz_ml=this%multilayer%nz_ml)
         if (this%vmix_tidal%enable) call this%vmix_tidal%init(grid, nz_ml=this%multilayer%nz_ml)
         if (need_slopes) call this%slopes%init(grid, nz_ml=this%multilayer%nz_ml)
         if (this%mle%enable) call this%mle%init(grid, nz_ml=this%multilayer%nz_ml)
         if (this%gm%enable) call this%gm%init(grid, nz_ml=this%multilayer%nz_ml)
         if (this%redi%enable) call this%redi%init(grid, nz_ml=this%multilayer%nz_ml)
         if (this%varmix%enable) call this%varmix%init(grid, nz_ml=this%multilayer%nz_ml)
         if (this%meke%enable) call this%meke%init(grid, nz_ml=this%multilayer%nz_ml)
      else
         call this%vmix%init(grid)
         call this%lateral_mix%init(grid)
         if (this%epbl%enable) call this%epbl%init(grid)
         if (this%kshear%enable) call this%kshear%init(grid)
         if (this%vmix_tidal%enable) call this%vmix_tidal%init(grid)
         if (need_slopes) call this%slopes%init(grid)
         if (this%mle%enable) call this%mle%init(grid)
         if (this%gm%enable) call this%gm%init(grid)
         if (this%redi%enable) call this%redi%init(grid)
         if (this%varmix%enable) call this%varmix%init(grid)
         if (this%meke%enable) call this%meke%init(grid)
      end if
      call this%wavespeed%init(grid)
      call this%eos%init(grid)
      if (this%use_multilayer) then
         call this%vcoord%init(grid, nz_ml=this%multilayer%nz_ml)
      else
         call this%vcoord%init(grid)
      end if
      call this%tides%init(grid)
      call this%p_surf%init(grid)
      if (this%ice%enable) call this%ice%init(grid)
      call this%obc%init(grid)
      if (this%use_multilayer) then
         call ocean_bc_state_init(this%bc, grid, nz_ml=this%multilayer%nz_ml, &
                                  n_tracers=size(this%multilayer%tracers))
         ! PR-23: gated call (mirrors epbl/kshear/...) — `ocean_sponge_init`
         ! only allocates the (potentially large) idamp/ref_tracer arrays
         ! when `enable`, so a disabled sponge (default) never allocates.
         if (this%sponge%enable) then
            call this%sponge%init(grid, nz_ml=this%multilayer%nz_ml, &
                                  n_tracers=size(this%multilayer%tracers))
         end if
      else
         call ocean_bc_state_init(this%bc, grid, nz_ml=1)
      end if
      call this%diag%init(grid)
#ifndef RDB_NO_NETCDF
      call this%data_input%init()
#endif
      call this%restart%init()
      this%is_init = .true.
   end subroutine ocean_state_init