!
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE ENERGY ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE energy(nx,ny,nz, & 2,13
u,v,w,ptprt,pprt,qv,qc,qr,qi,qs,qh,rhobar, &
x,y,z,zp,hterain, j3, &
rhostr,ustr,vstr,wstr,tem4)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Compute the density-weighted domain average of grid-scale kinetic
! energy, momentum, potential temperature and potential temperature
! variance.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Ming Xue
! 11/13/91.
!
! MODIFICATION HISTORY:
!
! 6/06/92 (M. Xue)
! Added full documentation.
!
! This routine need to be checked for the terrain version.
! 5/6/93, Ming Xue
!
!-----------------------------------------------------------------------
!
! INPUT:
!
! nx Number of grid points in the x-direction (east/west)
! ny Number of grid points in the y-direction (north/south)
! nz Number of grid points in the vertical
!
! u x component of velocity (m/s)
! v y component of velocity (m/s)
! w Vertical component of Cartesian velocity (m/s)
! ptprt Perturbation potential temperature (K)
! pprt Perturbation pressure (Pascal)
! qv Water vapor specific humidity (kg/kg)
! qc Cloud water mixing ratio (kg/kg)
! qr Rainwater mixing ratio (kg/kg)
! qi Cloud ice mixing ratio (kg/kg)
! qs Snow mixing ratio (kg/kg)
! qh Hail mixing ratio (kg/kg)
!
! rhobar Base state density (kg/m**3)
!
! x x coordinate of grid points in physical/comp. space (m)
! y y coordinate of grid points in physical/comp. space (m)
! z z coordinate of grid points in computational space (m)
! zp Vertical coordinate of grid points in physical space (m)
! hterain Terrain height (m)
!
! j3 Coordinate transformation Jacobian d(zp)/dz
!
! OUTPUT:
!
! None.
!
! WORK ARRAY:
!
! rhostr j3 times base state density rhobar, a work array.
! ustr rhobar*u, work array.
! vstr rhobar*v, work array.
! wstr rhobar*w, work array.
! tem4 Temporary work array.
!
!-----------------------------------------------------------------------
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INCLUDE 'timelvls.inc'
INTEGER :: nx,ny,nz ! Number of grid points in 3 directions
REAL :: u (nx,ny,nz,nt) ! Total u-velocity (m/s)
REAL :: v (nx,ny,nz,nt) ! Total v-velocity (m/s)
REAL :: w (nx,ny,nz,nt) ! Total w-velocity (m/s)
REAL :: ptprt (nx,ny,nz,nt) ! Perturbation potential temperature (K)
REAL :: pprt (nx,ny,nz,nt) ! Perturbation pressure (Pascal)
REAL :: qv (nx,ny,nz,nt) ! Water vapor specific humidity (kg/kg)
REAL :: qc (nx,ny,nz,nt) ! Cloud water mixing ratio (kg/kg)
REAL :: qr (nx,ny,nz,nt) ! Rain water mixing ratio (kg/kg)
REAL :: qi (nx,ny,nz,nt) ! Cloud ice mixing ratio (kg/kg)
REAL :: qs (nx,ny,nz,nt) ! Snow mixing ratio (kg/kg)
REAL :: qh (nx,ny,nz,nt) ! Hail mixing ratio (kg/kg)
REAL :: rhobar(nx,ny,nz) ! Base state air density (kg/m**3)
REAL :: x (nx) ! The x-coord. of the physical and
! computational grid. Defined at u-point.
REAL :: y (ny) ! The y-coord. of the physical and
! computational grid. Defined at v-point.
REAL :: z (nz) ! The z-coord. of the computational grid.
! Defined at w-point on the staggered grid.
REAL :: zp (nx,ny,nz) ! The physical height coordinate defined at
! w-point of the staggered grid.
REAL :: hterain(nx,ny) ! Terrain height.
REAL :: j3 (nx,ny,nz) ! Coordinate transformation Jacobian defined
! as d( zp )/d( z )
REAL :: rhostr(nx,ny,nz) ! Work array
REAL :: ustr (nx,ny,nz) ! rhostr*u, work array
REAL :: vstr (nx,ny,nz) ! rhostr*v, work array
REAL :: wstr (nx,ny,nz) ! rhostr*w, work array
REAL :: tem4 (nx,ny,nz) ! Temporary work array
!
!-----------------------------------------------------------------------
!
! Include files:
!
!-----------------------------------------------------------------------
!
INCLUDE 'phycst.inc'
INCLUDE 'globcst.inc'
INCLUDE 'mp.inc' ! Message passing parameters.
!
!-----------------------------------------------------------------------
!
! Misc. local variables:
!
!-----------------------------------------------------------------------
!
INTEGER :: istat
INTEGER :: tlevel ! Time level at which data are printed.
INTEGER :: i,j,k
CHARACTER (LEN=80 ) :: engfn ! File name of the energy statistics
! output
INTEGER :: lengfn ! String length of the file name
REAL :: tmass ! Total mass of the air in model domain (kg)
REAL :: keu ! Contribution of u to the
! total kinetic energy
REAL :: kev ! Contribution of v to the
! total kinetic energy
REAL :: kew ! Contribution of w to the
! total kinetic energy
REAL :: ke ! Domain average kinetic energy per
! unit mass (m/s)**2
REAL :: ptvari ! Domain average variance of ptprt
! per unit mass (K**2)
REAL :: momntu ! Domain average x-component of momentum
! per unit mass (m/s)
REAL :: momntv ! Domain average y-component of momentum
! per unit mass (m/s)
REAL :: momntw ! Domain average z-component of momentum
! per unit mass (m/s)
REAL :: ptavg ! Domain average potential temperature
! perturbation (K)
REAL :: dxdz05,dydz05,dxdy05
INTEGER :: ncalls
SAVE ncalls
DATA ncalls /0/
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
! Dump restart data files every nrstout number of time steps.
!
!-----------------------------------------------------------------------
!
tlevel=tpresent
!
!-----------------------------------------------------------------------
!
! Calculate ustr=rhostr*u, vstr=rhostr*v, wstr=rhostr*w
!
!-----------------------------------------------------------------------
!
CALL aamult
(rhobar,j3,nx,ny,nz,1,nx-1,1,ny-1,1,nz-1, rhostr)
CALL rhouvw
(nx,ny,nz,rhostr, ustr, vstr, wstr )
DO k=1,nz-1
DO j=1,ny-1
DO i=1,nx
ustr(i,j,k)=u(i,j,k,tlevel)*ustr(i,j,k)
END DO
END DO
END DO
DO k=1,nz-1
DO j=1,ny
DO i=1,nx-1
vstr(i,j,k)=v(i,j,k,tlevel)*vstr(i,j,k)
END DO
END DO
END DO
DO k=1,nz
DO j=1,ny-1
DO i=1,nx-1
wstr(i,j,k)=w(i,j,k,tlevel)*wstr(i,j,k)
END DO
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Calculate the total mass of air inside the physical boundaries
! based on the base state air density.
!
!-----------------------------------------------------------------------
!
tmass = 0.0
DO k=2,nz-2
DO j=2,ny-2
DO i=2,nx-2
tmass = tmass + rhostr(i,j,k) &
*(x(i+1)-x(i))*(y(j+1)-y(j))*(z(k+1)-z(k))
END DO
END DO
END DO
IF (mp_opt > 0) THEN
CALL mptotal
(tmass)
END IF
!
!-----------------------------------------------------------------------
!
! Determine the contribution of u to the total kinetic energy:
!
!-----------------------------------------------------------------------
!
keu = 0.0
DO k=2,nz-2
DO j=2,ny-2
dydz05 = (y(j+1)-y(j))*(z(k+1)-z(k))*0.5
keu = keu + 0.5*ustr( 2, j,k)*u( 2, j,k,tlevel) &
*dydz05*(x(3)-x(1))
keu = keu + 0.5*ustr(nx-1,j,k)*u(nx-1,j,k,tlevel) &
*dydz05*(x(nx)-x(nx-2))
DO i=3,nx-2
keu = keu + ustr(i,j,k)*u(i,j,k,tlevel) &
*dydz05*(x(i+1)-x(i-1))
END DO
END DO
END DO
IF (mp_opt > 0) THEN
CALL mptotal
(keu)
END IF
!
!-----------------------------------------------------------------------
!
! Determine the contribution of v to the total kinetic energy:
!
!-----------------------------------------------------------------------
!
kev = 0.0
DO k=2,nz-2
DO i=2,nx-2
dxdz05 = (x(i+1)-x(i))*(z(k+1)-z(k))*0.5
kev = kev + 0.5*vstr(i, 2, k)*v(i, 2, k,tlevel) &
*dxdz05*(y(3)-y(1))
kev = kev + 0.5*vstr(i,ny-1,k)*v(i,ny-1,k,tlevel) &
*dxdz05*(y(ny)-y(ny-2))
DO j=3,ny-2
kev = kev + vstr(i,j,k)*v(i,j,k,tlevel) &
*dxdz05*(y(j+1)-y(j-1))
END DO
END DO
END DO
IF (mp_opt > 0) THEN
CALL mptotal
(kev)
END IF
!
!-----------------------------------------------------------------------
!
! Determine the contribution of w to the total kinetic energy:
!
!-----------------------------------------------------------------------
!
kew = 0.0
DO i=2,nx-2
DO j=2,ny-2
dxdy05 = (x(i+1)-x(i))*(y(j+1)-y(j))*0.5
kew = kew + 0.5*wstr(i,j, 2 )*w(i,j, 2 ,tlevel) &
*dxdy05*(z(3)-z(1))
kew = kew + 0.5*wstr(i,j,nz-1)*w(i,j,nz-1,tlevel) &
*dxdy05*(z(nz)-z(nz-2))
DO k=3,nz-2
kew = kew + wstr(i,j,k)*w(i,j,k,tlevel) &
*dxdy05*(z(k+1)-z(k-1))
END DO
END DO
END DO
IF (mp_opt > 0) THEN
CALL mptotal
(kew)
END IF
!
!-----------------------------------------------------------------------
!
! The domain average kinetic energy per unit mass:
!
!-----------------------------------------------------------------------
!
ke = 0.5*(keu+kev+kew)/tmass
!
!-----------------------------------------------------------------------
!
! The domain average potential temperature variance:
!
!-----------------------------------------------------------------------
!
ptvari = 0.0
DO k=2,nz-2
DO j=2,ny-2
DO i=2,nx-2
ptvari = ptvari + rhostr(i,j,k)*ptprt(i,j,k,tlevel)**2 &
*(x(i+1)-x(i))*(y(j+1)-y(j))*(z(k+1)-z(k))
END DO
END DO
END DO
IF (mp_opt > 0) THEN
CALL mptotal
(ptvari)
END IF
ptvari = ptvari/tmass
!
!-----------------------------------------------------------------------
!
! Calculate the domain average momentum in the x direction.
!
!-----------------------------------------------------------------------
!
momntu = 0.0
DO k=2,nz-2
DO j=2,ny-2
dydz05 = (y(j+1)-y(j))*(z(k+1)-z(k))*0.5
momntu = momntu + 0.5*ustr( 2, j,k)*dydz05*(x(3)-x(1))
momntu = momntu + 0.5*ustr(nx-1,j,k)*dydz05*(x(nx)-x(nx-2))
DO i=3,nx-2
momntu = momntu + ustr(i,j,k)*dydz05*(x(i+1)-x(i-1))
END DO
END DO
END DO
IF (mp_opt > 0) THEN
CALL mptotal
(momntu)
END IF
momntu = momntu/tmass
!
!-----------------------------------------------------------------------
!
! Calculate the domain average momentum in the y direction.
!
!-----------------------------------------------------------------------
!
momntv = 0.0
DO k=2,nz-2
DO i=2,nx-2
dxdz05 = (x(i+1)-x(i))*(z(k+1)-z(k))*0.5
momntv = momntv + 0.5*vstr(i, 2, k)*dxdz05*(y(3)-y(1))
momntv = momntv + 0.5*vstr(i,ny-1,k)*dxdz05*(y(ny)-y(ny-2))
DO j=3,ny-2
momntv = momntv + vstr(i,j,k)*dxdz05*(y(j+1)-y(j-1))
END DO
END DO
END DO
IF (mp_opt > 0) THEN
CALL mptotal
(momntv)
END IF
momntv = momntv/tmass
!
!-----------------------------------------------------------------------
!
! Calculate the domain average momentum in the z direction.
!
!-----------------------------------------------------------------------
!
momntw = 0.0
DO i=2,nx-2
DO j=2,ny-2
dxdy05 = (x(i+1)-x(i))*(y(j+1)-y(j))*0.5
momntw = momntw + 0.5*wstr(i,j, 2 )*dxdy05*(z(3)-z(1))
momntw = momntw + 0.5*wstr(i,j,nz-1)*dxdy05*(z(nz)-z(nz-2))
DO k=3,nz-2
momntw = momntw + wstr(i,j,k)*dxdy05*(z(k+1)-z(k-1))
END DO
END DO
END DO
IF (mp_opt > 0) THEN
CALL mptotal
(momntw)
END IF
momntw = momntw/tmass
!
!-----------------------------------------------------------------------
!
! Calculate the mass-weighted domain average perturbation potential
! temperature (K)
!
!-----------------------------------------------------------------------
!
ptavg = 0.0
DO k=2,nz-2
DO j=2,ny-2
DO i=2,nx-2
ptavg = ptavg + rhostr(i,j,k)*ptprt(i,j,k,tlevel) &
*(x(i+1)-x(i))*(y(j+1)-y(j))*(z(k+1)-z(k))
END DO
END DO
END DO
IF (mp_opt > 0) THEN
CALL mptotal
(ptavg)
END IF
ptavg = ptavg/tmass
!
!-----------------------------------------------------------------------
!
! Write the results to a file
!
!-----------------------------------------------------------------------
!
IF (myproc == 0) THEN
IF(ncalls == 0) THEN
IF( dirname /= ' ' ) THEN
engfn = dirname(1:ldirnam)//'/'//runname(1:lfnkey)//'.eng'
lengfn = 6 + lfnkey + ldirnam + 1
ELSE
engfn = runname(1:lfnkey)//'.eng'
lengfn = 6 + lfnkey
END IF
CALL getunit
( ncheng )
OPEN(ncheng,FORM='formatted',STATUS='unknown', &
FILE=engfn(1:lengfn),IOSTAT=istat)
IF( istat /= 0) THEN
WRITE(6,'(/a,i2)') &
' Error occured when opening file '//runname(1:lfnkey) &
//'.eng'// &
' using FORTRAN unit ',ncheng
CALL arpsstop
('arpsstop called from energy',1)
END IF
WRITE(ncheng,'(a)') ''''//runname//''''
WRITE(ncheng,'(t4,a,t15,a,t30,a,t45,a,t60,a,t75,a,t90,a)') &
'''TIME',' KE',' U-MOMENTUM',' V-MOMENTUM', &
' w-momentum',' ptvari',' ptavg'''
END IF
WRITE(ncheng,'(f9.3,6f15.7)') &
curtim,ke,momntu,momntv,momntw,ptvari,ptavg
END IF
ncalls = 1
RETURN
END SUBROUTINE energy