ocean_varmix_t Derived Type

type, public :: ocean_varmix_t

Spatially-varying lateral-diffusivity-coefficient state. All fields default to the inert (enable=.false.) configuration so an ocean run that never sets &ocean_varmix_nml is bit-identical.


Inherited by

type~~ocean_varmix_t~~InheritedByGraph type~ocean_varmix_t ocean_varmix_t type~ocean_state_t ocean_state_t type~ocean_state_t->type~ocean_varmix_t varmix type~ocean_engine_t ocean_engine_t type~ocean_engine_t->type~ocean_state_t state type~ocean_handle_t ocean_handle_t type~ocean_handle_t->type~ocean_state_t state type~ocean_handle_t->type~ocean_engine_t engine

Components

Type Visibility Attributes Name Initial
real(kind=wp), public, allocatable :: beta_dx2_u(:,:)

oneOrTwo*(dx^2+dy^2)*|grad f| at u-faces, (nx+1,ny). Static.

real(kind=wp), public, allocatable :: beta_dx2_v(:,:)

Same at v-faces, (nx,ny+1).

logical, public :: enable = .false.

Master switch. Off ⇒ varmix_compute is never called and GM uses the scalar khth ⇒ bit-identity. Requires the slopes slot AND the wavespeed slot (loud configure invariant).

real(kind=wp), public, allocatable :: f2_dx2_u(:,:)

(dx^2+dy^2) max(f^2,eps^2) at u-faces, (nx+1,ny). Static.

real(kind=wp), public, allocatable :: f2_dx2_v(:,:)

Same at v-faces, (nx,ny+1).

logical, public :: gill_equatorial_ld = .true.

Gill (1982) equatorial-Ld convention ⇒ oneOrTwo = 2 in beta_dx2 (else Pedlosky ⇒ 1). Static; folded into the precomputed beta_dx2_* at init.

logical, public :: interpolate_res_fn = .false.

.true.: build Res_fn at centres then 2-pt-average to faces. .false. (default, MOM6 default): interpolate cg1 to faces, then recompute Res_fn from the face f2_dx2/beta_dx2/cg1.

logical, public :: is_init = .false.

True between init and destroy; gate on this (never on allocated, which misses the GPU mapping).

integer, public :: kh_res_fn_power = 2

Resolution-function power p (even; 2 is the production form).

real(kind=wp), public :: kh_res_scale_coef = 1.0_wp

Resolution-function alpha (the (alpha*cg1)^p denom coef).

real(kind=wp), public :: khth = 0.0_wp

Background thickness diffusivity KhTh (m^2/s) — the constant the Visbeck term and Res_fn scale. Mirrors &ocean_gm_nml khth.

real(kind=wp), public :: khth_max = 0.0_wp

Upper clamp on KhTh (m^2/s); <= 0 ⇒ no upper cap.

real(kind=wp), public :: khth_min = 0.0_wp

Lower clamp on the assembled KhTh (m^2/s).

real(kind=wp), public :: khth_slope_cff = 0.0_wp

Visbeck coefficient alpha_s for the KhTh chain.

real(kind=wp), public, allocatable :: khth_u(:,:)

Pre-CFL base thickness diffusivity at u-faces (m^2/s), (nx+1,ny) — threaded into GM as the optional external base.

real(kind=wp), public, allocatable :: khth_v(:,:)

Pre-CFL base KhTh at v-faces, (nx,ny+1).

real(kind=wp), public :: khtr = 0.0_wp

Background tracer diffusivity KhTr (m^2/s) for the future Redi.

real(kind=wp), public :: khtr_max = 0.0_wp

Upper clamp on KhTr (m^2/s); <= 0 ⇒ no upper cap.

real(kind=wp), public :: khtr_min = 0.0_wp

Lower clamp on KhTr (m^2/s).

real(kind=wp), public :: khtr_slope_cff = 0.0_wp

Visbeck coefficient for the KhTr chain.

real(kind=wp), public, allocatable :: khtr_u(:,:)

Pre-CFL base tracer diffusivity at u-faces (m^2/s), (nx+1,ny) — consumed by the future Redi path.

real(kind=wp), public, allocatable :: khtr_v(:,:)

Pre-CFL base KhTr at v-faces, (nx,ny+1).

real(kind=wp), public, allocatable :: l2_u(:,:)

Visbeck L^2 at u-faces (m^2), (nx+1,ny). Static.

real(kind=wp), public, allocatable :: l2_v(:,:)

Visbeck L^2 at v-faces (m^2), (nx,ny+1).

integer, public :: nx_total = 0
integer, public :: ny_total = 0
integer, public :: nz_ml = 0
real(kind=wp), public, allocatable :: res_fn_u(:,:)

Resolution function at u-faces (nondim, [0,1]), (nx+1,ny).

real(kind=wp), public, allocatable :: res_fn_v(:,:)

Resolution function at v-faces, (nx,ny+1).

logical, public :: resoln_scaled_khth = .false.

Multiply the assembled KhTh by Res_fn.

logical, public :: resoln_scaled_khtr = .false.

Multiply the assembled KhTr by Res_fn.

real(kind=wp), public, allocatable :: sn_u(:,:)

Eady growth rate S*N at u-faces (1/s), (nx+1,ny).

real(kind=wp), public, allocatable :: sn_v(:,:)

Eady growth rate at v-faces, (nx,ny+1).

logical, public :: use_visbeck = .false.

Add the Visbeck/Eady khth_slope_cff * L2 * SN term.

real(kind=wp), public :: visbeck_l_scale = 0.0_wp

Visbeck length scale L (m); if < 0, |L|^2 * areaCu/areaCv is used (a nondimensional scale times the local cell area).

real(kind=wp), public :: visbeck_max_slope = 0.0_wp

S^2 limiter scale; <= 0 ⇒ no S^2 limit.


Type-Bound Procedures

procedure, public, non_overridable :: build_static => ocean_varmix_build_static

  • private subroutine ocean_varmix_build_static(this, metrics, f_centre)

    Fill the static f2_dx2_*, beta_dx2_*, and l2_* face fields from the (curvilinear) metrics + the cell-centre Coriolis magnitude f_centre. Called ONCE after init + configure + metrics fill (so oneOrTwo, visbeck_l_scale, and the device-resident metrics are known), BEFORE the device map. HOST loops only — these are static (functions of geometry + planetary f) and never change with time.

    Read more…

    Arguments

    Type IntentOptional Attributes Name
    class(ocean_varmix_t), intent(inout) :: this
    type(ocean_metrics_t), intent(in) :: metrics
    real(kind=wp), intent(in) :: f_centre(this%nx_total,this%ny_total)

procedure, public, non_overridable :: bytes => ocean_varmix_bytes

  • private pure function ocean_varmix_bytes(this) result(nbytes)

    Counted allocatable footprint of the VarMix slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

    Arguments

    Type IntentOptional Attributes Name
    class(ocean_varmix_t), intent(in) :: this

    Return Value integer(kind=int64)

procedure, public, non_overridable :: destroy => ocean_varmix_destroy

procedure, public, non_overridable :: enter_data => ocean_varmix_enter_data

procedure, public, non_overridable :: exit_data => ocean_varmix_exit_data

procedure, public, non_overridable :: init => ocean_varmix_init

  • private 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).

    Arguments

    Type IntentOptional Attributes Name
    class(ocean_varmix_t), intent(inout) :: this
    type(hgrid_t), intent(in) :: grid
    integer, intent(in), optional :: nz_ml

Source Code

   type :: ocean_varmix_t
      !! Spatially-varying lateral-diffusivity-coefficient state.  All
      !! fields default to the inert (`enable=.false.`) configuration so an
      !! ocean run that never sets `&ocean_varmix_nml` is bit-identical.
      logical :: is_init = .false.
         !! True between `init` and `destroy`; gate on this (never on
         !! `allocated`, which misses the GPU mapping).
      logical :: enable = .false.
         !! Master switch.  Off ⇒ `varmix_compute` is never called and GM
         !! uses the scalar `khth` ⇒ bit-identity.  Requires the slopes slot
         !! AND the wavespeed slot (loud configure invariant).
      logical :: use_visbeck = .false.
         !! Add the Visbeck/Eady `khth_slope_cff * L2 * SN` term.
      logical :: resoln_scaled_khth = .false.
         !! Multiply the assembled KhTh by `Res_fn`.
      logical :: resoln_scaled_khtr = .false.
         !! Multiply the assembled KhTr by `Res_fn`.
      logical :: gill_equatorial_ld = .true.
         !! Gill (1982) equatorial-Ld convention ⇒ `oneOrTwo = 2` in
         !! `beta_dx2` (else Pedlosky ⇒ 1).  Static; folded into the
         !! precomputed `beta_dx2_*` at init.
      logical :: interpolate_res_fn = .false.
         !! `.true.`: build `Res_fn` at centres then 2-pt-average to faces.
         !! `.false.` (default, MOM6 default): interpolate `cg1` to faces,
         !! then recompute `Res_fn` from the face `f2_dx2/beta_dx2/cg1`.
      integer :: kh_res_fn_power = 2
         !! Resolution-function power `p` (even; 2 is the production form).
      real(wp) :: kh_res_scale_coef = 1.0_wp
         !! Resolution-function `alpha` (the `(alpha*cg1)^p` denom coef).
      real(wp) :: khth = 0.0_wp
         !! Background thickness diffusivity KhTh (m^2/s) — the constant the
         !! Visbeck term and Res_fn scale.  Mirrors `&ocean_gm_nml khth`.
      real(wp) :: khtr = 0.0_wp
         !! Background tracer diffusivity KhTr (m^2/s) for the future Redi.
      real(wp) :: khth_slope_cff = 0.0_wp
         !! Visbeck coefficient `alpha_s` for the KhTh chain.
      real(wp) :: khtr_slope_cff = 0.0_wp
         !! Visbeck coefficient for the KhTr chain.
      real(wp) :: khth_min = 0.0_wp
         !! Lower clamp on the assembled KhTh (m^2/s).
      real(wp) :: khth_max = 0.0_wp
         !! Upper clamp on KhTh (m^2/s); <= 0 ⇒ no upper cap.
      real(wp) :: khtr_min = 0.0_wp
         !! Lower clamp on KhTr (m^2/s).
      real(wp) :: khtr_max = 0.0_wp
         !! Upper clamp on KhTr (m^2/s); <= 0 ⇒ no upper cap.
      real(wp) :: visbeck_l_scale = 0.0_wp
         !! Visbeck length scale L (m); if < 0, |L|^2 * areaCu/areaCv is used
         !! (a nondimensional scale times the local cell area).
      real(wp) :: visbeck_max_slope = 0.0_wp
         !! S^2 limiter scale; <= 0 ⇒ no S^2 limit.

      ! ---- Cached extents ----
      integer :: nx_total = 0
      integer :: ny_total = 0
      integer :: nz_ml = 0

      ! ---- Static grid terms (precomputed once at init) ----
      real(wp), allocatable :: f2_dx2_u(:, :)
         !! `(dx^2+dy^2) max(f^2,eps^2)` at u-faces, `(nx+1,ny)`.  Static.
      real(wp), allocatable :: f2_dx2_v(:, :)
         !! Same at v-faces, `(nx,ny+1)`.
      real(wp), allocatable :: beta_dx2_u(:, :)
         !! `oneOrTwo*(dx^2+dy^2)*|grad f|` at u-faces, `(nx+1,ny)`.  Static.
      real(wp), allocatable :: beta_dx2_v(:, :)
         !! Same at v-faces, `(nx,ny+1)`.
      real(wp), allocatable :: l2_u(:, :)
         !! Visbeck `L^2` at u-faces (m^2), `(nx+1,ny)`.  Static.
      real(wp), allocatable :: l2_v(:, :)
         !! Visbeck `L^2` at v-faces (m^2), `(nx,ny+1)`.

      ! ---- Per-step diagnostics + outputs ----
      real(wp), allocatable :: res_fn_u(:, :)
         !! Resolution function at u-faces (nondim, [0,1]), `(nx+1,ny)`.
      real(wp), allocatable :: res_fn_v(:, :)
         !! Resolution function at v-faces, `(nx,ny+1)`.
      real(wp), allocatable :: sn_u(:, :)
         !! Eady growth rate `S*N` at u-faces (1/s), `(nx+1,ny)`.
      real(wp), allocatable :: sn_v(:, :)
         !! Eady growth rate at v-faces, `(nx,ny+1)`.
      real(wp), allocatable :: khth_u(:, :)
         !! Pre-CFL base thickness diffusivity at u-faces (m^2/s),
         !! `(nx+1,ny)` — threaded into GM as the optional external base.
      real(wp), allocatable :: khth_v(:, :)
         !! Pre-CFL base KhTh at v-faces, `(nx,ny+1)`.
      real(wp), allocatable :: khtr_u(:, :)
         !! Pre-CFL base tracer diffusivity at u-faces (m^2/s), `(nx+1,ny)`
         !! — consumed by the future Redi path.
      real(wp), allocatable :: khtr_v(:, :)
         !! Pre-CFL base KhTr at v-faces, `(nx,ny+1)`.
   contains
      procedure, non_overridable :: init => ocean_varmix_init
      procedure, non_overridable :: destroy => ocean_varmix_destroy
      procedure, non_overridable :: build_static => ocean_varmix_build_static
      procedure, non_overridable :: enter_data => ocean_varmix_enter_data
      procedure, non_overridable :: exit_data => ocean_varmix_exit_data
      procedure, non_overridable :: bytes => ocean_varmix_bytes
   end type ocean_varmix_t