ocean_varmix_build_static Subroutine

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.

|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 Bound

ocean_varmix_t

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)

Calls

proc~~ocean_varmix_build_static~~CallsGraph proc~ocean_varmix_build_static ocean_varmix_t%ocean_varmix_build_static proc~varmix_dfdx_vface varmix_dfdx_vface proc~ocean_varmix_build_static->proc~varmix_dfdx_vface proc~varmix_dfdy_uface varmix_dfdy_uface proc~ocean_varmix_build_static->proc~varmix_dfdy_uface

Called by

proc~~ocean_varmix_build_static~~CalledByGraph proc~ocean_varmix_build_static ocean_varmix_t%ocean_varmix_build_static proc~configure_ocean_varmix configure_ocean_varmix proc~configure_ocean_varmix->proc~ocean_varmix_build_static proc~configure_ocean_lateral configure_ocean_lateral proc~configure_ocean_lateral->proc~configure_ocean_varmix proc~engine_setup engine_setup proc~engine_setup->proc~configure_ocean_lateral proc~complete_ocean_create complete_ocean_create proc~complete_ocean_create->proc~engine_setup proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_setup proc~driver_validate driver_validate proc~driver_validate->proc~engine_setup proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean proc~rdb_ocean_create_finalize rdb_ocean_create_finalize proc~rdb_ocean_create_finalize->proc~complete_ocean_create proc~rdb_ocean_create_from_string rdb_ocean_create_from_string proc~rdb_ocean_create_from_string->proc~complete_ocean_create

Variables

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

Source Code

   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