ocean_surfstress_set_2gyre Subroutine

private subroutine ocean_surfstress_set_2gyre(this, grid, taux_mag, j_offset, ny_global)

Fill tau_x with the MOM6 2gyre profile, tau_x(i,j) = taux_mag · (1 − cos(2π · (y − y_south) / y_len)), and zero tau_y. In Cartesian terms (y − y_south) / y_len is the normalised position from the south wall of the physical domain (0 at south, 1 at north), so the formula reduces to taux_mag · (1 − cos(2π · ((j_phys − 0.5) / ny_phys))) with j_phys = j − nghost. Physical-interior rows only; ghost rows stay at zero so wall faces see no spurious stress. Host only — call enter_data afterwards (or !$acc update device if already mapped).

j_offset is the global physical-index offset of this rank’s first physical row (= decomp%j_start - 1). ny_global is the global meridional physical extent. Both default to the single-rank values (0 and grid%ny_phys), preserving byte-identical single-rank behaviour.

Type Bound

ocean_surface_stress_t

Arguments

Type IntentOptional Attributes Name
class(ocean_surface_stress_t), intent(inout) :: this
type(hgrid_t), intent(in) :: grid
real(kind=wp), intent(in) :: taux_mag
integer, intent(in), optional :: j_offset
integer, intent(in), optional :: ny_global

Calls

proc~~ocean_surfstress_set_2gyre~~CallsGraph proc~ocean_surfstress_set_2gyre ocean_surface_stress_t%ocean_surfstress_set_2gyre proc~ocean_surfstress_refresh_stress_mag ocean_surfstress_refresh_stress_mag proc~ocean_surfstress_set_2gyre->proc~ocean_surfstress_refresh_stress_mag proc~ocean_surface_stress_refresh_mag ocean_surface_stress_refresh_mag proc~ocean_surfstress_refresh_stress_mag->proc~ocean_surface_stress_refresh_mag proc~ocean_surfstress_derived_impl ocean_surfstress_derived_impl proc~ocean_surface_stress_refresh_mag->proc~ocean_surfstress_derived_impl local local proc~ocean_surfstress_derived_impl->local

Called by

proc~~ocean_surfstress_set_2gyre~~CalledByGraph proc~ocean_surfstress_set_2gyre ocean_surface_stress_t%ocean_surfstress_set_2gyre proc~configure_ocean_forcing configure_ocean_forcing proc~configure_ocean_forcing->proc~ocean_surfstress_set_2gyre proc~engine_setup engine_setup proc~engine_setup->proc~configure_ocean_forcing 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, parameter :: TWO_PI = 8.0_wp*atan(1.0_wp)
integer, private :: i
integer, private :: j
integer, private :: j_phys
integer, private :: joff
integer, private :: ng
integer, private :: nyg
real(kind=wp), private :: y_rel

Source Code

   subroutine ocean_surfstress_set_2gyre(this, grid, taux_mag, j_offset, ny_global)
      !! Fill `tau_x` with the MOM6 2gyre profile,
      !! `tau_x(i,j) = taux_mag · (1 − cos(2π · (y − y_south) / y_len))`,
      !! and zero `tau_y`.  In Cartesian terms `(y − y_south) / y_len`
      !! is the normalised position from the south wall of the physical
      !! domain (0 at south, 1 at north), so the formula reduces to
      !! `taux_mag · (1 − cos(2π · ((j_phys − 0.5) / ny_phys)))` with
      !! `j_phys = j − nghost`.  Physical-interior rows only; ghost rows
      !! stay at zero so wall faces see no spurious stress.  Host only —
      !! call `enter_data` afterwards (or `!$acc update device` if
      !! already mapped).
      !!
      !! `j_offset` is the global physical-index offset of this rank's
      !! first physical row (= `decomp%j_start - 1`).  `ny_global` is
      !! the global meridional physical extent.  Both default to the
      !! single-rank values (`0` and `grid%ny_phys`), preserving
      !! byte-identical single-rank behaviour.
      class(ocean_surface_stress_t), intent(inout) :: this
      type(hgrid_t), intent(in) :: grid
      real(wp), intent(in) :: taux_mag
      integer, intent(in), optional :: j_offset, ny_global
      real(wp), parameter :: TWO_PI = 8.0_wp*atan(1.0_wp)
      real(wp) :: y_rel
      integer :: i, j, j_phys, ng
      integer :: joff, nyg

      joff = 0
      if (present(j_offset)) joff = j_offset
      nyg = grid%ny_phys
      if (present(ny_global)) nyg = ny_global

      this%tau_x = 0.0_wp
      this%tau_y = 0.0_wp
      ng = grid%nghost
      do j = 1, size(this%tau_x, 2)
         j_phys = j - ng
         ! Every storage row inside the GLOBAL domain, ghost rows included:
         ! a ghost row beyond an MPI seam is a neighbour's physical row and
         ! must carry its stress (read by the stress/ustar stencils), not
         ! the zero a wall ghost gets.  Rows beyond the global edges stay 0.
         if (j_phys + joff < 1 .or. j_phys + joff > nyg) cycle
         ! Global meridional normalisation: (j_phys + joff) gives the
         ! global physical row index; ny_global is the global extent.
         y_rel = (real(j_phys + joff, wp) - 0.5_wp)/real(nyg, wp)
         do i = 1, size(this%tau_x, 1)
            this%tau_x(i, j) = taux_mag*(1.0_wp - cos(TWO_PI*y_rel))
         end do
      end do
      call ocean_surfstress_refresh_stress_mag(this)
   end subroutine ocean_surfstress_set_2gyre