rdb_ocean_varmix Module

VarMix capability [4]: produces the spatially-varying thickness- and tracer-diffusion coefficient face fields (khth_u/khth_v, khtr_u/khtr_v, m^2/s) that GM (rdb_ocean_gm) and the future Redi path consume — replacing the constant khth they fill from for v1.

Two ingredients, both clean-room from the literature:

  • A resolution function Res_fn in [0,1] (Hallberg 2013) that turns the parameterization OFF where the deformation radius is well resolved (Ld >> dx) and ON where it is not. In the divide-free form for power p:

    f2_dx2 = (dx^2 + dy^2) * max(f^2, eps^2) beta_dx2 = oneOrTwo * (dx^2 + dy^2) * |grad f| dx_term = f2_dx2 + cg1 * beta_dx2 Res_fn = dx_term^(p/2) / (dx_term^(p/2) + (alpha*cg1)^p)

    where cg1 is the first baroclinic gravity-wave speed (the wavespeed slot), |grad f| the FULL discrete 2D Coriolis- gradient magnitude (so the equatorial f -> 0 limit stays finite via the beta term — no divide-by-zero), oneOrTwo = 2 under the Gill (1982) equatorial-Ld convention (default). f2_dx2 and beta_dx2 are STATIC (functions of metrics + f only) — precomputed once at init with host loops; only Res_fn is rebuilt per thermo step from the (slowly varying) cg1. eps = VERY_SMALL_FREQUENCY.

  • A Visbeck (1997) / Eady (1949) baroclinicity scaling KhTh += khth_slope_cff * L2 * SN where SN is the Eady growth rate (thickness-weighted vertical average of sqrt(S^2 N^2)) and L2 = visbeck_l_scale^2 (or visbeck_l_scale^2 * areaCu if the knob is negative ⇒ a nondimensional scale times the cell area).

SN_u (calc_Visbeck_coeffs thickness-weighted path):

SN_u = sum_k sqrt(S2 * N2) * H_geom / sum_k H_geom    (k = 2..nz)
H_geom = sqrt( sqrt(h(i,k)*h(i+1,k)) * sqrt(h(i,k-1)*h(i+1,k-1)) )
S2     = slope_x(i,k)^2 + (h-weighted avg of the 4 corner slope_y^2)
N2     = max(0, n2_u(i,k))
(optional S2 limit S2 = S2*S2max/(S2+S2max) only if visbeck_max_slope>0)

The orthogonal slope is already folded into S2 (the h-weighted 4-corner slope_y^2 term), so SN_u is FINAL after the thickness-weighted sum — no separate SN_v combine (MOM6 calc_Visbeck_coeffs_old; the SN_v 4-corner combine belongs to the distinct calc_Eady_growth_rate_2D path).

Assembly order (Res_fn BEFORE the clamp) per face: Kh = khth Kh += khth_slope_cff * L2 * SN Kh = Res_fn (when resoln_scaled_khth) Kh = max(khth_min, min(Kh, khth_max)) (min only when khth_max>0) This is the pre-CFL base* KhTh face field. The diffusive-CFL cap is owned by GM (it holds dt + the native face metrics): GM does KH = min(KH_CFL, base). When VarMix is OFF, GM falls back to its constant khth ⇒ byte-identical.

Bottom-up convention (k=1 bed, k=nz surface; interface K=1 bed, K=nz+1 surface — both carry zero slope from the slopes slot).

Deferred (documented): EBT/SQG vertical-structure functions (KhTh stays 2D), the MEKE additive term, depth tapering, the calc_Eady_growth_rate_2D outcrop-cropping filter, and the OBC-aware face interpolation (interior straddle-average only for now).

Default off (&ocean_varmix_nml enable = .false.) ⇒ varmix_compute is never called and GM keeps its constant khth ⇒ bit-identical.

References: Visbeck, Marshall, Haine & Spall (1997) JPO 27, 381-402; Hallberg (2013) Ocean Modelling 72, 92-103; Eady (1949) Tellus 1, 33-52; Chelton, deSzoeke, Schlax, El Naggar & Siwertz (1998) JPO 28, 433-460; Gill (1982) “Atmosphere-Ocean Dynamics”. No source ported.


Uses

  • module~~rdb_ocean_varmix~~UsesGraph module~rdb_ocean_varmix rdb_ocean_varmix iso_fortran_env iso_fortran_env module~rdb_ocean_varmix->iso_fortran_env module~rdb_constants rdb_constants module~rdb_ocean_varmix->module~rdb_constants module~rdb_grid rdb_grid module~rdb_ocean_varmix->module~rdb_grid module~rdb_mem_report rdb_mem_report module~rdb_ocean_varmix->module~rdb_mem_report module~rdb_multilayer_state rdb_multilayer_state module~rdb_ocean_varmix->module~rdb_multilayer_state module~rdb_ocean_isopycnal_slopes rdb_ocean_isopycnal_slopes module~rdb_ocean_varmix->module~rdb_ocean_isopycnal_slopes module~rdb_ocean_metrics rdb_ocean_metrics module~rdb_ocean_varmix->module~rdb_ocean_metrics module~rdb_ocean_wave_speed rdb_ocean_wave_speed module~rdb_ocean_varmix->module~rdb_ocean_wave_speed pic_types pic_types module~rdb_constants->pic_types module~rdb_grid->module~rdb_constants module~rdb_mem_report->iso_fortran_env module~rdb_mem_report->module~rdb_constants pic_logger pic_logger module~rdb_mem_report->pic_logger pic_strings pic_strings module~rdb_mem_report->pic_strings module~rdb_multilayer_state->iso_fortran_env module~rdb_multilayer_state->module~rdb_constants module~rdb_multilayer_state->module~rdb_grid module~rdb_multilayer_state->module~rdb_mem_report module~rdb_efp rdb_efp module~rdb_multilayer_state->module~rdb_efp module~rdb_error_ring rdb_error_ring module~rdb_multilayer_state->module~rdb_error_ring module~rdb_tracer rdb_tracer module~rdb_multilayer_state->module~rdb_tracer module~rdb_multilayer_state->pic_logger module~rdb_ocean_isopycnal_slopes->iso_fortran_env module~rdb_ocean_isopycnal_slopes->module~rdb_constants module~rdb_ocean_isopycnal_slopes->module~rdb_grid module~rdb_ocean_isopycnal_slopes->module~rdb_mem_report module~rdb_ocean_isopycnal_slopes->module~rdb_multilayer_state module~rdb_ocean_isopycnal_slopes->module~rdb_ocean_metrics module~rdb_eos rdb_eos module~rdb_ocean_isopycnal_slopes->module~rdb_eos module~rdb_ocean_metrics->iso_fortran_env module~rdb_ocean_metrics->module~rdb_constants module~rdb_ocean_metrics->module~rdb_grid module~rdb_ocean_metrics->module~rdb_mem_report module~rdb_ocean_metrics->module~rdb_error_ring module~rdb_io_netcdf rdb_io_netcdf module~rdb_ocean_metrics->module~rdb_io_netcdf module~rdb_ocean_bipolar rdb_ocean_bipolar module~rdb_ocean_metrics->module~rdb_ocean_bipolar module~rdb_ocean_fold rdb_ocean_fold module~rdb_ocean_metrics->module~rdb_ocean_fold module~rdb_ocean_status rdb_ocean_status module~rdb_ocean_metrics->module~rdb_ocean_status netcdf netcdf module~rdb_ocean_metrics->netcdf module~rdb_ocean_metrics->pic_logger module~rdb_ocean_metrics->pic_strings module~rdb_ocean_wave_speed->iso_fortran_env module~rdb_ocean_wave_speed->module~rdb_constants module~rdb_ocean_wave_speed->module~rdb_grid module~rdb_ocean_wave_speed->module~rdb_mem_report module~rdb_ocean_wave_speed->module~rdb_multilayer_state module~rdb_ocean_wave_speed->module~rdb_ocean_metrics module~rdb_efp->iso_fortran_env ieee_arithmetic ieee_arithmetic module~rdb_efp->ieee_arithmetic module~rdb_eos->module~rdb_constants module~rdb_eos->module~rdb_grid module~rdb_error_ring->pic_logger module~rdb_io_netcdf->iso_fortran_env module~rdb_io_netcdf->module~rdb_constants module~rdb_io_netcdf->module~rdb_error_ring module~rdb_io_netcdf->netcdf module~rdb_io_netcdf->pic_logger module~rdb_io_netcdf->pic_strings iso_c_binding iso_c_binding module~rdb_io_netcdf->iso_c_binding module~rdb_ocean_bipolar->module~rdb_constants module~rdb_ocean_fold->module~rdb_constants module~rdb_tracer->iso_fortran_env module~rdb_tracer->module~rdb_constants module~rdb_tracer->module~rdb_grid module~rdb_tracer->module~rdb_mem_report

Used by

  • module~~rdb_ocean_varmix~~UsedByGraph module~rdb_ocean_varmix rdb_ocean_varmix module~rdb_ocean_dyn rdb_ocean_dyn module~rdb_ocean_dyn->module~rdb_ocean_varmix module~rdb_ocean_meke rdb_ocean_meke module~rdb_ocean_dyn->module~rdb_ocean_meke module~rdb_ocean_meke->module~rdb_ocean_varmix module~rdb_ocean_state rdb_ocean_state module~rdb_ocean_state->module~rdb_ocean_varmix module~rdb_ocean_state->module~rdb_ocean_dyn module~rdb_ocean_state->module~rdb_ocean_meke module~rdb_driver rdb_driver module~rdb_driver->module~rdb_ocean_dyn module~rdb_driver->module~rdb_ocean_state module~rdb_ocean_engine rdb_ocean_engine module~rdb_driver->module~rdb_ocean_engine module~rdb_handle rdb_handle module~rdb_handle->module~rdb_ocean_state module~rdb_handle->module~rdb_ocean_engine module~rdb_ocean_api rdb_ocean_api module~rdb_ocean_api->module~rdb_ocean_dyn module~rdb_ocean_api->module~rdb_handle module~rdb_ocean_diag_derived rdb_ocean_diag_derived module~rdb_ocean_api->module~rdb_ocean_diag_derived module~rdb_ocean_diag_fills rdb_ocean_diag_fills module~rdb_ocean_api->module~rdb_ocean_diag_fills module~rdb_ocean_api->module~rdb_ocean_engine module~rdb_ocean_diag_derived->module~rdb_ocean_state module~rdb_ocean_diag_derived->module~rdb_ocean_diag_fills module~rdb_ocean_diag_fills->module~rdb_ocean_state module~rdb_ocean_engine->module~rdb_ocean_dyn module~rdb_ocean_engine->module~rdb_ocean_state module~rdb_ocean_engine->module~rdb_ocean_diag_derived module~rdb_ocean_engine->module~rdb_ocean_diag_fills module~rdb_ocean_setup rdb_ocean_setup module~rdb_ocean_engine->module~rdb_ocean_setup module~rdb_ocean_setup->module~rdb_ocean_dyn module~rdb_ocean_setup->module~rdb_ocean_state

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private, parameter :: H_SUBROUNDOFF4 = 1.0e-40_wp

Tiny denominator armour for the 4-corner slope_y weighted average (mirrors the MOM6 H_subroundoff^4 guard).

real(kind=wp), private, parameter :: VERY_SMALL_FREQUENCY = 1.0e-17_wp

Floor on f (1/s) inside f2_dx2 so the resolution function stays finite at the equator (where f = 0; the beta term then dominates).


Derived Types

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.

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
procedure, public, non_overridable :: bytes => ocean_varmix_bytes
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

Functions

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)

private pure function varmix_assemble(kh_bg, cff, l2, sn, res_fn, resoln, kh_min, kh_max, do_visbeck) result(kh)

Assembly chain in the load-bearing order: background + Visbeck addend, THEN Res_fn scale, THEN clamp. kh_max <= 0 ⇒ no upper cap.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: kh_bg
real(kind=wp), intent(in) :: cff
real(kind=wp), intent(in) :: l2
real(kind=wp), intent(in) :: sn
real(kind=wp), intent(in) :: res_fn
logical, intent(in) :: resoln
real(kind=wp), intent(in) :: kh_min
real(kind=wp), intent(in) :: kh_max
logical, intent(in) :: do_visbeck

Return Value real(kind=wp)

private pure function varmix_dfdx_vface(f_centre, nx, ny, i, j, idx) result(dfdx)

Cross-face df/dx at a v-face (j interior): average of the centred x-derivatives in the south (j-1) and north (j) rows.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: f_centre(nx,ny)
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: i
integer, intent(in) :: j
real(kind=wp), intent(in) :: idx

Return Value real(kind=wp)

private pure function varmix_dfdy_uface(f_centre, nx, ny, i, j, idy) result(dfdy)

Cross-face df/dy at a u-face (i interior): average of the two centred y-derivatives in the west (i-1) and east (i) columns, clamped at the j edges (one-sided / zero there).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: f_centre(nx,ny)
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: i
integer, intent(in) :: j
real(kind=wp), intent(in) :: idy

Return Value real(kind=wp)

private pure function varmix_res_fn(f2_dx2, beta_dx2, cg1, alpha, p) result(r)

Divide-free resolution function for power p (even). p=2: dx_term/(dx_term + (alpha*cg1)^2); general even p: dx_term^(p/2)/(dx_term^(p/2) + (alpha*cg1)^p). dx_term = f2_dx2 + cg1*beta_dx2. -> 1 where unresolved, -> 0 where Ld>>dx.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: f2_dx2
real(kind=wp), intent(in) :: beta_dx2
real(kind=wp), intent(in) :: cg1
real(kind=wp), intent(in) :: alpha
integer, intent(in) :: p

Return Value real(kind=wp)


Subroutines

public subroutine varmix_compute(grid, metrics, this, slopes, wavespeed, ms)

Fill res_fn_*, sn_*, khth_*, khtr_* (the pre-CFL base face coefficients) from the static grid terms, the slopes/N^2 slot, and the first-mode wave speed cg1. No-op when disabled / the deps are absent. The CFL cap is applied downstream by GM.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(ocean_varmix_t), intent(inout) :: this
type(ocean_slopes_t), intent(in) :: slopes
type(ocean_wave_speed_t), intent(in) :: wavespeed
type(multilayer_state_t), intent(in) :: ms

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)

private subroutine ocean_varmix_destroy(this)

Arguments

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

private subroutine ocean_varmix_enter_data(this)

Arguments

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

private subroutine ocean_varmix_enter_data_impl(this)

Arguments

Type IntentOptional Attributes Name
type(ocean_varmix_t), intent(inout) :: this

private subroutine ocean_varmix_exit_data(this)

Arguments

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

private subroutine ocean_varmix_exit_data_impl(this)

Arguments

Type IntentOptional Attributes Name
type(ocean_varmix_t), intent(inout) :: this

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

private subroutine varmix_compute_impl(nx, ny, nz, p, alpha, resoln_khth, resoln_khtr, interp_res, do_visbeck, s2max, khth, khtr, khth_cff, khtr_cff, khth_min, khth_max, khtr_min, khtr_max, f2_dx2_u, f2_dx2_v, beta_dx2_u, beta_dx2_v, l2_u, l2_v, cg1, h_layer, slope_x, slope_y, n2_u, n2_v, res_fn_u, res_fn_v, sn_u, sn_v, khth_u, khth_v, khtr_u, khtr_v)

Flat-impl VarMix kernel (explicit-shape; NVHPC descriptor-walk-free). Three phases: (1) Res_fn at faces (cg1 interpolated to faces or the centre-Res_fn averaged, per interp_res), (2) Eady SN at u/v faces (thickness-weighted column reductions with the orthogonal slope folded into S^2, scalar accumulators — SN is final, no SN_v combine), (3) the assembly (Visbeck addend, Res_fn scale, clamp) into the KhTh/KhTr base.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: nz
integer, intent(in) :: p
real(kind=wp), intent(in) :: alpha
logical, intent(in) :: resoln_khth
logical, intent(in) :: resoln_khtr
logical, intent(in) :: interp_res
logical, intent(in) :: do_visbeck
real(kind=wp), intent(in) :: s2max
real(kind=wp), intent(in) :: khth
real(kind=wp), intent(in) :: khtr
real(kind=wp), intent(in) :: khth_cff
real(kind=wp), intent(in) :: khtr_cff
real(kind=wp), intent(in) :: khth_min
real(kind=wp), intent(in) :: khth_max
real(kind=wp), intent(in) :: khtr_min
real(kind=wp), intent(in) :: khtr_max
real(kind=wp), intent(in) :: f2_dx2_u(nx+1,ny)
real(kind=wp), intent(in) :: f2_dx2_v(nx,ny+1)
real(kind=wp), intent(in) :: beta_dx2_u(nx+1,ny)
real(kind=wp), intent(in) :: beta_dx2_v(nx,ny+1)
real(kind=wp), intent(in) :: l2_u(nx+1,ny)
real(kind=wp), intent(in) :: l2_v(nx,ny+1)
real(kind=wp), intent(in) :: cg1(nx,ny)
real(kind=wp), intent(in) :: h_layer(nx,ny,nz)
real(kind=wp), intent(in) :: slope_x(nx+1,ny,nz+1)
real(kind=wp), intent(in) :: slope_y(nx,ny+1,nz+1)
real(kind=wp), intent(in) :: n2_u(nx+1,ny,nz+1)
real(kind=wp), intent(in) :: n2_v(nx,ny+1,nz+1)
real(kind=wp), intent(out) :: res_fn_u(nx+1,ny)
real(kind=wp), intent(out) :: res_fn_v(nx,ny+1)
real(kind=wp), intent(out) :: sn_u(nx+1,ny)
real(kind=wp), intent(out) :: sn_v(nx,ny+1)
real(kind=wp), intent(out) :: khth_u(nx+1,ny)
real(kind=wp), intent(out) :: khth_v(nx,ny+1)
real(kind=wp), intent(out) :: khtr_u(nx+1,ny)
real(kind=wp), intent(out) :: khtr_v(nx,ny+1)

private pure subroutine varmix_sn_u(nx, ny, nz, do_visbeck, s2max, h_layer, slope_x, slope_y, n2_u, sn_u)

Thickness-weighted Eady growth rate at u-faces (own component). Interior u-face (i=2..nx) pairs centre columns iw=i-1 (west) and i (east). Interior interfaces K=2..nz; H_geom = sqrt(sqrt(h_iw,k * h_i,k) * sqrt(h_iw,k-1 * h_i,k-1)). S2 = slope_x^2 + the four corner slope_y^2 h-weighted to the u-face; S2 optionally limited. SN_u = sum sqrt(S2*N2)*H_geom / sum H_geom.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: nz
logical, intent(in) :: do_visbeck
real(kind=wp), intent(in) :: s2max
real(kind=wp), intent(in) :: h_layer(nx,ny,nz)
real(kind=wp), intent(in) :: slope_x(nx+1,ny,nz+1)
real(kind=wp), intent(in) :: slope_y(nx,ny+1,nz+1)
real(kind=wp), intent(in) :: n2_u(nx+1,ny,nz+1)
real(kind=wp), intent(out) :: sn_u(nx+1,ny)

private pure subroutine varmix_sn_v(nx, ny, nz, do_visbeck, s2max, h_layer, slope_x, slope_y, n2_v, sn_v)

Thickness-weighted Eady growth rate at v-faces (mirror of varmix_sn_u). Interior v-face (j=2..ny) pairs js=j-1 (south) + j.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: nz
logical, intent(in) :: do_visbeck
real(kind=wp), intent(in) :: s2max
real(kind=wp), intent(in) :: h_layer(nx,ny,nz)
real(kind=wp), intent(in) :: slope_x(nx+1,ny,nz+1)
real(kind=wp), intent(in) :: slope_y(nx,ny+1,nz+1)
real(kind=wp), intent(in) :: n2_v(nx,ny+1,nz+1)
real(kind=wp), intent(out) :: sn_v(nx,ny+1)