subroutine ocean_varmix_init(this, grid, nz_ml)
!! Allocate the static grid terms, the per-step diagnostics, and the
!! KhTh/KhTr base face fields. Always allocates (configure runs after
!! init); the static `f2_dx2_*` / `beta_dx2_*` / `l2_*` are filled by
!! `build_static` once the metrics + f_centre are known. Setup uses
!! plain host allocation (no `do concurrent` before enter_data).
class(ocean_varmix_t), intent(inout) :: this
type(hgrid_t), intent(in) :: grid
integer, intent(in), optional :: nz_ml
integer :: nx, ny, nz
nx = grid%nx_total
ny = grid%ny_total
nz = 1
if (present(nz_ml)) nz = nz_ml
if (nz < 1) nz = 1
if (nz > NZ_STACK_MAX) then
error stop "ocean_varmix_init: nz_ml exceeds NZ_STACK_MAX "// &
"(raise NZ_STACK_MAX in rdb_constants)"
end if
this%nx_total = nx
this%ny_total = ny
this%nz_ml = nz
allocate (this%f2_dx2_u(nx + 1, ny), source=0.0_wp)
allocate (this%f2_dx2_v(nx, ny + 1), source=0.0_wp)
allocate (this%beta_dx2_u(nx + 1, ny), source=0.0_wp)
allocate (this%beta_dx2_v(nx, ny + 1), source=0.0_wp)
allocate (this%l2_u(nx + 1, ny), source=0.0_wp)
allocate (this%l2_v(nx, ny + 1), source=0.0_wp)
allocate (this%res_fn_u(nx + 1, ny), source=0.0_wp)
allocate (this%res_fn_v(nx, ny + 1), source=0.0_wp)
allocate (this%sn_u(nx + 1, ny), source=0.0_wp)
allocate (this%sn_v(nx, ny + 1), source=0.0_wp)
allocate (this%khth_u(nx + 1, ny), source=0.0_wp)
allocate (this%khth_v(nx, ny + 1), source=0.0_wp)
allocate (this%khtr_u(nx + 1, ny), source=0.0_wp)
allocate (this%khtr_v(nx, ny + 1), source=0.0_wp)
this%is_init = .true.
end subroutine ocean_varmix_init