LCOV - code coverage report
Current view: top level - dynamics/fv - gravity_waves_sources.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 104 108 96.3 %
Date: 2025-03-14 01:26:08 Functions: 2 2 100.0 %

          Line data    Source code
       1             : module gravity_waves_sources
       2             : 
       3             :   use shr_kind_mod, only: r8 => shr_kind_r8
       4             :   use pmgrid, only: plev, plevp
       5             :   use hycoef, only         : hypi
       6             : 
       7             :   implicit none
       8             :   save
       9             :   private
      10             : 
      11             :   public :: gws_src_fnct
      12             : 
      13             :   ! ghosting added by Francis Vitt -- 7 July 2008
      14             :   !
      15             :   ! moved from waccm to fv, changed source of psurf_ref
      16             :   !   -- S Santos -- 10 Aug 2011
      17             : 
      18             :   contains
      19             : 
      20             : 
      21             : !=================================================================
      22             : 
      23        8064 :     subroutine gws_src_fnct(grid, u3,v3,pt, q3, pe, frontgf, frontga)
      24             : 
      25             :       use dynamics_vars, only: t_fvdycore_grid
      26             :       use physconst,     only: zvir, cappa, aearth => rearth
      27             : 
      28             :       implicit none
      29             : 
      30             : ! Input/Output arguments
      31             :       type (t_fvdycore_grid), intent(in) :: grid    ! grid for XY decomp
      32             :       real(r8), intent(in) :: u3(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)          ! zonal velocity
      33             :       real(r8), intent(in) :: v3(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)          ! meridional velocity
      34             :       real(r8), intent(in) :: pt(grid%ifirstxy:grid%ilastxy,grid%jfirstxy:grid%jlastxy,plev)          ! virtual temperature
      35             :       real(r8), intent(in) :: q3(grid%ifirstxy:grid%ilastxy,grid%jfirstxy:grid%jlastxy,plev)          ! water constituent
      36             :       real(r8), intent(in) :: pe(grid%ifirstxy:grid%ilastxy,plevp,grid%jfirstxy:grid%jlastxy)         ! interface pressure
      37             : 
      38             :       real(r8), intent(out) :: frontgf(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)    ! Frontogenesis function
      39             :       real(r8), intent(out) :: frontga(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)    ! Frontogenesis angle
      40             : 
      41             : ! Locals
      42             :       real(r8) :: psurf_ref                        ! surface reference pressure
      43             : 
      44       16128 :       real(r8) :: ptemp(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)       ! temperature
      45       16128 :       real(r8) :: pm(grid%ifirstxy:grid%ilastxy   ,plev,grid%jfirstxy:grid%jlastxy)       ! mid-point pressure
      46             :       real(r8) :: pexf                                ! Exner function
      47             : 
      48       16128 :       real(r8) :: pty(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)         ! temperature meridional gradient
      49       16128 :       real(r8) :: ptx(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)         ! temperature zonal gradient
      50             : 
      51       16128 :       real(r8) :: uy(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)         ! U-wind meridional gradient
      52       16128 :       real(r8) :: ux(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)         ! U-wind zonal gradient
      53             : 
      54       16128 :       real(r8) :: vy(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)         ! V-wind meridional gradient
      55       16128 :       real(r8) :: vx(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)         ! V-wind zonal gradient
      56             : 
      57       16128 :       real(r8) :: ptg(grid%ifirstxy-1:grid%ilastxy+1,plev,grid%jfirstxy-1:grid%jlastxy+1)  ! temperature ghosted
      58       16128 :       real(r8) ::  ug(grid%ifirstxy-1:grid%ilastxy+1,plev,grid%jfirstxy-1:grid%jlastxy+1)  ! U-wind ghosted
      59       16128 :       real(r8) ::  vg(grid%ifirstxy-1:grid%ilastxy+1,plev,grid%jfirstxy-1:grid%jlastxy+1)  ! V-wind ghosted
      60             : 
      61             :       real(r8) :: tglat                               ! tangent-latitude
      62             :       integer  :: i,j,k
      63             :       integer  :: im, ip
      64             :       integer  :: beglatxy, endlatxy, beglonxy, endlonxy
      65             : !-----------------------------------------------------------------------------------------
      66             : 
      67        8064 :       beglatxy = grid%jfirstxy
      68        8064 :       endlatxy = grid%jlastxy
      69        8064 :       beglonxy = grid%ifirstxy
      70        8064 :       endlonxy = grid%ilastxy
      71             : 
      72    40916736 :       pty(:,:,:) = 0._r8
      73    40916736 :       ptx(:,:,:) = 0._r8
      74    40916736 :       uy(:,:,:) = 0._r8
      75    40916736 :       ux(:,:,:) = 0._r8
      76    40916736 :       vy(:,:,:) = 0._r8
      77    40916736 :       vx(:,:,:) = 0._r8
      78    40916736 :       frontgf(:,:,:) = 0._r8
      79    40916736 :       frontga(:,:,:) = 0._r8
      80             : 
      81        8064 :       psurf_ref = hypi(plev+1)
      82             : 
      83             :       !$omp parallel do private (i,j,k,pexf)
      84       32256 :       do j = beglatxy, endlatxy
      85     3177216 :          do k = 1, plev
      86    40908672 :             do i = beglonxy, endlonxy
      87             : 
      88             :                ! Calculate pressure and Exner function
      89    37739520 :                pm(i,k,j) = 0.5_r8 * ( pe(i,k,j) + pe(i,k+1,j) )
      90    37739520 :                pexf      = (psurf_ref / pm(i,k,j))**cappa
      91             : 
      92             :                ! Convert virtual temperature to temperature and calculate potential temperature
      93    40884480 :                ptemp(i,k,j) = pt(i,j,k) / (1._r8 + zvir*q3(i,j,k)) * pexf
      94             : 
      95             :             end do
      96             :          end do
      97             :       end do
      98             : 
      99        8064 :       call ghost_array(grid, ptemp, ptg)
     100        8064 :       call ghost_array(grid, u3, ug)
     101        8064 :       call ghost_array(grid, v3, vg)
     102             : 
     103             :       !$omp parallel do private (i,j,k)
     104     1056384 :       do k=1, plev
     105    13636224 :          do i=beglonxy, endlonxy
     106    51367680 :             do j=beglatxy, endlatxy
     107             : 
     108             :                ! Pot. Temperature
     109    37739520 :                pty(i,k,j) = ( ptg(i,k,j+1) - ptg(i,k,j-1) ) / (2._r8 * grid%dp)
     110    37739520 :                pty(i,k,j) = pty(i,k,j) / aearth
     111             : 
     112             :                ! U-wind
     113    37739520 :                uy(i,k,j) = ( ug(i,k,j+1) - ug(i,k,j-1) ) / (2._r8 * grid%dp)
     114    37739520 :                uy(i,k,j) = uy(i,k,j) / aearth
     115             : 
     116             :                ! V-wind
     117    37739520 :                vy(i,k,j) = ( vg(i,k,j+1) - vg(i,k,j-1) ) / (2._r8 * grid%dp)
     118    50319360 :                vy(i,k,j) = vy(i,k,j) / aearth
     119             : 
     120             :             end do
     121             :          end do
     122             :       end do
     123             : 
     124             :       !++rrg use 1.e-3 floor on cosine terms in the denominator of frontgf
     125             : 
     126             :       !$omp parallel do private (i,j,k,im,ip)
     127     1056384 :       do k=1, plev
     128     4201344 :          do j=beglatxy, endlatxy
     129    41932800 :             do i=beglonxy, endlonxy
     130             : 
     131    37739520 :                im = i-1
     132    37739520 :                ip = i+1
     133             : 
     134             :                ! Pot. Temperature
     135    37739520 :                ptx(i,k,j) = ( ptg(ip,k,j) - ptg(im,k,j) ) / (2._r8 * grid%dl)
     136    37739520 :                ptx(i,k,j) = ptx(i,k,j) / (aearth * (grid%cosp(j)+1.e-3_r8))
     137             : 
     138             :                ! U-wind
     139    37739520 :                ux(i,k,j) = ( ug(ip,k,j) - ug(im,k,j) ) / (2._r8 *grid%dl)
     140    37739520 :                ux(i,k,j) = ux(i,k,j) / (aearth * (grid%cosp(j)+1.e-3_r8))
     141             : 
     142             :                ! V-wind
     143    37739520 :                vx(i,k,j) = ( vg(ip,k,j) - vg(im,k,j) ) / (2._r8 *grid%dl)
     144    40884480 :                vx(i,k,j) = vx(i,k,j) / (aearth * (grid%cosp(j)+1.e-3_r8))
     145             : 
     146             :             end do
     147             :          end do
     148             :       end do
     149             : 
     150             :       !$omp parallel do private (i,j,k, tglat)
     151       32256 :       do j=beglatxy, endlatxy
     152             : 
     153       24192 :          tglat = grid%sinp(j) / (grid%cosp(j)+1.e-3_r8)
     154             : 
     155     3177216 :          do k=1, plev
     156    40908672 :             do i=beglonxy, endlonxy
     157             : 
     158   113218560 :                frontgf(i,k,j) =                                                                          &
     159             :                     - ptx(i,k,j)**2._r8 * (ux(i,k,j) - v3(i,k,j) * tglat / aearth)                          &
     160             :                     - pty(i,k,j)**2._r8 * vy(i,k,j)                                                         &
     161   116363520 :                     - ptx(i,k,j) * pty(i,k,j) * ( vx(i,k,j) + uy(i,k,j) + u3(i,k,j) * tglat / aearth )
     162             : 
     163             :             end do
     164             :          end do
     165             : 
     166             :       end do
     167             : 
     168             :       !--rrg use 1.e-3 floor on cosine terms in the denominator of frontgf
     169             : 
     170             :       !$omp parallel do private (i,j,k)
     171       32256 :       do j=beglatxy, endlatxy
     172     3177216 :          do k=1, plev
     173    40908672 :             do i=beglonxy, endlonxy
     174    40884480 :                frontga(i,k,j) = atan2 ( pty(i,k,j) , ptx(i,k,j) + 1.e-10_r8 )
     175             :             end do
     176             :          end do
     177             :       end do
     178             : 
     179        8064 :       return
     180             : 
     181             :     end subroutine gws_src_fnct
     182             : 
     183       24192 :     subroutine ghost_array(grid, x, xg)
     184             : 
     185             :       ! subroutine added by Francis Vitt -- 7 July 2008
     186             : 
     187             : #if defined( SPMD )
     188             :       use mod_comm,      only: mp_send3d, mp_recv3d
     189             : #endif
     190             :       use dynamics_vars, only: T_FVDYCORE_GRID
     191             : 
     192             :       implicit none
     193             : 
     194             :       ! Input/Output arguments
     195             :       type (T_FVDYCORE_GRID), intent(in) :: grid    ! grid for XY decomp
     196             :       real(r8), intent(in)  :: x(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)          ! zonal velocity
     197             :       real(r8), intent(out) :: xg(grid%ifirstxy-1:grid%ilastxy+1,plev,grid%jfirstxy-1:grid%jlastxy+1)          ! zonal velocity
     198             : 
     199             :       ! local variables
     200       48384 :       real(r8) :: north(grid%ifirstxy:grid%ilastxy,plev)
     201       48384 :       real(r8) :: south(grid%ifirstxy:grid%ilastxy,plev)
     202       48384 :       real(r8) :: east(plev,grid%jfirstxy:grid%jlastxy)
     203       48384 :       real(r8) :: west(plev,grid%jfirstxy:grid%jlastxy)
     204             :       integer  :: im, jm, km, ifirstxy, ilastxy, jfirstxy, jlastxy, iam, myidxy_y, nprxy_x
     205             :       integer  :: itot, dest, src, j, k
     206             : 
     207       24192 :       im = grid%im
     208       24192 :       jm = grid%jm
     209       24192 :       km = grid%km
     210             : 
     211       24192 :       ifirstxy = grid%ifirstxy
     212       24192 :       ilastxy  = grid%ilastxy
     213       24192 :       jfirstxy = grid%jfirstxy
     214       24192 :       jlastxy  = grid%jlastxy
     215             : 
     216       24192 :       iam      = grid%iam
     217       24192 :       myidxy_y = grid%myidxy_y
     218       24192 :       nprxy_x  = grid%nprxy_x
     219       24192 :       itot = ilastxy-ifirstxy+1
     220             : 
     221   122774400 :       xg(ifirstxy:ilastxy,:,jfirstxy:jlastxy) = x(ifirstxy:ilastxy,:,jfirstxy:jlastxy)
     222             : 
     223             : #if defined( SPMD )
     224             : 
     225             :   ! north
     226             :       call mp_send3d( grid%commxy, iam-nprxy_x, iam+nprxy_x, im, km, jm,      &
     227             :                       ifirstxy, ilastxy, 1, km, jfirstxy, jlastxy,           &
     228       24192 :                       ifirstxy, ilastxy, 1, km, jfirstxy, jfirstxy, x )
     229             :       call mp_recv3d( grid%commxy, iam+nprxy_x, im, jm, km,                   &
     230             :                       ifirstxy, ilastxy, 1, km, jlastxy+1, jlastxy+1,        &
     231       24192 :                       ifirstxy, ilastxy, 1, km, jlastxy+1, jlastxy+1, north )
     232             : 
     233             :   ! south
     234             :       call mp_send3d( grid%commxy, iam+nprxy_x, iam-nprxy_x, im, km, jm,      &
     235             :                       ifirstxy, ilastxy, 1, km, jfirstxy, jlastxy,           &
     236       24192 :                       ifirstxy, ilastxy, 1, km, jlastxy,  jlastxy, x )
     237             :       call mp_recv3d( grid%commxy, iam-nprxy_x, im, jm, km,                   &
     238             :                       ifirstxy, ilastxy, 1, km, jfirstxy-1, jfirstxy-1,        &
     239       24192 :                       ifirstxy, ilastxy, 1, km, jfirstxy-1, jfirstxy-1, south )
     240             : 
     241             : #endif
     242             : 
     243       24192 :       if (itot .ne. im) then
     244             : #if defined( SPMD )
     245             : 
     246             :    ! east
     247             : 
     248       24192 :          dest = myidxy_y*nprxy_x + MOD(iam+nprxy_x-1,nprxy_x)
     249       24192 :          src  = myidxy_y*nprxy_x + MOD(iam+1,nprxy_x)
     250             :          call mp_send3d( grid%commxy, dest, src, im, km, jm,                  &
     251             :                          ifirstxy, ilastxy, 1, km, jfirstxy, jlastxy,        &
     252       24192 :                          ifirstxy, ifirstxy, 1, km, jfirstxy, jlastxy, x )
     253             :          call mp_recv3d( grid%commxy, src, im, km, jm,                        &
     254             :                          ilastxy+1, ilastxy+1, 1, km, jfirstxy, jlastxy,     &
     255       24192 :                          ilastxy+1, ilastxy+1, 1, km, jfirstxy, jlastxy, east )
     256             : 
     257             :    ! west
     258             : 
     259       24192 :          dest = myidxy_y*nprxy_x + MOD(iam+1,nprxy_x)
     260       24192 :          src  = myidxy_y*nprxy_x + MOD(iam+nprxy_x-1,nprxy_x)
     261             :          call mp_send3d( grid%commxy, dest, src, im, km, jm,                  &
     262             :                          ifirstxy, ilastxy, 1, km, jfirstxy, jlastxy,          &
     263       24192 :                          ilastxy,  ilastxy, 1, km, jfirstxy, jlastxy, x )
     264             :          call mp_recv3d( grid%commxy, src, im, km, jm,                        &
     265             :                          ifirstxy-1, ifirstxy-1, 1, km, jfirstxy, jlastxy, &
     266       24192 :                          ifirstxy-1, ifirstxy-1, 1, km, jfirstxy, jlastxy, west )
     267             : #endif
     268             : 
     269             :       else
     270             : !$omp parallel do private(j, k)
     271           0 :          do k = 1,km
     272           0 :             do j=jfirstxy,jlastxy
     273           0 :                east(k,j) = x(1, k,j)
     274           0 :                west(k,j) = x(im,k,j)
     275             :             enddo
     276             :          enddo
     277             :       endif
     278             : 
     279       24192 :       if ( jfirstxy == 1 ) then
     280     1278396 :          xg(ifirstxy:ilastxy,:,jfirstxy-1) = xg(ifirstxy:ilastxy,:,jfirstxy)
     281             :       else
     282    39630276 :          xg(ifirstxy:ilastxy,:,jfirstxy-1) = south
     283             :       endif
     284             : 
     285       24192 :       if ( jlastxy == jm ) then
     286     1278396 :          xg(ifirstxy:ilastxy,:,jlastxy+1) = xg(ifirstxy:ilastxy,:,jlastxy)
     287             :       else
     288    39630276 :          xg(ifirstxy:ilastxy,:,jlastxy+1) = north
     289             :       endif
     290             : 
     291     9531648 :       xg(ifirstxy-1,:,jfirstxy:jlastxy) = west
     292     9531648 :       xg( ilastxy+1,:,jfirstxy:jlastxy) = east
     293             : 
     294       24192 :     end subroutine ghost_array
     295             : !=================================================================
     296             : 
     297             :   end module gravity_waves_sources

Generated by: LCOV version 1.14