evp_str_s_relax_impl Subroutine

private pure subroutine evp_str_s_relax_impl(areaT, zeta, sh_ds, mi_ratio_a_q, i_1pdt_t, dt_2tdamp, i_ec2, str_s, nx, ny)

str_s relax (:1137-1143). Corners in [1,nx+1]x[1,ny+1]; the 4 surrounding T-cells at an array-edge corner are handled by zeta’s own ghost values (zero-mass ghost cells => zeta=0 there, contributing nothing) — no special-case branch needed.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: areaT(nx,ny)
real(kind=wp), intent(in) :: zeta(nx,ny)
real(kind=wp), intent(in) :: sh_ds(nx+1,ny+1)
real(kind=wp), intent(in) :: mi_ratio_a_q(nx+1,ny+1)
real(kind=wp), intent(in) :: i_1pdt_t
real(kind=wp), intent(in) :: dt_2tdamp
real(kind=wp), intent(in) :: i_ec2
real(kind=wp), intent(inout) :: str_s(nx+1,ny+1)
integer, intent(in) :: nx
integer, intent(in) :: ny

Calls

proc~~evp_str_s_relax_impl~~CallsGraph proc~evp_str_s_relax_impl evp_str_s_relax_impl local local proc~evp_str_s_relax_impl->local

Called by

proc~~evp_str_s_relax_impl~~CalledByGraph proc~evp_str_s_relax_impl evp_str_s_relax_impl proc~ice_evp_dynamics_impl ice_evp_dynamics_impl proc~ice_evp_dynamics_impl->proc~evp_str_s_relax_impl proc~ice_evp_dynamics ice_evp_dynamics proc~ice_evp_dynamics->proc~ice_evp_dynamics_impl proc~ice_evp_step ice_evp_step proc~ice_evp_step->proc~ice_evp_dynamics proc~engine_step_ice engine_step_ice proc~engine_step_ice->proc~ice_evp_step proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_step_ice proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step_ice

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private :: a_ne
real(kind=wp), private :: a_nw
real(kind=wp), private :: a_se
real(kind=wp), private :: a_sw
integer, private :: ic
integer, private :: jc
real(kind=wp), private :: weighted_zeta
real(kind=wp), private :: zeta_ne
real(kind=wp), private :: zeta_nw
real(kind=wp), private :: zeta_se
real(kind=wp), private :: zeta_sw

Source Code

   pure subroutine evp_str_s_relax_impl(areaT, zeta, sh_ds, mi_ratio_a_q, &
                                        i_1pdt_t, dt_2tdamp, i_ec2, str_s, nx, ny)
      !! str_s relax (:1137-1143). Corners in [1,nx+1]x[1,ny+1]; the 4
      !! surrounding T-cells at an array-edge corner are handled by
      !! `zeta`'s own ghost values (zero-mass ghost cells => zeta=0
      !! there, contributing nothing) — no special-case branch needed.
      integer, intent(in) :: nx, ny
      real(wp), intent(in) :: areaT(nx, ny)
      real(wp), intent(in) :: zeta(nx, ny)
      real(wp), intent(in) :: sh_ds(nx + 1, ny + 1)
      real(wp), intent(in) :: mi_ratio_a_q(nx + 1, ny + 1)
      real(wp), intent(in) :: i_1pdt_t, dt_2tdamp, i_ec2
      real(wp), intent(inout) :: str_s(nx + 1, ny + 1)
      integer :: ic, jc
      real(wp) :: zeta_sw, zeta_se, zeta_nw, zeta_ne, a_sw, a_se, a_nw, a_ne
      real(wp) :: weighted_zeta

      ! Interior corners only.  At an array-edge corner zeta/areaT have no
      ! defined 4th neighbour; these are ghost/land corners under the
      ! ghost policy, never read by a physical-interior momentum face, and
      ! str_s is left untouched there.  The loop range, not an in-loop
      ! guard, excludes them -- see `evp_build_masks_impl` (nvfortran CPU
      ! vectoriser, four-way guard).
      do concurrent(jc=2:ny, ic=2:nx) &
         local(zeta_sw, zeta_se, zeta_nw, zeta_ne, a_sw, a_se, a_nw, a_ne, weighted_zeta)
         zeta_sw = zeta(ic - 1, jc - 1)
         zeta_se = zeta(ic, jc - 1)
         zeta_nw = zeta(ic - 1, jc)
         zeta_ne = zeta(ic, jc)
         a_sw = areaT(ic - 1, jc - 1)
         a_se = areaT(ic, jc - 1)
         a_nw = areaT(ic - 1, jc)
         a_ne = areaT(ic, jc)
         weighted_zeta = ((a_sw*zeta_sw + a_ne*zeta_ne) + (a_se*zeta_se + a_nw*zeta_nw))
         str_s(ic, jc) = i_1pdt_t*(str_s(ic, jc) + (i_ec2*dt_2tdamp)* &
                                   (weighted_zeta*mi_ratio_a_q(ic, jc)*sh_ds(ic, jc)))
      end do
   end subroutine evp_str_s_relax_impl