!
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE RADTRNS ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE radtrns(nx,ny,nz,rbufsz, & 1,24
ptprt,pprt,qv,qc,qr,qi,qs,qh, &
ptbar,pbar,ppi, rhostr, tsfc, &
x,y,z,zp, j3inv, &
radfrc, radsw,rnflx, cosss, &
rsirbm,rsirdf,rsuvbm,rsuvdf, cosz, &
fdirir,fdifir,fdirpar,fdifpar, st4, &
plinv,tinv,qvinv,o3a,ccld, &
flxir,flcir,flxuv,flcuv,dfdts, &
tauir,taual, tauswi,tauswl,reffi,reffl, &
radbuf)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! This subroutine is to compute the atmospheric radiation forcing
!
!-----------------------------------------------------------------------
!
! AUTHOR: Yuhe Liu
! 03/11/1996
!
! MODIFICATION HISTORY:
!
! 04/09/1997 (Yuhe Liu)
! Removed dimension size check statement. For normal ARPS run, the
! dimension size check is now done in the main driver, arps##. For
! nested runs, no need to check the dimension size because the
! working array is allocated automatically from existing space.
!
! Added call of subroutine SETRADWRK to set the indeces of working
! arrays in the radiation buffer. Those indeces are passed by
! common blocks in radcst.inc.
!
! 10/11/1998 (Keith Brewster)
! Added option for using RH in cloud optical depth calculation.
!
! 10/30/1998 (Keith Brewster)
! Added calculation of aerosol density.
!
! 11/18/98 (Keith Brewster)
! Changed pibar to ppi (full pi).
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: nx,ny,nz
INTEGER :: rbufsz
!
!-----------------------------------------------------------------------
!
! Define ARPS variables
!
!-----------------------------------------------------------------------
!
REAL :: x(nx)
REAL :: y(ny)
REAL :: z(nz)
REAL :: zp(nx,ny,nz)
REAL :: ptprt (nx,ny,nz)
REAL :: pprt (nx,ny,nz)
REAL :: qv (nx,ny,nz)
REAL :: qc (nx,ny,nz)
REAL :: qr (nx,ny,nz)
REAL :: qi (nx,ny,nz)
REAL :: qs (nx,ny,nz)
REAL :: qh (nx,ny,nz)
REAL :: ptbar (nx,ny,nz)
REAL :: pbar (nx,ny,nz)
REAL :: ppi (nx,ny,nz)
REAL :: rhostr(nx,ny,nz)
REAL :: j3inv (nx,ny,nz) ! Inverse of j3
REAL :: tsfc (nx,ny) ! Surface temperature (K)
REAL :: radfrc(nx,ny,nz) ! Radiation forcing (K/s)
REAL :: radsw (nx,ny) ! Solar radiation reaching the surface
REAL :: rnflx (nx,ny) ! Net upward radiation flux
REAL :: cosz (nx,ny) ! Cosine of zenith
REAL :: cosss (nx,ny) ! Cosine of angle between sun light and
! surface terrain slope
!
!-----------------------------------------------------------------------
!
! Define 2-D variables for radiation calculation.
!
!-----------------------------------------------------------------------
!
REAL :: rsirbm(nx,ny) ! Solar IR surface albedo for beam radiation
REAL :: rsirdf(nx,ny) ! Solar IR surface albedo for diffuse radiation
REAL :: rsuvbm(nx,ny) ! Solar UV surface albedo for beam radiation
REAL :: rsuvdf(nx,ny) ! Solar UV surface albedo for diffuse radiation
REAL :: fdirir (nx,ny) ! all-sky direct downward IR flux
! (0.7-10 micron) at the surface
REAL :: fdifir (nx,ny) ! all-sky diffuse downward IR flux
! at the surface
REAL :: fdirpar(nx,ny) ! all-sky direct downward par flux
! (0.4-0.7 micron) at the surface
REAL :: fdifpar(nx,ny) ! all-sky diffuse downward par flux
! at the surface
REAL :: st4(nx,ny) ! Emission by the surface
!
!-----------------------------------------------------------------------
!
! Arrays which have the vertical coordinate inversed, that
! is, k=1 is for top while k=nz is at the surface.
!
!-----------------------------------------------------------------------
!
REAL :: plinv (nx,ny,nz) ! Pressure in mb at scalar points
REAL :: tinv (nx,ny,nz) ! Temperature
REAL :: qvinv (nx,ny,nz) ! Water vapor mixing ratio (g/g)
REAL :: o3a (nx,ny,nz) ! Ozone (o3) mixing ratio (g/g)
REAL :: ccld (nx,ny,nz) ! Cloud coverage (fraction)
REAL :: flxir (nx,ny,nz) ! all-sky net downward flux
REAL :: flcir (nx,ny,nz) ! clear-sky net downward flux
REAL :: flxuv (nx,ny,nz) ! all-sky solar flux (downward minus upward)
REAL :: flcuv (nx,ny,nz) ! clear-sky solar flux (downward minus upward)
REAL :: dfdts (nx,ny,nz) ! Sensitivity of net downward flux to surface
! temperature
REAL :: tauir (nx,ny,nz) ! Cloud optical depth for LW IR
REAL :: taual (nx,ny,nz) ! Aerosol optical thickness
REAL :: tauswi(nx,ny,nz) ! Cloud optical depth for solar IR for
! ice particles
REAL :: tauswl(nx,ny,nz) ! Cloud optical depth for solar IR for
! liquid particles
REAL :: reffi (nx,ny,nz) ! Effective cloud-particle size for
! ice particles
REAL :: reffl (nx,ny,nz) ! Effective cloud-particle size for
! liquid particles
!
!-----------------------------------------------------------------------
!
! Include files:
!
!-----------------------------------------------------------------------
!
INCLUDE 'globcst.inc'
INCLUDE 'phycst.inc'
INCLUDE 'radcst.inc'
INCLUDE 'bndry.inc' ! add by Yunheng
INCLUDE 'mp.inc'
!
!-----------------------------------------------------------------------
!
! Include file radcst.inc which contains the definition of dimension
! sizes for 2-d and 3-d temporary arrays represented by a buffer,
! radbuf. When radopt is NOT set to 2, the dimensions and buffer
! sizes can be 1. Otherwise, the dimension sizes should be the same
! as nx, ny, and nz, and the buffer size should be larger than the
! total size of 27 2-d arrays and 44 3-d arrays.
!
! integer n2d_rad ! number of 2-d arrays in the buffer
! integer n3d_rad ! number of 3-d arrays in the buffer
!
! integer rbufsz ! nx*ny*(n2d_rad+n3d_rad*nz)
! real radbuf( rbufsz )
!
! The 2-d arrays should be always at the beginning of radbuf and
! the 3-d arrays then following.
!
!-----------------------------------------------------------------------
!
REAL :: radbuf( rbufsz )
!
!-----------------------------------------------------------------------
!
! Local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: nxy, nxyz
INTEGER :: i,j,k
INTEGER :: im,jm,km, ij, ijm
INTEGER :: istgr, jstgr
INTEGER :: nxodd, nyodd, jeven, jodd
INTEGER :: m, n
INTEGER :: night ! Flag for night time
REAL :: tqe, dp, coolrate,heatrate
REAL :: pk,psfc,tk,qvsat,rh,hgtagl,ccld1,ccld2,aden,psqc,aersum
LOGICAL :: high
INTEGER :: rh2cldopt
REAL :: rhcldwgt,qcwgt
PARAMETER (rh2cldopt=0,rhcldwgt=0.667)
INTEGER :: mptag1, mptag2, mptag3 ! add by Yunheng
INTEGER :: mptag4, mptag5, mptag6 ! add by Yunheng
REAL :: tem1(nx, ny, nz), tem2(nx, ny) ! add by Yunheng
!
!-----------------------------------------------------------------------
!
! Functions
!
!-----------------------------------------------------------------------
!
REAL :: f_qvsat,rh_to_cldcv,aeroden
!fpp$ expand (f_qvsat)
!dir$ inline always f_qvsat
!*$* inline routine (f_qvsat)
!
!-----------------------------------------------------------------------
!
! Define additional layer to the top of model atmosphere
!
!-----------------------------------------------------------------------
!
REAL :: padd ! Additional pressure level (mb) to TOA
REAL :: tadd ! Temperature for additional layer to TOA
PARAMETER (padd = 1.0)
PARAMETER (tadd =223.0)
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
IF ( rlwopt == 0 ) THEN
high = .false.
ELSE
high = .true.
END IF
CALL setradwrk
(nx,ny,nz)
nxy = nx*ny
nxyz = nxy*nz
qcwgt=1.-rhcldwgt
IF ( (pbar(1,1,nz-1)*0.01) <= padd ) THEN
WRITE (6,'(a/a)') &
'The pressure at the top of atmosphere was too low to add ', &
'additional levels. Check the sounding profile.', &
'Program stopped in RADTRNS.'
CALL arpsstop
('arpsstop stopped RADTRNS pressure to low at the top ',1)
END IF
DO j=1,ny-1
DO i=1,nx-1
DO k=1,nz-1
o3a(i,j,k)=qc(i,j,k)
END DO
END DO
END DO
!
!-----------------------------------------------------------------------
!
! In the staggering case, only those points of (i,j) = (even,even)
! and (odd,odd) will be calculated. Do defragment to move the points
! to the left half domain, i=1,nx/2 and j=1,ny-1
!
!-----------------------------------------------------------------------
!
nyodd = MOD(ny,2)
nxodd = MOD(nx,2)
IF ( radstgr == 0 ) THEN
m = nx-1
n = ny-1
! WARNING: this loop is repeated for radstgr=1, changes made here must
! also be made there as well.
DO km=3,nz-1
k = nz+1-km
DO j=1,n
DO i=1,m
pk = pbar(i,j,k)+pprt(i,j,k)
plinv(i,j,km) = 0.005*((pbar(i,j,k ) + pprt(i,j,k )) &
+(pbar(i,j,k+1) + pprt(i,j,k+1)))
tk = (ptbar(i,j,k)+ptprt(i,j,k))*ppi(i,j,k)
tinv (i,j,km) = MAX(tk, 190.)
qvinv(i,j,km) = MAX(qv(i,j,k), 1.0E-6)
tqe = qc(i,j,k)+qr(i,j,k)+qi(i,j,k)+qs(i,j,k)+qh(i,j,k)
tqe = MAX(1.0E-20, tqe)
IF( rh2cldopt > 0 ) THEN
qvsat=MAX(f_qvsat
(pk,tk),1.0E-20)
rh = MIN(1.0,(qv(i,j,k)/qvsat))
hgtagl = (0.5*(zp(i,j,k)+zp(i,j,k+1)))-zp(i,j,2)
ccld1 = rh_to_cldcv(rh,hgtagl)
ccld2 = MIN(1.0, MAX(0.0, 0.25*ALOG10(tqe)+1.5))
ccld1 = MIN(1.0, MAX(ccld2, ccld1))
ccld (i,j,km) = rhcldwgt*ccld1 + qcwgt*ccld2
! borrow o3a to store psuedo-cloud
psqc= 0.10*ccld1*qvsat
o3a(i,j,k) = MAX(qc(i,j,k),psqc)
ELSE
ccld(i,j,km) = MIN(1.0, MAX(0.0, 0.25*ALOG10(tqe)+1.5))
! borrow o3a to store psuedo-cloud
o3a(i,j,k) = qc(i,j,k)
END IF
psfc = 0.5* (pbar(i,j,1)+pprt(i,j,1) + &
pbar(i,j,2)+pprt(i,j,2) )
aden=2.0*aeroden(pk,psfc)
taual(i,j,km)=aden*0.5*((pbar(i,j,k-1)+pprt(i,j,k-1)) &
-(pbar(i,j,k+1)+pprt(i,j,k+1)))
END DO
END DO
END DO
! WARNING: this loop is repeated for radstgr=1, changes made here must
! also be made there as well.
DO j=1,n
DO i=1,m
ij = nx*(j-1) + i
radbuf(ij) = tsfc(i,j)
plinv(i,j,1) = padd
tinv (i,j,1) = tadd
qvinv(i,j,1) = 1.0E-6
ccld (i,j,1) = 0.0
taual(i,j,1) = 0.0
plinv(i,j,2) = 0.5*(plinv(i,j,1)+plinv(i,j,3))
tinv (i,j,2) = MAX(0.5*(tinv(i,j,1)+tinv(i,j,3)), 190.0)
qvinv(i,j,2) = MAX(qv(i,j,nz-1), 1.0E-6)
ccld (i,j,2) = 0.0
taual(i,j,2) = 0.0
plinv(i,j,nz) = 0.005*((pbar(i,j,1) + pprt(i,j,1)) &
+(pbar(i,j,2) + pprt(i,j,2)))
END DO
END DO
ELSE IF ( radstgr == 1 ) THEN
istgr = 1
jstgr = 2
m = nx-1
n = ny/2
! WARNING: this loop is repeated above for radstgr=0, changes made here
! must also be made there as well.
DO km=3,nz-1
k = nz+1-km
DO j=1,ny-1
jodd = istgr*MOD(j,2)
DO i=jstgr-jodd, nx-1, jstgr
im = i
jm = j/jstgr + istgr*MOD(i,2)
pk = pbar(i,j,k)+pprt(i,j,k)
plinv(im,jm,km) = 0.005*((pbar(i,j,k ) + pprt(i,j,k )) &
+(pbar(i,j,k+1) + pprt(i,j,k+1)))
tk = (ptbar(i,j,k)+ptprt(i,j,k))*ppi(i,j,k)
tinv (im,jm,km) = MAX(tk, 190.)
qvinv(im,jm,km) = MAX(qv(i,j,k), 1.0E-6)
tqe = qc(i,j,k)+qr(i,j,k)+qi(i,j,k)+qs(i,j,k)+qh(i,j,k)
tqe = MAX(1.0E-20, tqe)
IF( rh2cldopt > 0 ) THEN
qvsat=MAX(f_qvsat
(pk,tk),1.0E-20)
rh = MIN(1.0,(qv(i,j,k)/qvsat))
hgtagl = (0.5*(zp(i,j,k)+zp(i,j,k+1)))-zp(i,j,2)
ccld1 = rh_to_cldcv(rh,hgtagl)
ccld2 = MIN(1.0, MAX(0.0, 0.25*ALOG10(tqe)+1.5))
ccld1 = MIN(1.0, MAX(ccld2, ccld1))
ccld (im,jm,km) = rhcldwgt*ccld1 + qcwgt*ccld2
! borrow o3a to store psuedo-cloud
psqc= 0.10*ccld1*qvsat
o3a(i,j,k) = MAX(qc(i,j,k),psqc)
ELSE
ccld (im,jm,km) = MIN(1.0, MAX(0.0, 0.25*ALOG10(tqe)+1.5))
! borrow o3a to store psuedo-cloud
o3a(i,j,k) = qc(i,j,k)
END IF
psfc = 0.5* (pbar(i,j,1)+pprt(i,j,1) + &
pbar(i,j,2)+pprt(i,j,2) )
aden=2.0*aeroden(pk,psfc)
taual(im,jm,km)=aden*0.5*((pbar(i,j,k-1)+pprt(i,j,k-1)) &
-(pbar(i,j,k+1)+pprt(i,j,k+1)))
END DO
END DO
IF ( nyodd == 0 ) THEN
DO im=2,m,2
plinv(im,n,km) = plinv(im,n-1,km)
tinv (im,n,km) = tinv (im,n-1,km)
qvinv(im,n,km) = qvinv(im,n-1,km)
ccld (im,n,km) = ccld (im,n-1,km)
taual(im,n,km) = taual(im,n-1,km)
END DO
END IF
END DO
! WARNING: loops 180 & 190 are repeated above for radstgr=0, changes made
! here must also be made there as well.
DO j=1,ny-1
jodd = istgr*MOD(j,2)
DO i=jstgr-jodd, nx-1, jstgr
im = i
jm = j/jstgr + istgr*MOD(i,2)
ijm = nx*(jm-1) + im
radbuf(ijm) = tsfc(i,j)
cosz (im,jm) = cosz(i,j)
rsirbm(im,jm) = rsirbm(i,j)
rsuvbm(im,jm) = rsuvbm(i,j)
rsirdf(im,jm) = rsirdf(i,j)
rsuvdf(im,jm) = rsuvdf(i,j)
plinv(im,jm,1) = padd
tinv (im,jm,1) = tadd
qvinv(im,jm,1) = 1.0E-6
ccld (im,jm,1) = 0.0
taual(im,jm,1) = 0.0
plinv(im,jm,2) = 0.5*(plinv(im,jm,1)+plinv(im,jm,3))
tinv (im,jm,2) = MAX(0.5*(tinv(im,jm,1)+tinv(im,jm,3)), &
190.0)
qvinv(im,jm,2) = MAX(qv(i,j,nz-1), 1.0E-6)
ccld (im,jm,2) = 0.0
taual(im,jm,2) = 0.0
plinv(im,jm,nz) = 0.005*((pbar(i,j,1) + pprt(i,j,1)) &
+(pbar(i,j,2) + pprt(i,j,2)))
END DO
END DO
IF ( nyodd == 0 ) THEN
DO im=2,m,2
ijm = nx*(n-1) + im
radbuf(ijm) = tsfc(im,n-1)
cosz (im,n) = cosz(im,n-1)
rsirbm(im,n) = rsirbm(im,n-1)
rsuvbm(im,n) = rsuvbm(im,n-1)
rsirdf(im,n) = rsirdf(im,n-1)
rsuvdf(im,n) = rsuvdf(im,n-1)
plinv(im,n,1) = padd
tinv (im,n,1) = tadd
qvinv(im,n,1) = 1.0E-6
ccld (im,n,1) = 0.0
taual(im,n,1) = 0.0
plinv(im,n,2) = plinv(im,n-1,2)
tinv (im,n,2) = tinv (im,n-1,2)
qvinv(im,n,2) = qvinv(im,n-1,2)
ccld (im,n,2) = 0.0
taual(im,n,2) = 0.0
plinv(im,n,nz) = plinv(im,n-1,nz)
END DO
END IF
END IF
DO km=1,nz-1
DO j=1,n
DO i=1,m
dp = plinv(i,j,km+1) - plinv(i,j,km)
IF ( dp <= 0.0 ) THEN
WRITE (6,'(a,i3,a,i3,a,i3,a,i3,a/a,a/a)') &
'ERROR: The pressure gradient between level k = ',nz+1-km, &
' and ',nz-km, ' at i = ',i,' and j = ',j,' was <=0.', &
'Please check the sounding file, ', &
runname(1:lfnkey)//'.sound, or the data sets.', &
'Program stopped in RADTRNS.'
CALL arpsstop
('arpsstop stopped RADTRNS problem with sounding',1)
END IF
END DO
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Notes: The arguments in subroutine CLDOPTD have different vertical
! coordinates orders:
!
! plinv -- 1 for top
! tinv -- 1 for top
!
! qc -- 1 for bottom
! qr -- 1 for bottom
! qi -- 1 for bottom
! qs -- 1 for bottom
! qh -- 1 for bottom
!
! tauir -- 1 for top
! tauswi -- 1 for top
! tauswl -- 1 for top
! reffi -- 1 for top
! reffl -- 1 for top
!
!-----------------------------------------------------------------------
!
! note borrowed o3a to store psuedo-cloud in place of qc.
CALL cldoptd
(nx,ny,m,n,nz, radstgr, &
plinv,tinv,o3a,qr,qi,qs,qh, rhostr,j3inv, &
tauir,tauswi,tauswl,reffi,reffl)
IF ( radstgr == 1 ) THEN
IF ( nyodd == 0 ) THEN
DO km=1,nz-1
DO im=2,m,2
tauir (im,n,km) = tauir (im,n-1,km)
tauswi(im,n,km) = tauswi(im,n-1,km)
tauswl(im,n,km) = tauswl(im,n-1,km)
reffi (im,n,km) = reffi (im,n-1,km)
reffl (im,n,km) = reffl (im,n-1,km)
END DO
END DO
END IF
END IF
!
!-----------------------------------------------------------------------
!
! Fit the ozone concentration by interpolating a standard o3 profile
! to ARPS pressure levels.
!
!-----------------------------------------------------------------------
!
CALL fito3
(nx,ny,m,n, nz-1, plinv,o3a)
!
!-----------------------------------------------------------------------
!
! Calculate the downward longwave IR radiation.
!
! Positions of 2-d arrays in the buffer:
!
! fclr (m,n) -- radbuf(1+ 1*nxy)
! dbs (m,n) -- radbuf(1+ 2*nxy)
! trant(m,n) -- radbuf(1+ 3*nxy)
!
! th2o (m,n,6) -- radbuf(1+ 4*nxy)
! tcon (m,n,3) -- radbuf(1+10*nxy)
! tco2 (m,n,6,2) -- radbuf(1+13*nxy)
!
! Positions of 3-d arrays in the buffer:
!
! pa (m,n,np) -- radbuf(1+25*nxy)
! dt (m,n,np) -- radbuf(1+25*nxy+ 1*nxyz)
! sh2o (m,n,np+1) -- radbuf(1+25*nxy+ 2*nxyz)
! swpre (m,n,np+1) -- radbuf(1+25*nxy+ 3*nxyz)
! swtem (m,n,np+1) -- radbuf(1+25*nxy+ 4*nxyz)
! sco3 (m,n,np+1) -- radbuf(1+25*nxy+ 5*nxyz)
! scopre(m,n,np+1) -- radbuf(1+25*nxy+ 6*nxyz)
! scotem(m,n,np+1) -- radbuf(1+25*nxy+ 7*nxyz)
! dh2o (m,n,np) -- radbuf(1+25*nxy+ 8*nxyz)
! dcont (m,n,np) -- radbuf(1+25*nxy+ 9*nxyz)
! dco2 (m,n,np) -- radbuf(1+25*nxy+10*nxyz)
! do3 (m,n,np) -- radbuf(1+25*nxy+11*nxyz)
! flxu (m,n,np+1) -- radbuf(1+25*nxy+12*nxyz)
! flxd (m,n,np+1) -- radbuf(1+25*nxy+13*nxyz)
! clr (m,n,0:np+1) -- radbuf(1+25*nxy+14*nxyz) ! nz+1
! blayer(m,n,0:np+1) -- radbuf(1+26*nxy+15*nxyz) ! nz+1
!
! h2oexp(m,n,np,6) -- radbuf(1+27*nxy+16*nxyz)
! conexp(m,n,np,3) -- radbuf(1+27*nxy+22*nxyz)
!
! co2exp(m,n,np,6,2) -- radbuf(1+27*nxy+25*nxyz)
!
!-----------------------------------------------------------------------
!
CALL irrad
(nx,ny,m,n,nz-1, &
tauir,ccld, plinv,tinv,qvinv,o3a, co2,radbuf(1), &
high,flxir,flcir,dfdts,st4, &
radbuf(ir2d1),radbuf(ir2d2),radbuf(ir2d3), &
radbuf(ir2d4),radbuf(ir2d5),radbuf(ir2d6), &
radbuf(ir3d1),radbuf(ir3d2),radbuf(ir3d3), &
radbuf(ir3d4),radbuf(ir3d5),radbuf(ir3d6), &
radbuf(ir3d7),radbuf(ir3d8),radbuf(ir3d9), &
radbuf(ir3d10),radbuf(ir3d11),radbuf(ir3d12), &
radbuf(ir3d13),radbuf(ir3d14),radbuf(ir3d15), &
radbuf(ir3d16),radbuf(ir4d1),radbuf(ir4d2), &
radbuf(ir5d1))
!
!-----------------------------------------------------------------------
!
! Calculate solar radiation fluxes.
!
! Output flxuv and flcuv are the fractions to incoming solar flux
! at the top of atmosphere
!
! Positions of 2-d arrays used in subroutine SORAD
!
! sdf (m,n) -- radbuf(1+ 1*nxy )
! sclr (m,n) -- radbuf(1+ 2*nxy)
! csm (m,n) -- radbuf(1+ 3*nxy)
! cc (m,n,3) -- radbuf(1+ 4*nxy)
!
! Positions of 3-d arrays used in subroutine SORAD
!
! tauclb(m,n,np) -- radbuf(1+ 7*nxy )
! tauclf(m,n,np) -- radbuf(1+ 7*nxy+ 1*nxyz)
! dp (m,n,np) -- radbuf(1+ 7*nxy+ 2*nxyz)
! wh (m,n,np) -- radbuf(1+ 7*nxy+ 3*nxyz)
! oh (m,n,np) -- radbuf(1+ 7*nxy+ 4*nxyz)
! scal (m,n,np) -- radbuf(1+ 7*nxy+ 5*nxyz)
! swh (m,n,np+1) -- radbuf(1+ 7*nxy+ 6*nxyz)
! so2 (m,n,np+1) -- radbuf(1+ 7*nxy+ 7*nxyz)
! df (m,n,np+1) -- radbuf(1+ 7*nxy+ 8*nxyz)
!
! Positions of temporary arrays used in subroutine SOLIR, SOLUV, and
! CLDFLX:
!
! tem2d1 (m,n) -- radbuf(1+ 7*nxy+ 9*nxyz)
! tem2d2 (m,n) -- radbuf(1+ 8*nxy+ 9*nxyz)
! tem2d3 (m,n) -- radbuf(1+ 9*nxy+ 9*nxyz)
! tem2d4 (m,n) -- radbuf(1+10*nxy+ 9*nxyz)
! tem2d5 (m,n) -- radbuf(1+11*nxy+ 9*nxyz)
! tem2d6 (m,n) -- radbuf(1+12*nxy+ 9*nxyz)
! tem2d7 (m,n) -- radbuf(1+13*nxy+ 9*nxyz)
! tem2d8 (m,n) -- radbuf(1+14*nxy+ 9*nxyz)
! tem2d9 (m,n) -- radbuf(1+15*nxy+ 9*nxyz)
! tem2d10(m,n) -- radbuf(1+16*nxy+ 9*nxyz)
! tem2d11(m,n) -- radbuf(1+17*nxy+ 9*nxyz)
! tem2d12(m,n) -- radbuf(1+18*nxy+ 9*nxyz)
! tem2d13(m,n) -- radbuf(1+19*nxy+ 9*nxyz)
! tem2d14(m,n) -- radbuf(1+20*nxy+ 9*nxyz)
! tem2d15(m,n) -- radbuf(1+21*nxy+ 9*nxyz)
! tem2d16(m,n) -- radbuf(1+22*nxy+ 9*nxyz)
! tem2d17(m,n) -- radbuf(1+23*nxy+ 9*nxyz)
! tem2d18(m,n) -- radbuf(1+24*nxy+ 9*nxyz)
! tem2d19(m,n) -- radbuf(1+25*nxy+ 9*nxyz)
!
! tem3d1 (m,n,np+1) -- radbuf(1+26*nxy+ 9*nxyz)
! tem3d2 (m,n,np+1) -- radbuf(1+26*nxy+10*nxyz)
! tem3d3 (m,n,np+1) -- radbuf(1+26*nxy+11*nxyz)
! tem3d4 (m,n,np+1) -- radbuf(1+26*nxy+12*nxyz)
! tem3d5 (m,n,np+1) -- radbuf(1+26*nxy+13*nxyz)
!
! tem4d1 (m,n,np+1,2) -- radbuf(1+26*nxy+14*nxyz)
! tem4d2 (m,n,np+1,2) -- radbuf(1+26*nxy+16*nxyz)
! tem4d3 (m,n,np+1,2) -- radbuf(1+26*nxy+18*nxyz)
! tem4d4 (m,n,np+1,2) -- radbuf(1+26*nxy+20*nxyz)
! tem4d5 (m,n,np+1,2) -- radbuf(1+26*nxy+22*nxyz)
!
! tem5d1(m,n,np+1,2,2) -- radbuf(1+26*nxy+24*nxyz)
! tem5d2(m,n,np+1,2,2) -- radbuf(1+26*nxy+28*nxyz)
! tem5d3(m,n,np+1,2,2) -- radbuf(1+26*nxy+32*nxyz)
! tem5d4(m,n,np+1,2,2) -- radbuf(1+26*nxy+36*nxyz)
! tem5d5(m,n,np+1,2,2) -- radbuf(1+26*nxy+40*nxyz)
!
!-----------------------------------------------------------------------
!
night = 1
DO j=1,n
DO i=1,m
IF ( cosz(i,j) > 0.0 ) THEN
night = 0
GO TO 500
END IF
END DO
END DO
500 CONTINUE
! aersum=0.
! DO 505 k=1,nz-1
! aersum=aersum+taual(2,2,k)
! 505 CONTINUE
! write(6,'(a,f10.4))') ' Total aerosol optical depth: ',aersum
IF ( night == 0 ) THEN
CALL sorad
(nx,ny,m,n,nz-1, plinv,tinv,qvinv,o3a,co2, &
tauswi,tauswl,reffi,reffl,ccld,ict,icb, &
taual,rsirbm,rsirdf,rsuvbm,rsuvdf,cosz, &
flxuv,flcuv,fdirir,fdifir,fdirpar,fdifpar, &
radbuf(so2d1),radbuf(so2d2),radbuf(so2d3),radbuf(so2d4), &
radbuf(so3d1),radbuf(so3d2),radbuf(so3d3),radbuf(so3d4), &
radbuf(so3d5),radbuf(so3d6),radbuf(so3d7),radbuf(so3d8), &
radbuf(so3d9),radbuf(so2d5),radbuf(so2d6),radbuf(so2d7), &
radbuf(so2d8),radbuf(so2d9),radbuf(so2d10),radbuf(so2d11), &
radbuf(so2d12),radbuf(so2d13),radbuf(so2d14), &
radbuf(so2d15),radbuf(so2d16),radbuf(so2d17), &
radbuf(so2d18),radbuf(so2d19),radbuf(so2d20), &
radbuf(so2d21),radbuf(so2d22),radbuf(so2d23), &
radbuf(so3d10),radbuf(so3d11),radbuf(so3d12), &
radbuf(so3d13),radbuf(so3d14),radbuf(so4d1), &
radbuf(so4d2),radbuf(so4d3),radbuf(so4d4),radbuf(so4d5), &
radbuf(so5d1), radbuf(so5d2), &
radbuf(so5d3), radbuf(so5d4), radbuf(so5d5))
ELSE
DO k=1,nz-1
DO j=1,n
DO i=1,m
flxuv(i,j,k) = 0.0
END DO
END DO
END DO
DO j=1,n
DO i=1,m
fdirir (i,j) = 0.0
fdifir (i,j) = 0.0
fdirpar(i,j) = 0.0
fdifpar(i,j) = 0.0
END DO
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Added the heating rate of solar radiation to total radiation
! forcing (K/s)
!
! Constant 9.770687e-05 is equal to g/cp in cgs unit, where g = 980
! and cp = 1.003e7.
!
! Outputs from SORAD such as flxuv, flcuv, etc., are fractions of
! solar flux at the top of atmosphere. Therefore we need to multipy
! solar constant and cosine of zenith angle to obtain the solar
! radiation flux.
!
!-----------------------------------------------------------------------
!
IF ( radstgr == 0 ) THEN
DO k=2,nz-2
km=nz+1-k ! inverse vertical coordinates to ARPS grid
DO j=1,ny-1
DO i=1,nx-1
coolrate = 9.770687E-05 & ! = g/cp in cgs unit
* ( flxir(i,j,km+1) - flxir(i,j,km) ) &
/ ( plinv(i,j,km) - plinv(i,j,km+1) )
! coolr (i,j,k) = -coolrate*86400. ! cooling rate, C/day
heatrate = solarc * cosz(i,j) * 9.770687E-05 &
* ( flxuv(i,j,km+1) - flxuv(i,j,km) ) &
/ ( plinv(i,j,km) - plinv(i,j,km+1) )
! heatr (i,j,k) = heatrate*86400.0 ! heating rate, C/day
radfrc(i,j,k) = (coolrate + heatrate)/ppi(i,j,k)
END DO
END DO
END DO
DO j=1,ny-1
DO i=1,nx-1
rnflx(i,j) = solarc * radsw(i,j) * cosss(i,j) & ! radsw = a2dr2
* ( (1.0-rsirbm(i,j)) * fdirir(i,j) &
+ (1.0-rsuvbm(i,j)) * fdirpar(i,j) &
+ (1.0-rsirdf(i,j)) * fdifir(i,j) &
+ (1.0-rsuvdf(i,j)) * fdifpar(i,j) ) &
+ flxir(i,j,nz) ! net downward LW flux at sfc
radsw(i,j) = solarc * radsw(i,j) * cosss(i,j) &
* ( fdirir(i,j) + fdirpar(i,j) &
+ fdifir(i,j) + fdifpar(i,j) )
END DO
END DO
ELSE IF ( radstgr == 1 ) THEN
DO k=2,nz-2
km=nz+1-k ! inverse vertical coordinates to ARPS grid
DO j=1,ny-1
jodd = istgr*MOD(j,2)
DO i=jstgr-jodd, nx-1, jstgr
im = i
jm = j/jstgr + istgr*MOD(i,2)
coolrate = 9.770687E-05 & ! = g/cp in cgs unit
* ( flxir(im,jm,km+1) - flxir(im,jm,km) ) &
/ ( plinv(im,jm,km) - plinv(im,jm,km+1) )
! coolr(i,j,k) = -coolrate*86400. ! cooling rate, C/day
heatrate = solarc * cosz(im,jm) * 9.770687E-05 &
* ( flxuv(im,jm,km+1) - flxuv(im,jm,km) ) &
/ ( plinv(im,jm,km) - plinv(im,jm,km+1) )
! heatr(i,j,k) = heatrate*86400.0 ! heating rate, C/day
radfrc(i,j,k) = (coolrate + heatrate)/ppi(i,j,k)
! total radiation forcing (K/s)
END DO
END DO
IF ( nx-1 > 3 ) THEN
DO j=2,ny-2
jeven = MOD(j+1,2)
DO i=2+jeven,nx-2,2
! coolr (i,j,k) = 0.25
! : * (coolr (i+1,j,k)+coolr (i-1,j,k)
! : +coolr (i,j+1,k)+coolr (i,j-1,k))
! heatr (i,j,k) = 0.25
! : * (heatr (i+1,j,k)+heatr (i-1,j,k)
! : +heatr (i,j+1,k)+heatr (i,j-1,k))
radfrc(i,j,k) = 0.25 &
* (radfrc(i+1,j,k)+radfrc(i-1,j,k) &
+radfrc(i,j+1,k)+radfrc(i,j-1,k))
END DO
END DO
END IF
DO j=2,ny-2,2
! coolr (1,j,k) = 0.25
! : *(coolr(2,j,k)+coolr(2,j,k)
! : +coolr(1,j+1,k)+coolr(1,j-1,k))
! coolr (nx-1,j+nxodd,k) = 0.25
! : *(coolr(nx-2,j+nxodd,k)+coolr(nx-2,j+nxodd,k)
! : +coolr(nx-1,j+nxodd+1,k)+coolr(nx-1,j+nxodd-1,k))
! heatr (1,j,k) = 0.25
! : *(heatr(2,j,k)+heatr(2,j,k)
! : +heatr(1,j+1,k)+heatr(1,j-1,k))
! heatr (nx-1,j+nxodd,k) = 0.25
! : *(heatr(nx-2,j+nxodd,k)+heatr(nx-2,j+nxodd,k)
! : +heatr(nx-1,j+nxodd+1,k)+heatr(nx-1,j+nxodd-1,k))
radfrc(1,j,k) = 0.25 &
*(radfrc(2,j,k)+radfrc(2,j,k) &
+radfrc(1,j+1,k)+radfrc(1,j-1,k))
radfrc(nx-1,j+nxodd,k) = 0.25 &
*(radfrc(nx-2,j+nxodd,k)+radfrc(nx-2,j+nxodd,k) &
+radfrc(nx-1,j+nxodd+1,k)+radfrc(nx-1,j+nxodd-1,k))
END DO
DO i=2,nx-2,2
! coolr (i,1,k) = 0.25
! : *(coolr(i,2,k)+coolr(i,2,k)
! : +coolr(i+1,1,k)+coolr(i-1,1,k))
! coolr (i+nyodd,ny-1,k) = 0.25
! : *(coolr(i+nyodd,ny-2,k)+coolr(i+nyodd,ny-2,k)
! : +coolr(i+nyodd+1,ny-1,k)+coolr(i+nyodd-1,ny-1,k))
! heatr (i,1,k) = 0.25
! : *(heatr(i,2,k)+heatr(i,2,k)
! : +heatr(i+1,1,k)+heatr(i-1,1,k))
! heatr (i+nyodd,ny-1,k) = 0.25
! : *(heatr(i+nyodd,ny-2,k)+heatr(i+nyodd,ny-2,k)
! : +heatr(i+nyodd+1,ny-1,k)+heatr(i+nyodd-1,ny-1,k))
radfrc(i,1,k) = 0.25 &
*(radfrc(i,2,k)+radfrc(i,2,k) &
+radfrc(i+1,1,k)+radfrc(i-1,1,k))
radfrc(i+nyodd,ny-1,k) = 0.25 &
*(radfrc(i+nyodd,ny-2,k)+radfrc(i+nyodd,ny-2,k) &
+radfrc(i+nyodd+1,ny-1,k)+radfrc(i+nyodd-1,ny-1,k))
END DO
IF ( nxodd == 1 ) THEN
! coolr (nx-1,1,k) = 0.5*(coolr (nx-2,1,k)+coolr (nx-1,2,k))
! heatr (nx-1,1,k) = 0.5*(heatr (nx-2,1,k)+heatr (nx-1,2,k))
radfrc(nx-1,1,k) = 0.5*(radfrc(nx-2,1,k)+radfrc(nx-1,2,k))
END IF
IF ( nyodd == 1 ) THEN
! coolr (1,ny-1,k) = 0.5*(coolr (1,ny-2,k)+coolr (2,ny-1,k))
! heatr (1,ny-1,k) = 0.5*(heatr (1,ny-2,k)+heatr (2,ny-1,k))
radfrc(1,ny-1,k) = 0.5*(radfrc(1,ny-2,k)+radfrc(2,ny-1,k))
END IF
IF ( MOD(nyodd+nyodd,2) == 1 ) THEN
! coolr (nx-1,ny-1,k) = 0.5*(coolr (nx-1,ny-2,k)
! : +coolr (nx-2,ny-1,k))
! heatr (nx-1,ny-1,k) = 0.5*(heatr (nx-1,ny-2,k)
! : +heatr (nx-2,ny-1,k))
radfrc(nx-1,ny-1,k) = 0.5*(radfrc(nx-1,ny-2,k) &
+radfrc(nx-2,ny-1,k))
END IF
END DO
DO j=1,ny-1
jodd = istgr*MOD(j,2)
DO i=jstgr-jodd, nx-1, jstgr
im = i
jm = j/jstgr + istgr*MOD(i,2)
rnflx(i,j) = solarc * radsw(i,j) * cosss(i,j) & ! radsw = a2dr2
* ( (1.0-rsirbm(im,jm)) * fdirir (im,jm) &
+ (1.0-rsuvbm(im,jm)) * fdirpar(im,jm) &
+ (1.0-rsirdf(im,jm)) * fdifir (im,jm) &
+ (1.0-rsuvdf(im,jm)) * fdifpar(im,jm) ) &
+ flxir(im,jm,nz) ! net downward LW flux at sfc
radsw(i,j) = solarc * radsw(i,j) * cosss(i,j) &
* ( fdirir(im,jm) + fdirpar(im,jm) &
+ fdifir(im,jm) + fdifpar(im,jm) )
END DO
END DO
IF ( nx-1 > 3 ) THEN
DO j=2,ny-2
jeven = MOD(j+1,2)
DO i=2+jeven,nx-2,2
radsw(i,j) = 0.25*(radsw(i+1,j)+radsw(i-1,j) &
+radsw(i,j+1)+radsw(i,j-1))
rnflx(i,j) = 0.25*(rnflx(i+1,j)+rnflx(i-1,j) &
+rnflx(i,j+1)+rnflx(i,j-1))
END DO
END DO
END IF
DO j=2,ny-2,2
radsw(1,j) = 0.25 &
* (radsw(2,j)+radsw(2,j) &
+radsw(1,j+1)+radsw(1,j-1))
radsw(nx-1,j+nxodd) = 0.25 &
* (radsw(nx-2,j+nxodd)+radsw(nx-2,j+nxodd) &
+radsw(nx-1,j+nxodd+1)+radsw(nx-1,j+nxodd-1))
rnflx(1,j) = 0.25 &
* (rnflx(2,j)+rnflx(2,j) &
+rnflx(1,j+1)+rnflx(1,j-1))
rnflx(nx-1,j+nxodd) = 0.25 &
* (rnflx(nx-2,j+nxodd)+rnflx(nx-2,j+nxodd) &
+rnflx(nx-1,j+nxodd+1)+rnflx(nx-1,j+nxodd-1))
END DO
DO i=2,nx-2,2
radsw(i,1) = 0.25 &
* (radsw(i,2)+radsw(i,2) &
+radsw(i+1,1)+radsw(i-1,1))
radsw(i+nyodd,ny-1) = 0.25 &
* (radsw(i+nyodd,ny-2)+radsw(i+nyodd,ny-2) &
+radsw(i+nyodd+1,ny-1)+radsw(i+nyodd-1,ny-1))
rnflx(i,1) = 0.25 &
* (rnflx(i,2)+rnflx(i,2) &
+rnflx(i+1,1)+rnflx(i-1,1))
rnflx(i+nyodd,ny-1) = 0.25 &
* (rnflx(i+nyodd,ny-2)+rnflx(i+nyodd,ny-2) &
+rnflx(i+nyodd+1,ny-1)+rnflx(i+nyodd-1,ny-1))
END DO
IF ( nxodd == 1 ) THEN
radsw(nx-1,1) = 0.5*(radsw(nx-2,1)+radsw(nx-1,2))
rnflx(nx-1,1) = 0.5*(rnflx(nx-2,1)+rnflx(nx-1,2))
END IF
IF ( nyodd == 1 ) THEN
radsw(1,ny-1) = 0.5*(radsw(1,ny-2)+radsw(2,ny-1))
rnflx(1,ny-1) = 0.5*(rnflx(1,ny-2)+rnflx(2,ny-1))
END IF
IF ( MOD(nyodd+nyodd,2) == 1 ) THEN
radsw(nx-1,ny-1) = 0.5*(radsw(nx-1,ny-2)+radsw(nx-2,ny-1))
rnflx(nx-1,ny-1) = 0.5*(rnflx(nx-1,ny-2)+rnflx(nx-2,ny-1))
END IF
END IF
!---------------------------------------------------------------------
!
! Add by Yunheng to update the fake zone for radfrc, radsw, rnflx
!
!--------------------------------------------------------------------
IF (mp_opt > 0) THEN
CALL acct_interrupt
(mp_acct)
CALL mpsend2dew
(radfrc, nx, ny, nz, ebc, wbc, 0, mptag1, tem1)
CALL mprecv2dew
(radfrc, nx, ny, nz, ebc, wbc, 0, mptag1, tem1)
CALL mpsend1dew
(radsw, nx, ny, ebc, wbc, 0, mptag2, tem2)
CALL mprecv1dew
(radsw, nx, ny, ebc, wbc, 0, mptag2, tem2)
CALL mpsend1dew
(rnflx, nx, ny, ebc, wbc, 0, mptag3, tem2)
CALL mprecv1dew
(rnflx, nx, ny, ebc, wbc, 0, mptag3, tem2)
CALL mpsend2dns
(radfrc, nx, ny, nz, nbc, sbc, 0, mptag4, tem1)
CALL mprecv2dns
(radfrc, nx, ny, nz, nbc, sbc, 0, mptag4, tem1)
CALL mpsend1dns
(radsw, nx, ny, nbc, sbc, 0, mptag5, tem2)
CALL mprecv1dns
(radsw, nx, ny, nbc, sbc, 0, mptag5, tem2)
CALL mpsend1dns
(rnflx, nx, ny, nbc, sbc, 0, mptag6, tem2)
CALL mprecv1dns
(rnflx, nx, ny, nbc, sbc, 0, mptag6, tem2)
CALL acct_stop_inter
END IF
!-------------------------- end of addition ------------------------
IF ( raddiag == 1 ) THEN
WRITE(6,'(a,i8,a,f10.2,a)') &
' Dump radiation variables at time step,', nstep, &
', model time=',curtim,' (s)'
!
!-----------------------------------------------------------------------
!
! Write out results to GrADS file for display
!
!-----------------------------------------------------------------------
!
CALL wrtrad
(nx,ny,nz,m,n,x,y,z, &
plinv,tinv,qvinv,qc,qr,qi,qs,qh, o3a,radbuf(1), &
ccld, tauir,taual,tauswi,tauswl,reffi,reffl, &
rsirbm,rsirdf,rsuvbm,rsuvdf, &
fdirir,fdifir,fdirpar,fdifpar, &
dfdts, radsw,rnflx, cosz, &
flxir,flcir, flxuv,flcuv, &
radfrc)
! : radfrc, coolr,heatr)
END IF
RETURN
END SUBROUTINE radtrns
!
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE SETRADWRK ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE setradwrk( nx,ny,nz ) 1
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Set the indeces for radiation working arrays
!
!-----------------------------------------------------------------------
!
! AUTHOR: Yuhe Liu
! 04/09/1997
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! 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 z-direction (vertical)
!
!-----------------------------------------------------------------------
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: nx,ny,nz ! The number grid points in 3 directions
INTEGER :: nxy, nxyz
!
!-----------------------------------------------------------------------
!
! Include files
!
!-----------------------------------------------------------------------
!
INCLUDE 'radcst.inc'
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
nxy = nx*ny
nxyz = nxy*nz
!
!-----------------------------------------------------------------------
!
! Define indices which determine the positions of temporary arrays
! used in subroutine IRRAD and the subroutine IRRAD calls.
!
!-----------------------------------------------------------------------
!
ir2d1 = 1+ 1*nxy
ir2d2 = 1+ 2*nxy
ir2d3 = 1+ 3*nxy
ir2d4 = 1+ 4*nxy
ir2d5 = 1+10*nxy
ir2d6 = 1+13*nxy
ir3d1 = 1+25*nxy+ 0*nxyz
ir3d2 = 1+25*nxy+ 1*nxyz
ir3d3 = 1+25*nxy+ 2*nxyz
ir3d4 = 1+25*nxy+ 3*nxyz
ir3d5 = 1+25*nxy+ 4*nxyz
ir3d6 = 1+25*nxy+ 5*nxyz
ir3d7 = 1+25*nxy+ 6*nxyz
ir3d8 = 1+25*nxy+ 7*nxyz
ir3d9 = 1+25*nxy+ 8*nxyz
ir3d10 = 1+25*nxy+ 9*nxyz
ir3d11 = 1+25*nxy+10*nxyz
ir3d12 = 1+25*nxy+11*nxyz
ir3d13 = 1+25*nxy+12*nxyz
ir3d14 = 1+25*nxy+13*nxyz
ir3d15 = 1+25*nxy+14*nxyz
ir3d16 = 1+26*nxy+15*nxyz
ir4d1 = 1+27*nxy+16*nxyz
ir4d2 = 1+27*nxy+22*nxyz
ir5d1 = 1+27*nxy+25*nxyz
!
!-----------------------------------------------------------------------
!
! Define indices which determine the positions of temporary arrays
! used in subroutine SOLIR, SOLUV, and CLDFLX.
!
!-----------------------------------------------------------------------
!
so2d1 = 1+ 1*nxy
so2d2 = 1+ 2*nxy
so2d3 = 1+ 3*nxy
so2d4 = 1+ 4*nxy
so2d5 = 1+ 7*nxy
so2d6 = 1+ 8*nxy
so2d7 = 1+ 9*nxy
so2d8 = 1+10*nxy
so2d9 = 1+11*nxy
so2d10 = 1+12*nxy
so2d11 = 1+13*nxy
so2d12 = 1+14*nxy
so2d13 = 1+15*nxy
so2d14 = 1+16*nxy
so2d15 = 1+17*nxy
so2d16 = 1+18*nxy
so2d17 = 1+19*nxy
so2d18 = 1+20*nxy
so2d19 = 1+21*nxy
so2d20 = 1+22*nxy
so2d21 = 1+23*nxy
so2d22 = 1+24*nxy
so2d23 = 1+25*nxy
so3d1 = 1+26*nxy+ 0*nxyz
so3d2 = 1+26*nxy+ 1*nxyz
so3d3 = 1+26*nxy+ 2*nxyz
so3d4 = 1+26*nxy+ 3*nxyz
so3d5 = 1+26*nxy+ 4*nxyz
so3d6 = 1+26*nxy+ 5*nxyz
so3d7 = 1+26*nxy+ 6*nxyz
so3d8 = 1+26*nxy+ 7*nxyz
so3d9 = 1+26*nxy+ 8*nxyz
so3d10 = 1+26*nxy+ 9*nxyz
so3d11 = 1+26*nxy+10*nxyz
so3d12 = 1+26*nxy+11*nxyz
so3d13 = 1+26*nxy+12*nxyz
so3d14 = 1+26*nxy+13*nxyz
so4d1 = 1+26*nxy+14*nxyz
so4d2 = 1+26*nxy+16*nxyz
so4d3 = 1+26*nxy+18*nxyz
so4d4 = 1+26*nxy+20*nxyz
so4d5 = 1+26*nxy+22*nxyz
so5d1 = 1+26*nxy+24*nxyz
so5d2 = 1+26*nxy+28*nxyz
so5d3 = 1+26*nxy+32*nxyz
so5d4 = 1+26*nxy+36*nxyz
so5d5 = 1+26*nxy+40*nxyz
RETURN
END SUBROUTINE setradwrk
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE WRTRAD ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE wrtrad(nx,ny,nz,m,n,x,y,z, & 1,40
plinv,tinv,qvinv,qc,qr,qi,qs,qh,o3a,tsfc, &
ccld, tauir,taual,tauswi,tauswl,reffi,reffl, &
rsirbm,rsirdf,rsuvbm,rsuvdf, &
fdirir,fdifir,fdirpar,fdifpar, &
dfdts, radsw,rnflx, cosz, &
flxir,flcir,flxuv,flcuv, &
radfrc)
! : radfrc, coolr,heatr)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Write surface fields in GrADS format for diagnostic purpose.
!
! In the staggering case, only radfrc, coolr, and heatr have values
! at entire domain. Other variables have their values on every
! (i,j) = (even,even) and (odd,odd) point and they are defragmented
! with index i in the range between 1 and nx/2.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Yuhe Liu
! 03/13/1996
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! 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 z-direction (vertical)
!
!-----------------------------------------------------------------------
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: nx,ny,nz ! The number grid points in 3 directions
INTEGER :: m, n
REAL :: x(nx)
REAL :: y(ny)
REAL :: z(nz)
REAL :: plinv (nx,ny,nz)
REAL :: tinv (nx,ny,nz)
REAL :: qvinv (nx,ny,nz)
REAL :: qc (nx,ny,nz)
REAL :: qr (nx,ny,nz)
REAL :: qi (nx,ny,nz)
REAL :: qs (nx,ny,nz)
REAL :: qh (nx,ny,nz)
REAL :: o3a (nx,ny,nz)
REAL :: tsfc (nx,ny)
REAL :: ccld (nx,ny,nz)
REAL :: tauir (nx,ny,nz)
REAL :: taual (nx,ny,nz)
REAL :: tauswi(nx,ny,nz)
REAL :: tauswl(nx,ny,nz)
REAL :: reffi (nx,ny,nz)
REAL :: reffl (nx,ny,nz)
REAL :: rsirbm(nx,ny)
REAL :: rsirdf(nx,ny)
REAL :: rsuvbm(nx,ny)
REAL :: rsuvdf(nx,ny)
REAL :: fdirir(nx,ny)
REAL :: fdifir(nx,ny)
REAL :: fdirpar(nx,ny)
REAL :: fdifpar(nx,ny)
REAL :: dfdts(nx,ny,nz)
REAL :: cosz (nx,ny)
REAL :: flxir(nx,ny,nz)
REAL :: flcir(nx,ny,nz)
REAL :: flxuv(nx,ny,nz)
REAL :: flcuv(nx,ny,nz)
REAL :: radfrc(nx,ny,nz)
! real coolr (nx,ny,nz)
! real heatr (nx,ny,nz)
REAL :: radsw(nx,ny)
REAL :: rnflx(nx,ny)
!
!-----------------------------------------------------------------------
!
! Misc. local variables:
!
!-----------------------------------------------------------------------
!
INTEGER :: i, j, k
INTEGER :: tnum,tint
INTEGER :: year1,month1,day1, hour1,minute1,second1
INTEGER :: jday1, loopdy
CHARACTER (LEN=2) :: dtunit
INTEGER :: mndys(12) ! days for each months
CHARACTER (LEN=3) :: monnam(12)
CHARACTER (LEN=70) :: flnctl, flnrad
INTEGER :: radunit, flnctlen, radlen
INTEGER :: ierr
LOGICAL :: firstcall
!
!-----------------------------------------------------------------------
!
! Include files
!
!-----------------------------------------------------------------------
!
INCLUDE 'globcst.inc'
INCLUDE 'grid.inc' ! Grid & map parameters.
!
!-----------------------------------------------------------------------
!
! Save and initialize variables.
!
!-----------------------------------------------------------------------
!
SAVE firstcall, radunit
DATA firstcall/.true./
DATA mndys/0,31,59,90,120,151,181,212,243,273,304,334/
DATA monnam/'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', &
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'/
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
IF ( firstcall ) THEN
IF ( dtrad <= 0.0 ) THEN
WRITE (6, '(/a,a)') &
'Since dtrad <= 0, only data at the first time step ', &
'will be dumped.'
tnum = 1
tint = 1
dtunit = 'MN'
ELSE IF ( dtrad < 60.0 ) THEN
WRITE (6, '(/a/a)') &
'GrADS reqiures the smallest uint minute for time interval.', &
'Here we use uint MN to represent the second.'
tnum = nint(tstop/dtrad) + 1
tint = nint(dtrad)
dtunit = 'MN'
ELSE IF ( dtrad < 3600.0 ) THEN
tnum = nint(tstop/dtrad) + 1
tint = nint(dtrad/60.)
dtunit = 'MN'
ELSE IF ( dtrad < 86400.0 ) THEN
tnum = nint(tstop/dtrad) + 1
tint = nint(dtrad/3600.)
dtunit = 'HR'
ELSE
tnum = nint(tstop/dtrad) + 1
tint = nint(dtrad/86400.)
dtunit = 'DY'
END IF
IF ( initopt /= 2 ) THEN
second1 = second
minute1 = minute
hour1 = hour
day1 = day
month1 = month
year1 = year
ELSE
second1 = MOD( second + nint(tstart), 60 )
minute1 = ( second + nint(tstart) ) / 60
minute1 = MOD( minute + minute1, 60 )
hour1 = ( minute + ( second + nint(tstart) ) / 60 ) /60
hour1 = MOD( hour + hour1, 24 )
day1 = ( hour + ( minute &
+ ( second + nint(tstart) ) / 60 ) /60 ) / 24
jday1 = jday + day1
loopdy = 0
IF ( MOD( year, 4 ) == 0 ) loopdy = 1
year1 = year + jday1 / ( 365 + loopdy )
jday1 = MOD( jday1, 365 + loopdy )
month1 = 1
DO m = 2, 11
IF ( jday1 > mndys(m) .AND. jday1 <= mndys(m+1) + loopdy ) month1 = m
END DO
day1 = jday1 - mndys(month1)
END IF
flnctlen = lfnkey + 7
flnctl(1:flnctlen) = runname(1:lfnkey)//'.radctl'
CALL fnversn
( flnctl, flnctlen )
flnrad(1:ldirnam) = dirname(1:ldirnam)
radlen = ldirnam + lfnkey + 8
flnrad(1:radlen) = flnrad(1:ldirnam)//'/'//runname(1:lfnkey) &
//'.radout'
CALL fnversn
( flnrad, radlen )
!
!-----------------------------------------------------------------------
!
! Open GrADS data control file for surface variables.
!
!-----------------------------------------------------------------------
!
CALL getunit
(radunit)
OPEN (UNIT = radunit, FILE = flnctl(1:flnctlen), &
FORM = 'formatted', STATUS = 'new')
WRITE (6,'(a,a)') &
'Radiation output control file ', flnctl(1:flnctlen)
WRITE (radunit,'(a)') &
'TITLE Radiation output for '//runname(1:lfnkey)
WRITE (radunit,'(a)') &
'*'
WRITE (radunit,'(a,a)') &
'DSET ', flnrad(1:radlen)
WRITE (radunit,'(a)') &
'OPTIONS sequential cray_32bit_ieee'
WRITE (radunit,'(a)') &
'UNDEF -9.e+33'
WRITE (radunit,'(a,i8,a,2f10.4)') &
'XDEF ', nx, ' LINEAR ',(x(1)+x(2))/2000.,dx/1000.
WRITE (radunit,'(a,i8,a,2f10.4)') &
'YDEF ', ny, ' LINEAR ',(y(1)+y(2))/2000.,dy/1000.
WRITE (radunit,'(a,1x,i8,a)') &
'ZDEF',nz,' LEVELS '
WRITE (radunit,'(8f10.4)') &
((z(k)+z(k+1))/2000.,k=1,nz-1),z(nz)/1000.
WRITE (radunit,'(a,i8,a,i2.2,a,i2.2,a,i2.2,a3,i4.4, &
& 3X,i2.2,a)') &
'TDEF ', tnum, ' LINEAR ', &
hour1,':',minute1,'Z',day1,monnam(month1),year1, &
tint,dtunit
WRITE (radunit,'(a)') &
'*'
WRITE (radunit,'(a)') &
'VARS 34'
! : 'VARS 36'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'p ', nz,'99 Pressure (mb)'
WRITE (radunit,'(a,2x,i4,2x,a)') &
't ', nz,'99 Temperature (K)'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'qv ', nz,'99 Specific humidity (g/g)'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'qc ', nz,'99 Cloud water mixing ratio (g/g)'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'qr ', nz,'99 Rain water mixing ratio (g/g)'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'qi ', nz,'99 Ice mixing ratio (g/g)'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'qs ', nz,'99 Snow mixing ratio (g/g)'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'qh ', nz,'99 Hail mixing ratio (g/g)'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'o3 ', nz,'99 Ozone concentration (g/g)'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'cld ', nz,'99 Cloud coverage (%)'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'taual', nz,'99 Cloud optical depth for aeresol'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'tauir', nz,'99 Cloud optical depth for IR'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'tausi', nz,'99 Ice cloud optical depth for SW'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'tausl', nz,'99 Liquid cloud optical depth for SW'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'reffi', nz,'99 Eff. ice-cloud-particle size (mm)'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'reffl', nz,'99 Eff. liquid-cloud-particle size (mm)'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'flxir', nz,'99 all-sky IR flux'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'flcir', nz,'99 Cloud IR flux'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'flxuv', nz,'99 all-sky UV flux'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'flcuv', nz,'99 Clear-sky UV flux'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'dfdts', nz,'99 sensitivity to surface temperature'
WRITE (radunit,'(a,2x,i4,2x,a)') &
'radfc', nz,'99 radiation forcing (K/s)'
! write (radunit,'(a,2x,i4,2x,a)')
! : 'coolr', nz,'99 radiation cooling rate (K/day)'
! write (radunit,'(a,2x,i4,2x,a)')
! : 'heatr', nz,'99 radiation heating rate (K/day)'
WRITE (radunit,'(a)') &
'ts 0 99 Soil temperature (K)'
WRITE (radunit,'(a)') &
'albd1 0 99 solar ir surface albedo for beam'
WRITE (radunit,'(a)') &
'albd2 0 99 solar ir surface albedo for diffuse'
WRITE (radunit,'(a)') &
'albd3 0 99 solar uv surface albedo for beam'
WRITE (radunit,'(a)') &
'albd4 0 99 solar uv surface albedo for diffuse'
WRITE (radunit,'(a)') &
'cosz 0 99 Cosine of zenith'
WRITE (radunit,'(a)') &
'radsw 0 99 solar flux reaching the surface'
WRITE (radunit,'(a)') &
'rnflx 0 99 net radiation flux absorbed by surface'
WRITE (radunit,'(a)') &
'dirir 0 99 all-sky direct downward ir at sfc'
WRITE (radunit,'(a)') &
'difir 0 99 all-sky diffuse downward ir at sfc'
WRITE (radunit,'(a)') &
'dirpa 0 99 all-sky direct downward par at sfc'
WRITE (radunit,'(a)') &
'difpa 0 99 all-sky diffuse downward par at sfc'
WRITE (radunit,'(a)') &
'ENDVARS'
CLOSE (radunit)
CALL retunit (radunit)
!
!-----------------------------------------------------------------------
!
! Open GrADS data file for surface variables.
!
!-----------------------------------------------------------------------
!
CALL getunit
(radunit)
CALL asnctl
('NEWLOCAL', 1, ierr)
CALL asnfile
(flnrad(1:radlen), '-F f77 -N ieee', ierr)
OPEN (UNIT = radunit, FILE = flnrad(1:radlen), &
FORM = 'unformatted', STATUS = 'new', &
ACCESS = 'sequential')
firstcall = .false.
END IF
CALL edgfill
(plinv, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz)
DO k=nz,1,-1
WRITE(radunit) ((plinv(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(tinv, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz-1)
DO k=nz,1,-1
WRITE(radunit) ((tinv(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(qvinv, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz-1)
DO k=nz,1,-1
WRITE(radunit) ((qvinv(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(qc, 1,nx,1,nx-1, 1,ny,1,ny-1, 1,nz,1,nz-1)
DO k=1,nz
WRITE(radunit) ((qc(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(qr, 1,nx,1,nx-1, 1,ny,1,ny-1, 1,nz,1,nz-1)
DO k=1,nz
WRITE(radunit) ((qr(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(qi, 1,nx,1,nx-1, 1,ny,1,ny-1, 1,nz,1,nz-1)
DO k=1,nz
WRITE(radunit) ((qi(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(qs, 1,nx,1,nx-1, 1,ny,1,ny-1, 1,nz,1,nz-1)
DO k=1,nz
WRITE(radunit) ((qs(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(qh, 1,nx,1,nx-1, 1,ny,1,ny-1, 1,nz,1,nz-1)
DO k=1,nz
WRITE(radunit) ((qh(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(o3a, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz-1)
DO k=nz,1,-1
WRITE(radunit) ((o3a(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(ccld, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz-1)
DO k=nz,1,-1
WRITE(radunit) ((ccld(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(taual, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz-1)
DO k=nz,1,-1
WRITE(radunit) ((taual(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(tauir, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz-1)
DO k=nz,1,-1
WRITE(radunit) ((tauir(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(tauswi, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz-1)
DO k=nz,1,-1
WRITE(radunit) ((tauswi(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(tauswl, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz-1)
DO k=nz,1,-1
WRITE(radunit) ((tauswl(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(reffi, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz-1)
DO k=nz,1,-1
WRITE(radunit) ((reffi(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(reffl, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz-1)
DO k=nz,1,-1
WRITE(radunit) ((reffl(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(flxir, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz)
DO k=nz,1,-1
WRITE(radunit) ((flxir(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(flcir, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz)
DO k=nz,1,-1
WRITE(radunit) ((flcir(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(flxuv, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz)
DO k=nz,1,-1
WRITE(radunit) ((flxuv(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(flcuv, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz)
DO k=nz,1,-1
WRITE(radunit) ((flcuv(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(dfdts, 1,nx,1,m, 1,ny,1,n, 1,nz,1,nz)
DO k=nz,1,-1
WRITE(radunit) ((dfdts(i,j,k),i=1,nx),j=1,ny)
END DO
CALL edgfill
(radfrc, 1,nx,1,nx-1, 1,ny,1,ny-1, 1,nz,2,nz-2)
DO k=1,nz
WRITE(radunit) ((radfrc(i,j,k),i=1,nx),j=1,ny)
END DO
! CALL edgfill(coolr, 1,nx,1,nx-1, 1,ny,1,ny-1, 1,nz,2,nz-2)
! DO 300 k=1,nz
! write(radunit) ((coolr(i,j,k),i=1,nx),j=1,ny)
!300 CONTINUE
! CALL edgfill(heatr, 1,nx,1,nx-1, 1,ny,1,ny-1, 1,nz,2,nz-2)
! DO 310 k=1,nz
! write(radunit) ((heatr(i,j,k),i=1,nx),j=1,ny)
!310 CONTINUE
CALL edgfill
(tsfc, 1,nx,1,m, 1,ny,1,n, 1,1,1,1)
WRITE(radunit) tsfc
CALL edgfill
(rsirbm, 1,nx,1,m, 1,ny,1,n, 1,1,1,1)
WRITE(radunit) rsirbm
CALL edgfill
(rsirdf, 1,nx,1,m, 1,ny,1,n, 1,1,1,1)
WRITE(radunit) rsirdf
CALL edgfill
(rsuvbm, 1,nx,1,m, 1,ny,1,n, 1,1,1,1)
WRITE(radunit) rsuvbm
CALL edgfill
(rsuvdf, 1,nx,1,m, 1,ny,1,n, 1,1,1,1)
WRITE(radunit) rsuvdf
CALL edgfill
(cosz, 1,nx,1,m, 1,ny,1,n, 1,1,1,1)
WRITE(radunit) cosz
CALL edgfill
(radsw, 1,nx,1,nx-1, 1,ny,1,ny-1, 1,1,1,1)
WRITE(radunit) radsw
CALL edgfill
(rnflx, 1,nx,1,nx-1, 1,ny,1,ny-1, 1,1,1,1)
WRITE(radunit) rnflx
CALL edgfill
(fdirir, 1,nx,1,m, 1,ny,1,n, 1,1,1,1)
WRITE(radunit) fdirir
CALL edgfill
(fdifir, 1,nx,1,m, 1,ny,1,n, 1,1,1,1)
WRITE(radunit) fdifir
CALL edgfill
(fdirpar, 1,nx,1,m, 1,ny,1,n, 1,1,1,1)
WRITE(radunit) fdirpar
CALL edgfill
(fdifpar, 1,nx,1,m, 1,ny,1,n, 1,1,1,1)
WRITE(radunit) fdifpar
RETURN
END SUBROUTINE wrtrad
!
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE CLDOPTD ######
!###### ######
!###### Developed by ######
!###### ######
!###### Goddard Cumulus Ensemble Modeling Group, NASA ######
!###### ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE cldoptd(nx,ny,m,n,nz, radstgr, & 1
pres,temp,qc,qr,qi,qs,qh, rhostr, j3inv, &
tauir,tauswi,tauswl,reffi,reffl)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Calculate the optical depth
!
!-----------------------------------------------------------------------
!
! AUTHOR: NASA Goddard Center
!
! MODIFICATION:
!
! 03/11/1996 (Yuhe Liu)
! Modified the original code from 1-D to 3-D
!
!-----------------------------------------------------------------------
!
! 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 z-direction (vertical)
!
! Vertical index order
! pres Pressure (mb) 1 for top
! temp Temperature (K), 1 for top
! qc Cloud water mixing ratio (g/g), 1 for bottom
! qr Rain water mixing ratio (g/g), 1 for bottom
! qi cloud ice mixing ratio (g/g), 1 for bottom
! qs Snow mixing ratio (g/g), 1 for bottom
! qh Hail mixing ratio (g/g), 1 for bottom
! rhostr Density multiply by j3, 1 for bottom
! j3inv 1/j3, 1 for bottom
!
! OUTPUT:
!
! tauir Cloud optical depth for longwave, 1 for bottom
! tauswi Cloud optical depth for ice cloud
! for shortwave, 1 for bottom
! tauswl Cloud optical depth for liquid cloud
! for shortwave, 1 for bottom
! reffi Effective cloud-particle size (mm)
! for ice cloud for shortwave, 1 for bottom
! reffl Effective cloud-particle size (mm)
! for liquid cloud for shortwave, 1 for bottom
!
! WORK ARRAY:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: nx,ny,nz
INTEGER :: m,n
INTEGER :: radstgr
REAL :: pres (nx,ny,nz) ! in mb
REAL :: temp (nx,ny,nz) ! in K
REAL :: qc (nx,ny,nz) ! in g/g
REAL :: qr (nx,ny,nz) ! in g/g
REAL :: qi (nx,ny,nz) ! in g/g
REAL :: qs (nx,ny,nz) ! in g/g
REAL :: qh (nx,ny,nz) ! in g/g
REAL :: rhostr(nx,ny,nz) ! in kg/m**3
REAL :: j3inv (nx,ny,nz)
REAL :: tauir (nx,ny,nz)
REAL :: tauswi(nx,ny,nz)
REAL :: tauswl(nx,ny,nz)
REAL :: reffi (nx,ny,nz)
REAL :: reffl (nx,ny,nz)
REAL :: tauqc
REAL :: tauqr
REAL :: tauqi
REAL :: tauqs
REAL :: tauqh
REAL :: reff1
REAL :: reff2
REAL :: w1, effrad
REAL :: cpi,twco, dpg, rho
INTEGER :: i,j,k, im,jm,km
INTEGER :: istgr, jstgr, jodd
!
!-----------------------------------------------------------------------
!
! Include files:
!
!-----------------------------------------------------------------------
!
INCLUDE 'phycst.inc'
INCLUDE 'radcst.inc'
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
cpi = 4.*ATAN(1.)
twco = 1.e-6
IF ( radstgr == 0 ) THEN
istgr = 0
jstgr = 1
ELSE
istgr = 1
jstgr = 2
END IF
DO km=3,nz-1
k = nz+1-km
DO j=1,ny-1
jodd = istgr*MOD(j,2)
DO i=jstgr-jodd, nx-1, jstgr
im = i
jm = j/jstgr + istgr*MOD(im,2)
rho = rhostr(i,j,k)*j3inv(i,j,k)*1.0E-3 ! g/cm**3
dpg = 10.0*(pres(im,jm,km+1)-pres(im,jm,km))/g ! g/cm**2
IF ( qc(i,j,k) >= twco ) THEN
w1 = dpg*qc(i,j,k)
effrad = 0.0015
tauqc = w1/effrad
reff2 = effrad*1.0E4
ELSE
tauqc = 0.0
reff2 = 0.0
END IF
IF ( qr(i,j,k) >= twco ) THEN
w1 = dpg*qr(i,j,k)
effrad = 3./((cpi*tnw*roqr/(rho*qr(i,j,k)))**.25)
tauqr = w1/effrad
ELSE
tauqr=0.0
END IF
IF ( qi(i,j,k)+qs(i,j,k) >= twco ) THEN
w1 = 1.e4*dpg*(qi(i,j,k)+qs(i,j,k))
IF ( temp(im,jm,km) > 243.16 ) THEN
effrad = 0.0125
ELSE IF ( temp(im,jm,km) < 223.16 ) THEN
effrad = 0.0025
ELSE
effrad = 0.0125+(temp(im,jm,km)-243.16)*0.00050
END IF
tauqs = w1*(-0.006656 + 3.686E-4/effrad)
tauqi = w1*(-0.011500 + 4.110E-4/effrad &
+ 17.300E-8/(effrad*effrad))
reff1 = effrad*1.0E4
ELSE
tauqi = 0.0
tauqs = 0.0
reff1 = 0.0
END IF
IF ( qh(i,j,k) >= twco ) THEN
w1 = dpg*qh(i,j,k)
effrad = 3./((cpi*tng*roqg/(rho*qh(i,j,k)))**.25)
tauqh = w1/effrad
ELSE
tauqh = 0.0
END IF
tauswi(im,jm,km) = tauqs + tauqh
tauswl(im,jm,km) = 1.5 * ( tauqc + tauqr )
reffi (im,jm,km) = reff1
reffl (im,jm,km) = reff2
tauir (im,jm,km) = 0.5 * tauswl(im,jm,km) + tauqi + tauqh
END DO
END DO
END DO
IF ( radstgr /= 0 .AND. MOD(ny,2) == 0 ) THEN
DO km=3,nz-1
DO im=2,m,2
tauswi(im,n,km) = tauswi(im,n-1,km)
tauswl(im,n,km) = tauswl(im,n-1,km)
reffi (im,n,km) = reffi (im,n-1,km)
reffl (im,n,km) = reffl (im,n-1,km)
tauir (im,n,km) = tauir (im,n-1,km)
END DO
END DO
END IF
DO jm=1,n
DO im=1,m
tauswi(im,jm,1) = 0.0
tauswl(im,jm,1) = 0.0
reffi (im,jm,1) = 0.0
reffl (im,jm,1) = 0.0
tauir (im,jm,1) = 0.0
tauswi(im,jm,2) = 0.0
tauswl(im,jm,2) = 0.0
reffi (im,jm,2) = 0.0
reffl (im,jm,2) = 0.0
tauir (im,jm,2) = 0.0
END DO
END DO
RETURN
END SUBROUTINE cldoptd
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE FITO3 ######
!###### ######
!###### Developed by ######
!###### ######
!###### Goddard Cumulus Ensemble Modeling Group, NASA ######
!###### ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE fito3(nx,ny,m,n,np,pl,ao) 1,2
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! This subroutine is to fit o3 to the model grid
!
!-----------------------------------------------------------------------
!
! AUTHOR: (a) Radiative Transfer Model: M.-D. Chou and M. Suarez
! (b) Cloud Optics:Tao, Lang, Simpson, Sui, Ferrier and
! Chou (1996)
!
! MODIFICATION HISTORY:
!
! 03/15/1996 (Yuhe Liu)
! Modified the subroutine from 1-D to 3-D
!
!-----------------------------------------------------------------------
!
!fpp$ expand (terp1)
!dir$ inline always terp1
!*$* inline routine (terp1)
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: nx,ny,np
INTEGER :: m,n
REAL :: pl(nx,ny,np+1) ! Model pressure (mb)
REAL :: ao(nx,ny,np) ! Model o3 mixing ratio (g/g)
!
!-----------------------------------------------------------------------
!
! Local definitions
!
!-----------------------------------------------------------------------
!
INTEGER :: lay
PARAMETER (lay=75)
! integer iop(2),itab(3),iflag(5)
INTEGER :: iop(2),itab(3)
REAL :: pa(lay) ! Local layer pressure (mb)
REAL :: ta(lay) ! Local layer temperature (K)
REAL :: wa(lay) ! Local layer water vapor mixing ratio (g/g)
REAL :: oa(lay) ! Local layer o3 mixing ratio (g/g)
! real tsi(5)
! real w(lay)
REAL :: tab(3)
REAL :: wk(lay,4)
INTEGER :: i,j,k
INTEGER :: INT, ix
! integer lun
! real y
REAL :: p
!
!----- ix= 1:trp; 2:mls; 3:mlw; 4:sas; 5:saw
! data iflag/ 1 , 0 , 0 , 0 , 0 /
! data tsi/ 300.0, 294.0, 272.2, 287.0, 257.1/
!
!-----------------------------------------------------------------------
!
! Local data bank for pressure, temperature, moisture, and o3
!
!-----------------------------------------------------------------------
!
DATA (pa(k),k=1,lay)/ &
.0003, .0008, .0011, .0015, .0021, &
.0029, .0041, .0058, .0081, .0113, &
.0158, .0221, .0310, .0435, .0609, &
.0855, .1200, .1700, .2400, .3350, &
.4650, .6500, .9150, 1.2850, 1.8000, &
2.5250, 3.5450, 4.9700, 6.9700, 9.7800, &
13.7150, 19.2350, 26.9850, 37.8550, 53.1000, &
73.8900, 97.6650, 121.4350, 145.2100, 168.9900, &
192.7650, 216.5400, 240.3150, 264.0900, 287.8650, &
311.6350, 335.4100, 359.1900, 382.9650, 406.7400, &
430.5150, 454.2850, 478.0600, 501.8350, 525.6100, &
549.3900, 573.1650, 596.9400, 620.7150, 644.4900, &
668.2650, 692.0350, 715.8100, 739.5850, 763.3600, &
787.1400, 810.9150, 834.6900, 858.4650, 882.2400, &
906.0150, 929.7850, 953.5600, 977.3350, 1001.1100/
DATA (ta(k),k=1,lay)/ &
209.86, 210.20, 210.73, 211.27, 211.81, &
212.35, 212.89, 213.44, 213.98, 214.53, &
215.08, 215.62, 216.17, 216.74, 218.11, &
223.20, 230.04, 237.14, 244.46, 252.00, &
259.76, 267.70, 274.93, 274.60, 269.38, &
262.94, 256.45, 250.12, 244.31, 238.96, &
233.74, 228.69, 224.59, 221.75, 219.10, &
216.64, 215.76, 215.75, 215.78, 216.22, &
219.15, 223.79, 228.29, 232.45, 236.33, &
239.92, 243.32, 246.53, 249.56, 252.43, &
255.14, 257.69, 260.11, 262.39, 264.57, &
266.66, 268.67, 270.60, 272.48, 274.29, &
276.05, 277.75, 279.41, 281.02, 282.59, &
284.09, 285.53, 286.86, 288.06, 289.13, &
290.11, 291.03, 291.91, 292.76, 293.59/
DATA (wa(k),k=1,lay)/ &
0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, &
0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, &
0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, &
0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, &
0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, &
0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, &
0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, 0.400E-05, &
0.400E-05, 0.400E-05, 0.400E-05, 0.406E-05, 0.520E-05, &
0.115E-04, 0.275E-04, 0.572E-04, 0.107E-03, 0.166E-03, &
0.223E-03, 0.285E-03, 0.360E-03, 0.446E-03, 0.547E-03, &
0.655E-03, 0.767E-03, 0.890E-03, 0.103E-02, 0.118E-02, &
0.136E-02, 0.159E-02, 0.190E-02, 0.225E-02, 0.264E-02, &
0.306E-02, 0.351E-02, 0.399E-02, 0.450E-02, 0.504E-02, &
0.560E-02, 0.619E-02, 0.680E-02, 0.742E-02, 0.805E-02, &
0.869E-02, 0.935E-02, 0.100E-01, 0.107E-01, 0.113E-01/
DATA (oa(k),k=1,lay)/ &
.643E-07, .202E-06, .246E-06, .290E-06, .334E-06, &
.378E-06, .422E-06, .467E-06, .512E-06, .557E-06, &
.603E-06, .648E-06, .694E-06, .740E-06, .793E-06, &
.101E-05, .131E-05, .164E-05, .198E-05, .234E-05, &
.272E-05, .312E-05, .359E-05, .465E-05, .590E-05, &
.765E-05, .910E-05, .960E-05, .994E-05, .101E-04, &
.990E-05, .853E-05, .710E-05, .576E-05, .423E-05, &
.260E-05, .152E-05, .102E-05, .786E-06, .598E-06, &
.448E-06, .352E-06, .302E-06, .252E-06, .212E-06, &
.193E-06, .176E-06, .160E-06, .147E-06, .137E-06, &
.127E-06, .118E-06, .109E-06, .103E-06, .975E-07, &
.924E-07, .883E-07, .846E-07, .810E-07, .778E-07, &
.749E-07, .721E-07, .694E-07, .671E-07, .648E-07, &
.626E-07, .607E-07, .593E-07, .579E-07, .565E-07, &
.552E-07, .540E-07, .528E-07, .517E-07, .505E-07/
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
ix=1
iop(1)=4
iop(2)=4
INT=1
itab(1)=1
itab(2)=0
itab(3)=0
CALL coeff
(lay,pa,oa,wa,iop,INT,wk)
DO k=1,np
DO j=1,n
DO i=1,m
p = 0.5 * ( pl(i,j,k+1) + pl(i,j,k) )
CALL terp1
(lay,pa,oa,wa,p,INT,tab,itab)
ao(i,j,k)=tab(1)
END DO
END DO
END DO
RETURN
END SUBROUTINE fito3
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION AERODEN ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
FUNCTION aeroden(p,psfc)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Assign aerosol optical density (per Pa)
! For now we use an estimate based on the aerosol density used
! in simple climate models, where 0.05 of optical depth is
! assumed uniformly distributed over mass sfc to 800 mb and
! 0.025 is uniformly distributed over mass 800 mb to 225 mb.
!
! Here we normalize that distribution according to the
! surface pressure so that the mountains don't lose aerosols.
!
! Aerosol optical depth is computed by calling routine as
! layer depth (Pa) times this aerosol density.
!
! AUTHOR: Keith Brewster
!
! MODIFICATION HISTORY
!
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
REAL :: p,psfc
REAL :: aeroden
!
IF (p < (.225*psfc)) THEN
aeroden=0.
ELSE IF (p < (.80*psfc)) THEN
aeroden=0.025/(0.575*psfc)
ELSE
aeroden=0.050/(0.2*psfc)
END IF
RETURN
END FUNCTION aeroden
!
!##################################################################
!##################################################################
!###### ######
!###### FUNCTION RH_TO_CLDCV ######
!###### ######
!##################################################################
!##################################################################
!
FUNCTION rh_to_cldcv(rh,hgt)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Obtain first guess cloud cover field from relative humidity.
!
!
! AUTHOR: Jian Zhang
! 07/95
!
! MODIFICATION HISTORY
!
! 04/08/97 J. Zhang
! Added the empirical relationship between RH and
! cloud cover used by Koch et al. (1997).
! Reference:
! Reference:
! Koch, S.E., A. Aksakal, and J.T. McQueen, 1997:
! The influence of mesoscale humidity and evapotranspiration
! fields on a model forecast of a cold-frontal squall line.
! Mon. Wea. Rev., Vol.125, 384-409
! 09/10/97 J. Zhang
! Modified the empirical relationship between cloud
! fraction and relative humidity from quadratic
! to one-fourth-power.
!
!
!-----------------------------------------------------------------------
!
! INPUT:
! rh ! relative humidity
! hgt ! height (AGL)
!
! OUTPUT:
! rh_to_cld_cv ! cloud fractional cover value
!
! LOCAL:
! rh0 ! the critical RH value that seperate clear
! air condition and cloudy condition
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: rh2cform
PARAMETER (rh2cform=2)
REAL :: rh,hgt,rh_to_cldcv
REAL :: rh0
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
IF(rh2cform == 1) THEN
!
!-----------------------------------------------------------------------
!
! A quadratic relationship between relative humidity and cloud
! fractional cover.
!
!-----------------------------------------------------------------------
!
IF (hgt < 600.0) THEN
rh0 = 0.9
ELSE IF (hgt < 1500.0) THEN
rh0 = 0.8
ELSE IF (hgt < 2500.0) THEN
rh0 = 0.6
ELSE
rh0 = 0.5
END IF
IF (rh < rh0) THEN
rh_to_cldcv = 0.0
ELSE
rh_to_cldcv = (rh - rh0)/(1.0 - rh0)
rh_to_cldcv = rh_to_cldcv*rh_to_cldcv
END IF
ELSE IF(rh2cform == 2) THEN
!
!-----------------------------------------------------------------------
!
! A quadratic relationship between relative humidity and cloud
! fractional cover with fixed rh0=0.75
!
!-----------------------------------------------------------------------
!
IF (rh < 0.75) THEN
rh_to_cldcv = 0.0
ELSE
rh_to_cldcv = 16.*(rh - 0.75)*(rh - 0.75)
END IF
ELSE
!
!-----------------------------------------------------------------------
!
! A modified version of the sqrt relationship between
! relative humidity and cloud fractional cover used in Eta model.
!
!-----------------------------------------------------------------------
!
IF (hgt < 600.) THEN
rh0 = 0.8
ELSE
rh0 = 0.75
END IF
IF (rh < rh0) THEN
rh_to_cldcv = 0.0
ELSE
rh_to_cldcv = 1.0 - SQRT((1.0 - rh)/(1.0 - rh0))
END IF
END IF
RETURN
END FUNCTION rh_to_cldcv