module geopotential 4,3 !--------------------------------------------------------------------------------- ! Compute geopotential from temperature or ! compute geopotential and temperature from dry static energy. ! ! The hydrostatic matrix elements must be consistent with the dynamics algorithm. ! The diagonal element is the itegration weight from interface k+1 to midpoint k. ! The offdiagonal element is the weight between interfaces. ! ! Author: B.Boville, Feb 2001 from earlier code by Boville and S.J. Lin !--------------------------------------------------------------------------------- use shr_kind_mod, only: r8 => shr_kind_r8 use ppgrid, only: pcols, pver, pverp use dycore, only: dycore_is implicit none private save public geopotential_dse public geopotential_t contains !=============================================================================== subroutine geopotential_dse( & 2,1 piln , pmln , pint , pmid , pdel , rpdel , & dse , q , phis , rair , gravit , cpair , & zvir , t , zi , zm , ncol ) !----------------------------------------------------------------------- ! ! Purpose: ! Compute the temperature and geopotential height (above the surface) at the ! midpoints and interfaces from the input dry static energy and pressures. ! !----------------------------------------------------------------------- !------------------------------Arguments-------------------------------- ! ! Input arguments integer, intent(in) :: ncol ! Number of longitudes real(r8), intent(in) :: piln (pcols,pverp) ! Log interface pressures real(r8), intent(in) :: pmln (pcols,pver) ! Log midpoint pressures real(r8), intent(in) :: pint (pcols,pverp) ! Interface pressures real(r8), intent(in) :: pmid (pcols,pver) ! Midpoint pressures real(r8), intent(in) :: pdel (pcols,pver) ! layer thickness real(r8), intent(in) :: rpdel(pcols,pver) ! inverse of layer thickness real(r8), intent(in) :: dse (pcols,pver) ! dry static energy real(r8), intent(in) :: q (pcols,pver) ! specific humidity real(r8), intent(in) :: phis (pcols) ! surface geopotential real(r8), intent(in) :: rair ! Gas constant for dry air real(r8), intent(in) :: gravit ! Acceleration of gravity real(r8), intent(in) :: cpair ! specific heat at constant p for dry air real(r8), intent(in) :: zvir ! rh2o/rair - 1 ! Output arguments real(r8), intent(out) :: t(pcols,pver) ! temperature real(r8), intent(out) :: zi(pcols,pverp) ! Height above surface at interfaces real(r8), intent(out) :: zm(pcols,pver) ! Geopotential height at mid level ! !---------------------------Local variables----------------------------- ! logical :: fvdyn ! finite volume dynamics integer :: i,k ! Lon, level, level indices real(r8) :: hkk(pcols) ! diagonal element of hydrostatic matrix real(r8) :: hkl(pcols) ! off-diagonal element real(r8) :: rog ! Rair / gravit real(r8) :: tv ! virtual temperature real(r8) :: tvfac ! Tv/T ! !----------------------------------------------------------------------- rog = rair/gravit ! Set dynamics flag fvdyn = dycore_is ('LR') ! The surface height is zero by definition. do i = 1,ncol zi(i,pverp) = 0.0_r8 end do ! Compute the virtual temperature, zi, zm from bottom up ! Note, zi(i,k) is the interface above zm(i,k) do k = pver, 1, -1 ! First set hydrostatic elements consistent with dynamics if (fvdyn) then do i = 1,ncol hkl(i) = piln(i,k+1) - piln(i,k) hkk(i) = 1._r8 - pint(i,k) * hkl(i) * rpdel(i,k) end do else do i = 1,ncol hkl(i) = pdel(i,k) / pmid(i,k) hkk(i) = 0.5_r8 * hkl(i) end do end if ! Now compute tv, t, zm, zi do i = 1,ncol tvfac = 1._r8 + zvir * q(i,k) tv = (dse(i,k) - phis(i) - gravit*zi(i,k+1)) / ((cpair / tvfac) + rair*hkk(i)) t (i,k) = tv / tvfac zm(i,k) = zi(i,k+1) + rog * tv * hkk(i) zi(i,k) = zi(i,k+1) + rog * tv * hkl(i) end do end do return end subroutine geopotential_dse !=============================================================================== subroutine geopotential_t( & 1,1 piln , pmln , pint , pmid , pdel , rpdel , & t , q , rair , gravit , zvir , & zi , zm , ncol ) !----------------------------------------------------------------------- ! ! Purpose: ! Compute the geopotential height (above the surface) at the midpoints and ! interfaces using the input temperatures and pressures. ! !----------------------------------------------------------------------- !------------------------------Arguments-------------------------------- ! ! Input arguments ! integer, intent(in) :: ncol ! Number of longitudes real(r8), intent(in) :: piln (pcols,pverp) ! Log interface pressures real(r8), intent(in) :: pmln (pcols,pver) ! Log midpoint pressures real(r8), intent(in) :: pint (pcols,pverp) ! Interface pressures real(r8), intent(in) :: pmid (pcols,pver) ! Midpoint pressures real(r8), intent(in) :: pdel (pcols,pver) ! layer thickness real(r8), intent(in) :: rpdel(pcols,pver) ! inverse of layer thickness real(r8), intent(in) :: t (pcols,pver) ! temperature real(r8), intent(in) :: q (pcols,pver) ! specific humidity real(r8), intent(in) :: rair ! Gas constant for dry air real(r8), intent(in) :: gravit ! Acceleration of gravity real(r8), intent(in) :: zvir ! rh2o/rair - 1 ! Output arguments real(r8), intent(out) :: zi(pcols,pverp) ! Height above surface at interfaces real(r8), intent(out) :: zm(pcols,pver) ! Geopotential height at mid level ! !---------------------------Local variables----------------------------- ! logical :: fvdyn ! finite volume dynamics integer :: i,k ! Lon, level indices real(r8) :: hkk(pcols) ! diagonal element of hydrostatic matrix real(r8) :: hkl(pcols) ! off-diagonal element real(r8) :: rog ! Rair / gravit real(r8) :: tv ! virtual temperature real(r8) :: tvfac ! Tv/T ! !----------------------------------------------------------------------- ! rog = rair/gravit ! Set dynamics flag fvdyn = dycore_is ('LR') ! The surface height is zero by definition. do i = 1,ncol zi(i,pverp) = 0.0_r8 end do ! Compute zi, zm from bottom up. ! Note, zi(i,k) is the interface above zm(i,k) do k = pver, 1, -1 ! First set hydrostatic elements consistent with dynamics if (fvdyn) then do i = 1,ncol hkl(i) = piln(i,k+1) - piln(i,k) hkk(i) = 1._r8 - pint(i,k) * hkl(i) * rpdel(i,k) end do else do i = 1,ncol hkl(i) = pdel(i,k) / pmid(i,k) hkk(i) = 0.5_r8 * hkl(i) end do end if ! Now compute tv, zm, zi do i = 1,ncol tvfac = 1._r8 + zvir * q(i,k) tv = t(i,k) * tvfac zm(i,k) = zi(i,k+1) + rog * tv * hkk(i) zi(i,k) = zi(i,k+1) + rog * tv * hkl(i) end do end do return end subroutine geopotential_t end module geopotential