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.
|grad f| is the FULL discrete 2D Coriolis-gradient magnitude built
from f_centre (cell-centre) differences interpolated to each face;
on an f-plane it is identically 0 ⇒ beta_dx2 = 0 (and the resolution
function reduces to the midlatitude f^2-only form).
| Type | Intent | Optional | 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) |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=wp), | private | :: | d2 | ||||
| real(kind=wp), | private | :: | dfdx | ||||
| real(kind=wp), | private | :: | dfdy | ||||
| real(kind=wp), | private | :: | fu | ||||
| real(kind=wp), | private | :: | fv | ||||
| integer, | private | :: | i | ||||
| integer, | private | :: | j | ||||
| integer, | private | :: | nx | ||||
| integer, | private | :: | ny | ||||
| real(kind=wp), | private | :: | one_or_two |
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. !! !! `|grad f|` is the FULL discrete 2D Coriolis-gradient magnitude built !! from `f_centre` (cell-centre) differences interpolated to each face; !! on an f-plane it is identically 0 ⇒ beta_dx2 = 0 (and the resolution !! function reduces to the midlatitude `f^2`-only form). class(ocean_varmix_t), intent(inout) :: this type(ocean_metrics_t), intent(in) :: metrics real(wp), intent(in) :: f_centre(this%nx_total, this%ny_total) integer :: nx, ny, i, j real(wp) :: one_or_two, d2, fu, fv real(wp) :: dfdx, dfdy if (.not. this%is_init) return nx = this%nx_total ny = this%ny_total one_or_two = 1.0_wp if (this%gill_equatorial_ld) one_or_two = 2.0_wp ! ---- u-faces (i = 2..nx interior; edges left 0 ⇒ Res_fn = 0 there). ---- do j = 1, ny do i = 2, nx d2 = metrics%dxCu(i, j)*metrics%dxCu(i, j) + & metrics%dyCu(i, j)*metrics%dyCu(i, j) ! f at the u-face = straddle-average of the two centre f's. fu = 0.5_wp*(f_centre(i - 1, j) + f_centre(i, j)) this%f2_dx2_u(i, j) = d2*max(fu*fu, & VERY_SMALL_FREQUENCY*VERY_SMALL_FREQUENCY) ! |grad f| at the u-face: df/dx across the face, df/dy averaged ! from the two straddling centre rows. dfdx = (f_centre(i, j) - f_centre(i - 1, j))*metrics%idxCu(i, j) dfdy = varmix_dfdy_uface(f_centre, nx, ny, i, j, metrics%idyCu(i, j)) this%beta_dx2_u(i, j) = one_or_two*d2*sqrt(dfdx*dfdx + dfdy*dfdy) if (this%visbeck_l_scale < 0.0_wp) then this%l2_u(i, j) = this%visbeck_l_scale*this%visbeck_l_scale* & metrics%areaCu(i, j) else this%l2_u(i, j) = this%visbeck_l_scale*this%visbeck_l_scale end if end do end do ! ---- v-faces (j = 2..ny interior). ---- do j = 2, ny do i = 1, nx d2 = metrics%dxCv(i, j)*metrics%dxCv(i, j) + & metrics%dyCv(i, j)*metrics%dyCv(i, j) fv = 0.5_wp*(f_centre(i, j - 1) + f_centre(i, j)) this%f2_dx2_v(i, j) = d2*max(fv*fv, & VERY_SMALL_FREQUENCY*VERY_SMALL_FREQUENCY) dfdy = (f_centre(i, j) - f_centre(i, j - 1))*metrics%idyCv(i, j) dfdx = varmix_dfdx_vface(f_centre, nx, ny, i, j, metrics%idxCv(i, j)) this%beta_dx2_v(i, j) = one_or_two*d2*sqrt(dfdx*dfdx + dfdy*dfdy) if (this%visbeck_l_scale < 0.0_wp) then this%l2_v(i, j) = this%visbeck_l_scale*this%visbeck_l_scale* & metrics%areaCv(i, j) else this%l2_v(i, j) = this%visbeck_l_scale*this%visbeck_l_scale end if end do end do end subroutine ocean_varmix_build_static