ocean_metrics_init Subroutine

private subroutine ocean_metrics_init(this, grid)

Allocate + zero every metric array. Always allocates (configure runs after init, before enter_data); off-cost is ~24 (nx,ny)-class arrays (~2 MB at Tasman size).

Type Bound

ocean_metrics_t

Arguments

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

Variables

Type Visibility Attributes Name Initial
integer, private :: nx
integer, private :: ny

Source Code

   subroutine ocean_metrics_init(this, grid)
      !! Allocate + zero every metric array.  Always allocates (configure
      !! runs after init, before `enter_data`); off-cost is ~24
      !! `(nx,ny)`-class arrays (~2 MB at Tasman size).
      class(ocean_metrics_t), intent(inout) :: this
      type(hgrid_t), intent(in) :: grid
      integer :: nx, ny

      nx = grid%nx_total
      ny = grid%ny_total

      ! Lengths
      allocate (this%dxT(nx, ny), source=0.0_wp)
      allocate (this%dyT(nx, ny), source=0.0_wp)
      allocate (this%dxCu(nx + 1, ny), source=0.0_wp)
      allocate (this%dyCu(nx + 1, ny), source=0.0_wp)
      allocate (this%dxCv(nx, ny + 1), source=0.0_wp)
      allocate (this%dyCv(nx, ny + 1), source=0.0_wp)
      allocate (this%dxBu(nx + 1, ny + 1), source=0.0_wp)
      allocate (this%dyBu(nx + 1, ny + 1), source=0.0_wp)
      ! Topo face widths
      allocate (this%dy_cu(nx + 1, ny), source=0.0_wp)
      allocate (this%dx_cv(nx, ny + 1), source=0.0_wp)
      ! BT transport widths: ALWAYS full size (2D, cheap) so the
      ! barotropic substep can read them unconditionally — no branch, no
      ! placeholder.  `metrics_finalize` / `metrics_apply_land_mask` keep
      ! them a byte copy of `dy_cu` / `dx_cv` until porous barriers narrow
      ! them, which is what makes the knob-off path bit-identical.
      allocate (this%dy_cu_bt(nx + 1, ny), source=0.0_wp)
      allocate (this%dx_cv_bt(nx, ny + 1), source=0.0_wp)
      ! Porous barriers start at the (1,1)/(1,1,1) placeholder size:
      ! `metrics_porous_alloc` grows them at configure time (which runs
      ! after init and before enter_data) only when the knob is on, so a
      ! default run pays ~7 words instead of two full 3D fields.
      allocate (this%por_bed(1, 1), source=0.0_wp)
      allocate (this%por_dmin_u(1, 1), source=0.0_wp)
      allocate (this%por_dmax_u(1, 1), source=0.0_wp)
      allocate (this%por_davg_u(1, 1), source=0.0_wp)
      allocate (this%por_dmin_v(1, 1), source=0.0_wp)
      allocate (this%por_dmax_v(1, 1), source=0.0_wp)
      allocate (this%por_davg_v(1, 1), source=0.0_wp)
      allocate (this%por_face_area_u(1, 1, 1), source=1.0_wp)
      allocate (this%por_face_area_v(1, 1, 1), source=1.0_wp)
      ! z-level closed faces: same placeholder discipline as the porous
      ! arrays -- `metrics_closed_faces_alloc` grows them at configure
      ! (after init, before enter_data) only when the knob is on.  The
      ! placeholder is 1 (fully open) so an accidental read is inert, but
      ! it must NEVER reach an explicit-shape device dummy: every consumer
      ! names `open_u`/`open_v` only inside a branch guarded by
      ! `use_closed_faces`.
      allocate (this%open_u(1, 1, 1), source=1.0_wp)
      allocate (this%open_v(1, 1, 1), source=1.0_wp)
      ! Ice-shelf cavity statics.  Unlike the porous arrays (grown at
      ! configure), these are sized HERE off the `use_cavity` flag that
      ! `init_from_config` latches before `init` — the draft has to exist
      ! before `ocean_state_seed_from_cfg` seeds the wet mask and the
      ! layer thicknesses from `b - z_draft`, which is well before any
      ! `configure_ocean_*` runs.  Knob off ⇒ three `(1,1)` placeholders.
      if (this%use_cavity) then
         allocate (this%z_draft(nx, ny), source=0.0_wp)
         allocate (this%cover_frac(nx, ny), source=0.0_wp)
         allocate (this%p_ice_ref(nx, ny), source=0.0_wp)
      else
         allocate (this%z_draft(1, 1), source=0.0_wp)
         allocate (this%cover_frac(1, 1), source=0.0_wp)
         allocate (this%p_ice_ref(1, 1), source=0.0_wp)
      end if
      ! Land masks default ALL-WET (1.0): if metrics_apply_land_mask is
      ! never called (no land), the masks stay inert (×1) and the 6 face
      ! metrics are never altered — bit-identical to a no-mask build.
      allocate (this%wet_T(nx, ny), source=1.0_wp)
      allocate (this%wet_u(nx + 1, ny), source=1.0_wp)
      allocate (this%wet_v(nx, ny + 1), source=1.0_wp)
      allocate (this%wet_q(nx + 1, ny + 1), source=1.0_wp)
      ! Areas
      allocate (this%areaT(nx, ny), source=0.0_wp)
      allocate (this%areaCu(nx + 1, ny), source=0.0_wp)
      allocate (this%areaCv(nx, ny + 1), source=0.0_wp)
      allocate (this%areaBu(nx + 1, ny + 1), source=0.0_wp)
      ! Inverses
      allocate (this%idxT(nx, ny), source=0.0_wp)
      allocate (this%idyT(nx, ny), source=0.0_wp)
      allocate (this%idxCu(nx + 1, ny), source=0.0_wp)
      allocate (this%idyCu(nx + 1, ny), source=0.0_wp)
      allocate (this%idxCv(nx, ny + 1), source=0.0_wp)
      allocate (this%idyCv(nx, ny + 1), source=0.0_wp)
      allocate (this%iareaT(nx, ny), source=0.0_wp)
      allocate (this%iareaBu(nx + 1, ny + 1), source=0.0_wp)
      allocate (this%iareaCu(nx + 1, ny), source=0.0_wp)
      allocate (this%iareaCv(nx, ny + 1), source=0.0_wp)
      ! Geography
      allocate (this%geolatT(nx, ny), source=0.0_wp)
      allocate (this%geolonT(nx, ny), source=0.0_wp)
      allocate (this%geolatBu(nx + 1, ny + 1), source=0.0_wp)
      allocate (this%geolonBu(nx + 1, ny + 1), source=0.0_wp)
      allocate (this%angle_dx(nx, ny), source=0.0_wp)
      ! hvisc ratio bundle
      allocate (this%dy_dxT(nx, ny), source=0.0_wp)
      allocate (this%dx_dyT(nx, ny), source=0.0_wp)
      allocate (this%dy_dxBu(nx + 1, ny + 1), source=0.0_wp)
      allocate (this%dx_dyBu(nx + 1, ny + 1), source=0.0_wp)
      allocate (this%dx2h(nx, ny), source=0.0_wp)
      allocate (this%dy2h(nx, ny), source=0.0_wp)
      allocate (this%dx2q(nx + 1, ny + 1), source=0.0_wp)
      allocate (this%dy2q(nx + 1, ny + 1), source=0.0_wp)

      this%is_init = .true.
   end subroutine ocean_metrics_init