!
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE RETRPTPR ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE retrptpr(nx,ny,nz,x,y,z,zp, & 1,5
u,v,w,ptprt,pprt,qv,qc,qr,qi,qs,qh, &
ubar,vbar,ptbar,pbar,rhostr,qvbar, &
uforce,vforce,wforce,j1,j2,j3, &
tem1,tem2,tem3,tem4,tem5,tem6,tem7, &
pc,tem9,flag,tem11)
!
!--------------------------------------------------------------------------
!
! PURPOSE:
!
! This subroutine is the driver for a modified version of the Gal-Chen/
! Hane thermodynamic recovery. This technique derives the perturbation
! pressure and perturbation potential temperature fields at time t from
! distributions of u, v and w at three consecutive times: t-dtbig, t and
! t+dtbig. The technique was originally described in:
!
! Gal-Chen, T., 1978: A method for the initialization of the
! the anelastic equations: Implications for matching models with
! observations, Mon. Wea. Rev., 587-606;
!
! Hane, C. E., and B. C. Scott, 1978: Temperature and pressure
! perturbations within convective clouds derived from detailed
! air motion information: Preliminary testing. Mon. Wea. Rev.,
! 654-661.
!
! The main difference between this recovery and the conventional
! Gal-Chen/Hane scheme is that we make provision for the presence of
! the perturbation pressure in the buoyancy term in the vertical
! equation of motion.
!
! IMPORTANT NOTICE: The results of the recovery are stored in the
! arrays tem1 (ptprt) and tem2 (pprt). The original pprt and ptprt
! fields are unchanged. Results are provided at every computational
! point but the user is required to ensure that the boundary conditions
! are consistent with their run. The ARPS subroutine assimptpr, serving
! as a driver for this subroutine can take care of that.
!
!---------------------------------------------------------------------------
!
! AUTHORS: Alan Shapiro and Steve Lazarus
! 2/16/93.
!
! MODIFICATION HISTORY:
! 04/15/93 (Keith Brewster)
! Results stored in arrays tem1 (ptprt) and tem2 (pprt).
!
! 03/15/96 (Limin Zhao)
! Added the code to read radar data to flag retrieval
! temperature and pressure fields.
!
! 04/23/96 (Limin Zhao and Alan Shapiro)
! Modified the code to hole-fill force terms in data void area
! instead of using hole-filled velocity values.
!
! 06/18/96 (Limin Zhao and Alan Shapiro)
! Added an option for using Dirichlet boundary conditions
! for pressure solver.
!
!-----------------------------------------------------------------------
!
! 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)
!
! 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)
!
! u x component of velocity (m/s)
! v y component of velocity (m/s)
! w z component of velocity (m/s)
!
! ptprt Model's perturbation potential temperature (K)
! pprt Model's perturbation pressure (Pascal)
! qv Model's water vapor specific humidity (kg/kg)
! qc Model's cloud water mixing ratio (kg/kg)
! qr Model's rain water mixing ratio (kg/kg)
! qi Cloud ice mixing ratio (kg/kg)
! qs Snow mixing ratio (kg/kg)
! qh Hail mixing ratio (kg/kg)
!
! ubar Base state x velocity component (m/s)
! vbar Base state y velocity component (m/s)
! ptbar Base state potential temperature (K)
! pbar Base state pressure (Pascal)
! rhostr Base state air density (kg/m**3) times j3
! qvbar Base state water vapor specific humidity (kg/kg)
!
! uforce Acoustically inactive forcing terms in the u-momentum
! equation (kg/(m*s)**2). uforce = -uadv + umix + ucorio
! vforce Acoustically inactive forcing terms in the v-momentum
! equation (kg/(m*s)**2). vforce = -vadv + vmix + vcorio
! wforce Acoustically inactive forcing terms in the w-momentum
! equation, except for buoyancy (kg/(m*s)**2).
! wforce = -wadv + wmix + wcorio
!
! j1 Coordinate transformation Jacobian -d(zp)/dx
! j2 Coordinate transformation Jacobian -d(zp)/dy
! j3 Coordinate transformation Jacobian d(zp)/dz
!
! OUTPUT:
!
! tem1 Recovered perturbation potential temperature (K)
! tem2 Recovered perturbation pressure (Pascal)
!
! WORK ARRAYS:
!
! tem3 Temporary work array.
! tem4 Temporary work array.
! tem5 Temporary work array.
! tem6 Temporary work array.
! tem7 Temporary work array.
! pc Temporary work array.
! tem9 Temporary work array.
!
! (These arrays are defined and used locally (i.e. inside this
! subroutine), they may also be passed into routines called by
! this one. Exiting the call to this subroutine, these temporary
! work arrays may be used for other purposes and therefore their
! contents may be overwritten. Please examine the usage of work
! arrays before you alter the code.)
!
!-----------------------------------------------------------------------
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE ! Force explicit declarations
INTEGER :: isrc ! Flag indicating source of calling routine.
INTEGER :: nt ! Number of time levels of time-dependent arrays.
INTEGER :: tpast ! Index of time level for the past time.
INTEGER :: tpresent ! Index of time level for the present time.
INTEGER :: tfuture ! Index of time level for the future time.
PARAMETER (nt=3, tpast=1, tpresent=2, tfuture=3)
INTEGER :: nx,ny,nz ! Number of grid points in x, y, z directions
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 :: u(nx,ny,nz,nt) ! x component of velocity (m/s)
REAL :: v(nx,ny,nz,nt) ! y component of velocity (m/s)
REAL :: w(nx,ny,nz,nt) ! z component of 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 :: ubar (nx,ny,nz) ! Base state u-velocity (m/s)
REAL :: vbar (nx,ny,nz) ! Base state v-velocity (m/s)
REAL :: ptbar (nx,ny,nz) ! Base state potential temperature (K)
REAL :: pbar (nx,ny,nz) ! Base state pressure (Pascal).
REAL :: rhostr(nx,ny,nz) ! Base state air density (kg/m**3) times j3
REAL :: qvbar (nx,ny,nz) ! Base state water vapor specific humidity (kg/kg)
REAL :: uforce(nx,ny,nz) ! Acoustically inactive forcing terms
! in u-momentum equation (kg/(m*s)**2)
! uforce= -uadv + umix + ucorio
REAL :: vforce(nx,ny,nz) ! Acoustically inactive forcing terms
! in v-momentum equation (kg/(m*s)**2)
! vforce= -vadv + vmix + vcorio
REAL :: wforce(nx,ny,nz) ! Acoustically inactive forcing terms
! in w-momentum equation (kg/(m*s)**2)
! wforce= -wadv + wmix
REAL :: j1 (nx,ny,nz) ! Coordinate transformation Jacobian -d(zp)/d(x)
REAL :: j2 (nx,ny,nz) ! Coordinate transformation Jacobian -d(zp)/d(y)
REAL :: j3 (nx,ny,nz) ! Coordinate transformation Jacobian d(zp)/d(z)
INTEGER :: nn
PARAMETER (nn=500) ! Dimension of the a(z), b(z) and f(z)
! variables. nz should be < nn.
REAL :: f(nn) ! Vertical structure function for the
! recovered perturbation pressure,
! pprt = solution of Poisson equation + f(z)
REAL :: a(nn) ! Coefficient a(z) in the ordinary differential
! equation for f(z): df/dz + a(z)f + b(z) = 0.
REAL :: b(nn) ! Coefficient b(z) in the ordinary differential
! equation for f(z): df/dz + a(z)f + b(z) = 0.
REAL :: pc(nx,ny,nz) ! a variable related to perturbation pressure,
! the solution of a Poisson equation.
REAL :: f0 ! Constant of integration for f(z): f0=f(dz/2)
REAL :: tem1 (nx,ny,nz) ! Temporary work array.
REAL :: tem2 (nx,ny,nz) ! Temporary work array.
REAL :: tem3 (nx,ny,nz) ! Temporary work array.
REAL :: tem4 (nx,ny,nz) ! Temporary work array.
REAL :: tem5 (nx,ny,nz) ! Temporary work array.
REAL :: tem6 (nx,ny,nz) ! Temporary work array.
REAL :: tem7 (nx,ny,nz) ! Temporary work array.
REAL :: tem9 (nx,ny,nz) ! Temporary work array.
REAL :: flag (nx,ny,nz) ! Temporary work array.
REAL :: tem11 (nx,ny,nz) ! Temporary work array.
!
!-----------------------------------------------------------------------
!
! Misc. local variables:
!
!-----------------------------------------------------------------------
!
INTEGER :: i,j,k
INTEGER :: tlevel
INTEGER :: ic ! Counter, used for reading input data
SAVE ic
DATA ic/1/
INTEGER :: istat ! Error flag for reading input data
REAL :: dtinv ! Reciprocal of dtbig
REAL :: rdenom ! Reciprocal number of grid points on a horizontal sfc.
REAL :: dudt ! Time rate of change of rhostr*u
REAL :: dvdt ! Time rate of change of rhostr*v
REAL :: dwdt ! Time rate of change of rhostr*w
REAL :: dpdz ! Vertical derivative of pc
REAL :: wfave ! Vertical average of wforce - dwdt
REAL :: bave ! Vertical average of individual terms comprising b(z)
REAL :: b1, b2, b3, b4, b5 ! Individual terms comprising b(z).
REAL :: term1(nn), term2(nn) ! 1-D temporary arrays for use in RETRFZ
REAL :: assimtim(100) ! Time of data input files
REAL :: ptol
INTEGER :: icount
REAL :: pzng,ptzng,tzng,qvszng,rhzng,dqvsdpt,faczng
REAL :: corr,pterr
INTEGER :: iter,itermax, k1
REAL :: ubig,vbig
!
!-----------------------------------------------------------------------
!
! Include files:
!
!-----------------------------------------------------------------------
!
INCLUDE 'globcst.inc' ! Global constants that control model
INCLUDE 'assim.inc' ! Velocity insertion/thermodynamic
INCLUDE 'phycst.inc' ! Physical constants
INCLUDE 'grid.inc'
!
!-----------------------------------------------------------------------
!
! Routines called:
!
!-----------------------------------------------------------------------
!
EXTERNAL uvwrho
EXTERNAL retrpois
EXTERNAL retrfz
EXTERNAL retrchk
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
IF (recovopt == 0) RETURN
IF (irecov == 0) RETURN
IF (nz > nn) THEN
PRINT *, 'Warning from assimthermo: nz .gt.', nn
PRINT*, 'please reset nn'
END IF
!
!-----------------------------------------------------------------------
!
! Calculate rhostr*u, rhostr*v and rhostr*w at two time levels: tpast
! and tfuture. Store the results in temporary arrays.
!
!-----------------------------------------------------------------------
!
!
!===> Use SDVR winds local time change
!
tlevel = tpast
CALL uvwrho
(nx,ny,nz, &
u(1,1,1,tlevel),v(1,1,1,tlevel),w(1,1,1,tlevel), &
rhostr,tem1,tem2,tem3)
tlevel = tfuture
CALL uvwrho
(nx,ny,nz, &
u(1,1,1,tlevel),v(1,1,1,tlevel),w(1,1,1,tlevel), &
rhostr,tem5,tem6,tem7)
!
!===> for turbulence frozen assumption.
!
! tlevel = tpresent
!
! CALL uvwrho(nx,ny,nz,
! : u(1,1,1,tlevel),v(1,1,1,tlevel),w(1,1,1,tlevel),
! : rhostr,tem1,tem2,tem3)
!
!-----------------------------------------------------------------------
!
! Calculate the (local) time derivative of rhostr*u, rhostr*v and
! rhostr*w with a centered time difference. Subtract these time
! derivatives from uforce, vforce and wforce, and store the results
! in temporary arrays.
!
!-----------------------------------------------------------------------
!
! ubig = 8.3128 ! for 16:59Z
! vbig = - 10.9770
ubig = 7.9635 ! for 18:41Z
vbig = - 7.2613
dtinv = 0.5/dtbig
DO k=2,nz-2
DO j=2,ny-2
DO i=2,nx-1
!
!
dudt = dtinv*(tem5(i,j,k) - tem1(i,j,k)) ! SDVR wind
! dudt = 0.0 ! stationary
! dudt = -ubig*(tem1(i+1,j,k)-tem1(i-1,j,k))/(2.0*dx)
! : -vbig*(tem1(i,j+1,k)-tem1(i,j-1,k))/(2.0*dy) ! trb. frzn
uforce(i,j,k) = uforce(i,j,k) - dudt
END DO
END DO
END DO
DO k=2,nz-2
DO j=2,ny-1
DO i=2,nx-2
!
!
dvdt = dtinv*(tem6(i,j,k) - tem2(i,j,k)) ! SDVR wind
! dvdt = 0.0 ! stationary
! dvdt = -ubig*(tem2(i+1,j,k)-tem2(i-1,j,k))/(2.0*dx)
! : -vbig*(tem2(i,j+1,k)-tem2(i,j-1,k))/(2.0*dy) ! trb. frzn
vforce(i,j,k) = vforce(i,j,k) - dvdt
END DO
END DO
END DO
DO k=2,nz-1
DO j=2,ny-2
DO i=2,nx-2
!
!
dwdt = dtinv*(tem7(i,j,k) - tem3(i,j,k)) ! SDVR wind
! dwdt = 0.0 ! stationary
! dwdt = -ubig*(tem3(i+1,j,k)-tem3(i-1,j,k))/(2.0*dx)
! : -vbig*(tem3(i,j+1,k)-tem3(i,j-1,k))/(2.0*dy) ! trb. frzn
wforce(i,j,k) = wforce(i,j,k) - dwdt
END DO
END DO
END DO
DO k=1,nz
DO j=1,ny
DO i=1,nx
tem1(i,j,k) = 0.0
tem2(i,j,k) = 0.0
tem3(i,j,k) = 0.0
END DO
END DO
END DO
DO k=2,nz-2
DO j=2,ny-2
DO i=2,nx-1
tem1(i,j,k) = uforce(i,j,k)
END DO
END DO
END DO
DO k=2,nz-2
DO j=2,ny-1
DO i=2,nx-2
tem2(i,j,k) = vforce(i,j,k)
END DO
END DO
END DO
DO k=2,nz-1
DO j=2,ny-2
DO i=2,nx-2
tem3(i,j,k) = wforce(i,j,k)
END DO
END DO
END DO
!
!----------------------------------------------------------------------------
!
! Check if it is needed to use the hole-filled values in data void area.
! itest=1, use the hole-filled A & B values.
! =0, use the calculated values from hole-filled wind fields.
!
! Note: The resultes are good for itest=1 and A & B are are set to zero
!
!---------------------------------------------------------------------------
!
!ccxxx
!
IF(itest == 0) GO TO 911
ptol = .001
icount = 0
DO k= 1,nz-1
DO j= 1,ny-1
DO i= 1,nx
tem6(i,j,k) = 0.0
tem7(i,j,k) = 0.0
tem9(i,j,k) = 0.0
IF(flag(i,j,k) /= spval) THEN
tem11(i,j,k) = tem1(i,j,k)
!ccxxx ELSE IF(i.le.1.or.i.ge.nx-1.or.j.eq.1.or.j.eq.ny-1) THEN
!ccxxx tem11(i,j,k) = tem1(i,j,k)
!ccxxx tem11(i,j,k) = 0.0
!ccxxx tem5(i,j,k) = 0.0
ELSE
tem11(i,j,k) =0.0
!ccxxx tem11(i,j,k) = spval
tem5(i,j,k) = spval
icount = icount + 1
END IF
END DO
END DO
END DO
PRINT *,'No call to POIS3D to fill A, A=0 outside wind area'
!ccxxxprint *,'On call to POIS3D, there are ',icount,' filled A values'
!ccxxxCALL POIS3D(nx,ny,nz,dx,dy,dz,ptol,3.0,tem6,tem5,tem11,tem7,tem9)
DO k=1,nz-1
DO j=1,ny-1
DO i=1,nx
tem1(i,j,k) = tem11(i,j,k)
END DO
END DO
END DO
icount = 0
DO k= 1,nz-1
DO j= 1,ny
DO i= 1,nx-1
tem6(i,j,k) = 0.0
tem7(i,j,k) = 0.0
IF(flag(i,j,k) /= spval) THEN
tem11(i,j,k) = tem2(i,j,k)
!ccxxx ELSE IF(i.le.1.or.i.ge.nx-1.or.j.eq.1.or.j.eq.ny-1) THEN
!ccxxx tem11(i,j,k) = tem2(i,j,k)
!ccxxx tem11(i,j,k) = 0.0
!ccxxx tem5(i,j,k) = 0.0
ELSE
tem11(i,j,k) =0.0
!ccxxx tem11(i,j,k) = spval
tem5(i,j,k) = spval
icount = icount + 1
END IF
END DO
END DO
END DO
PRINT *,'No call to POIS3D to fill A, A=0 outside wind area'
!ccxxxprint *,'On call to POIS3D, there are ',icount,' filled B values'
!ccxxxCALL POIS3D(nx,ny,nz,dx,dy,dz,ptol,3.0,tem6,tem5,tem11,tem7,tem9)
DO k=1,nz-1
DO j=1,ny
DO i=1,nx-1
tem2(i,j,k) = tem11(i,j,k)
END DO
END DO
END DO
911 CONTINUE
!
!----------------------------------------------------------------------------
!
! Compute the right hand side of the Poisson equation and store it in
! tem4. Recall that tem1 = uforce - dudt; tem2 = vforce - dvdt. The
! right hand side is dtem1/dx + dtem2/dy.
!
!----------------------------------------------------------------------------
!
DO k = 2, nz-2
DO j = 2, ny-2
DO i = 2, nx-2
tem4(i,j,k) = dxinv*(tem1(i+1,j,k) - tem1(i,j,k)) + &
dyinv*(tem2(i,j+1,k) - tem2(i,j,k))
END DO
END DO
END DO
!
!----------------------------------------------------------------------------
!
! Solve the two-dimensional (x-y) Poisson Equation for the variable pc:
!
! d2pc/dx2 + d2pc/dy2 = dtem1/dx + dtem2/dy
!
!
! with Neumann boundary conditions:
!
! dpc/dx = tem1 on x faces
! dpc/dy = tem2 on y faces
!
! Recall that tem1 = uforce - dudt; tem2 = vforce - dvdt
!
! pc differs from the perturbation pressure, pprt, by an arbitrary
! function of height; that is, pprt = pc + f(z)
!
!----------------------------------------------------------------------------
!
tlevel = tpresent
DO i = 1, nx
DO j = 1, ny
!ccxxx pc(i,j,1) = 0. ! First guess of pc(i,j,1) is 0
pc(i,j,1) = pprt(i,j,1,tlevel)
END DO
END DO
DO k=1,nz
DO j=1,ny
DO i=1,nx
tem6(i,j,k) = pprt(i,j,k,tlevel)
END DO
END DO
END DO
DO k = 2, nz-2
DO i = 1, nx
DO j = 1, ny
!ccxxx pc(i,j,k) = pc(i,j,k-1) ! First guess of pc(i,j,k) is pc(i,j,k-1)
pc(i,j,k) = pprt(i,j,k,tlevel)
END DO
END DO
CALL retrpois
(nx,ny,nz,k, &
tem1,tem2,pc, &
tem4,tem5(1,1,1),tem5(1,1,2),tem5(1,1,3), &
tem5(1,1,4),tem6)
END DO
!
!----------------------------------------------------------------------------
!
! Check how well the retrieved pressure gradients fit the individual
! momentum equations.
!
!----------------------------------------------------------------------------
!
CALL retrchk
(nx,ny,nz,tem1,tem2,pc)
!
!----------------------------------------------------------------------------
!
! Calculate the coefficients a(z) and b(z) appearing in the ordinary
! differential equation for f(z): df/dz + a(z)f + b(z) = 0.
!
! a = rhostr*g/(pbar*cpdcv)
!
! b = horizontal average of (dpc/dz + a*pc - rhostr*g*ptpert/ptbar - tem3),
!
! where tem3 = wforce - dwdt.
!
! In the evaluation of the analytic solution for f(z), it is convenient
! to define the a(z) coefficient at scalar points and the b(z) coefficient
! at w points.
!
! Use bc_opt to control what kind of boundary will be used.
! bc_opt = 1, use Neumann boundary.
! = 0, use Dirichlet boundary.
!
!----------------------------------------------------------------------------
!
!ccxxx
IF (bc_opt == 0) GO TO 9119
tlevel = tpresent
rdenom = 1./((nx-3)*(ny-3))
DO k = 3, nz-2
a(k) = 0.
b1 = 0.
b2 = 0.
b3 = 0.
b4 = 0.
b5 = 0.
DO j = 2, ny-2
DO i = 2, nx-2
a(k) = a(k) + rhostr(i,j,k)*g/(pbar(i,j,k)*cpdcv)
b1 = b1 + dzinv*(pc(i,j,k) - pc(i,j,k-1))
bave = 0.5*(rhostr(i,j,k) *pc(i,j,k) /pbar(i,j,k) + &
rhostr(i,j,k-1)*pc(i,j,k-1)/pbar(i,j,k-1))
b2 = b2 + bave
bave = 0.5*(rhostr(i,j,k)*ptprt(i,j,k,tlevel)/ptbar(i,j,k) + &
rhostr(i,j,k-1)*ptprt(i,j,k-1,tlevel)/ptbar(i,j,k-1))
b3 = b3 + bave
b4 = b4 + tem3(i,j,k)
bave = 0.5*(rhostr(i,j,k)*qc(i,j,k,tlevel) + &
rhostr(i,j,k-1)*qc(i,j,k-1,tlevel) ) + &
0.5*(rhostr(i,j,k)*qr(i,j,k,tlevel) + &
rhostr(i,j,k-1)*qr(i,j,k-1,tlevel) ) - &
0.608*0.5*(rhostr(i,j,k)*(qv(i,j,k,tlevel)-qvbar(i,j,k)) + &
rhostr(i,j,k-1)*(qv(i,j,k-1,tlevel)-qvbar(i,j,k)))
b5 = b5 + bave
END DO
END DO
a(k) = a(k)*rdenom
b(k) = (b1 + g*b2/cpdcv - g*b3 - b4 + g*b5)*rdenom
END DO
!
!----------------------------------------------------------------------------
!
! Calculate the constant of integration for f(z) by equating the horizontal
! average of the recovered pprt to the model's pprt at the first scalar
! level above the lower boundary (the lowest level at which we have pc);
! that is, at z = dz/2. The constant of integration is then given by:
!
! f0 = horizontal average of (model's pprt - pc)
!
!----------------------------------------------------------------------------
!
f0 = 0.
DO i = 2, nx-2
DO j = 2, ny-2
f0 = f0 + pprt(i,j,2,tlevel) - pc(i,j,2)
END DO
END DO
f0 = f0*rdenom
!
!----------------------------------------------------------------------------
!
! Evaluate the analytic solution of the ordinary differential equation
! df/dz + a(z)f + b(z) = 0. The general solution is (cf Braun, 1975:
! Differential Equations and Their Applications):
!
! f(z) = exp(-integral(a(z))) * [f(0) - integral(b*exp(+integral(a)))]
!
! The lower limit of the integration is the first scalar grid point
! above the lower physical boundary; that is, at z = dz/2 (k=2).
!
!----------------------------------------------------------------------------
!
CALL retrfz
(nz,nn,f0,a,b,f,term1,term2)
!
!----------------------------------------------------------------------------
!
! Recover the perturbation pressure from: pprt = pc + f(z).
! Results are stored in tem2.
!
!----------------------------------------------------------------------------
!
!
9119 CONTINUE
!ccxxx
DO k=2,nz-2
DO j=1,ny-1
DO i=1,nx-1
IF (bc_opt /= 0) THEN
tem2(i,j,k) = pc(i,j,k) + f(k)
ELSE
tem2(i,j,k) = pc(i,j,k)
END IF
END DO
END DO
END DO
!
!----------------------------------------------------------------------------
! Options for estimate the perturbation pressure at the lowest level :
!
! ig=0
! To estimate the perturbation pressure tem2 at k = 1 and k = nz-1, use
! the first three terms of a Taylor series expansion of tem2 about k=3
! and k=nz-3, respectively.
!
! ig=1
! Use the zero gradient boundary conditions.
!
!----------------------------------------------------------------------------
!ccxxx
!
DO j=2,ny-2
DO i=2,nx-2
IF(ig == 0) THEN
k=1
tem2(i,j,k) = 3.0*tem2(i,j,k+1) &
-3.0*tem2(i,j,k+2) + tem2(i,j,k+3)
k=nz-1
tem2(i,j,k) = 3.0*tem2(i,j,k-1) &
-3.0*tem2(i,j,k-2) + tem2(i,j,k-3)
ELSE
tem2(i,j,1) = tem2(i,j,2)
tem2(i,j,nz-1) = tem2(i,j,nz-2)
END IF
END DO
END DO
!
!----------------------------------------------------------------------------
!
! Recover the perturbation potential temperature, tem1, from the vertical
! equation of motion as a residual. When approximating dpdz, use
! centered differences over 2 dz intervals.
!
! Note: since wforce (and hence tem3) is only known for i between 2
! and nx-2, and for j between 2 and ny-2 we can't recover tem1 on
! i=1 or i=nx-1 or j=1 or j=ny-1. To get tem1 on these boundaries, we
! must impose the model's boundary conditions (but we don't do it in this
! subroutine).
!
!----------------------------------------------------------------------------
!
itermax = 0
pterr = 0.01 ! tolerence in pt iteration
DO k=2,nz-2
DO j=2,ny-2
DO i=2,nx-2
dpdz = 0.5*dzinv*(tem2(i,j,k+1) - tem2(i,j,k-1))
wfave = 0.5*(tem3(i,j,k+1) + tem3(i,j,k))
!
!
! qc(i,j,k,tlevel) = 0.0
! qr(i,j,k,tlevel) = qr(i,j,k,tlevel) ! same
!cc qr(i,j,k,tlevel) = 0.7 * qr(i,j,k,tlevel) ! Kelvin's suggestion
! qr(i,j,k,tlevel) = 0.0 ! exclude qr effect
! qi(i,j,k,tlevel) = 0.0
! qs(i,j,k,tlevel) = 0.0
! qh(i,j,k,tlevel) = 0.0
!
!
! ==> Original form
!
tem1(i,j,k) = ptbar(i,j,k) * &
((-wfave + dpdz)/(rhostr(i,j,k)*g) + &
tem2(i,j,k)/(cpdcv*pbar(i,j,k)) &
+ qc(i,j,k,tlevel) + qr(i,j,k,tlevel) &
- 0.608*(qv(i,j,k,tlevel) - qvbar(i,j,k)) )
!
!
! tem1(i,j,k) = ptbar(i,j,k) *
! : ( (-wfave + dpdz)/(rhostr(i,j,k)*g) +
! : tem2(i,j,k)/(cpdcv*pbar(i,j,k))
! : + ( qc(i,j,k,tlevel) + qr(i,j,k,tlevel)
! : - (1.0-rddrv)*(qv(i,j,k,tlevel)-qvbar(i,j,k))
! : /(rddrv+qvbar(i,j,k)) ) / (1.0+qvbar(i,j,k)) )
!
!#### Scenario No. 1: use new scheme.
!
! ==> New scheme for properly hanling inclusion of qv in retrieving
! ptprt. Assuming RH unchanged before & after the retrival.
!
! Change to use Newton iteration method. 3-28-98
!
!**** Calculate RH using original p (NOT tem2), pt & qv.
!
! pzng = pbar(i,j,k) + pprt(i,j,k,tlevel)
! ptzng = ptbar(i,j,k) + ptprt(i,j,k,tlevel)
! tzng = ptzng * (1.0e-5*pzng)**rddcp
! qvszng = (380./pzng)*exp( 17.27*(tzng-273.15)/(tzng-35.86) )
! rhzng = qv(i,j,k,tlevel) / qvszng
!
!+++++++++ begin change of subcloud RH
!
! if(k.ge.2 .and. k.le.5) then ! change only made from k=2 to 5
! do k1=2,nz-2
! if(qr(i,j,k1,tlevel) .gt. 0.5e-3) then ! qr > 0.5 g/kg
!c rhzng = rhzng + 0.15 ! increase/decrease by 15%
! rhzng = rhzng - 0.15 ! increase/decrease by 15%
! if(rhzng.lt.0.) rhzng=0.
! if(rhzng.gt.1.) rhzng=1.
! endif
! enddo
! endif
!+++++++++ end of change of subcloud RH
!
!**** Calculate qvs and d(qvs)/d(pt) at ptbar & new p.
!
! iter = 0
! tem1(i,j,k) = ptprt(i,j,k,tlevel) ! initial guess of tem1
!666 continue
! pzng = pbar(i,j,k) + tem2(i,j,k)
! ptzng = ptbar(i,j,k) + tem1(i,j,k)
! tzng = ptzng * (1.0e-5*pzng)**rddcp
! qvszng = (380./pzng)*exp( 17.27*(tzng-273.15)/(tzng-35.86) )
! dqvsdpt = qvszng * (1.0e-5*pzng)**rddcp
! : * 4097.9983/(tzng-35.86)**2
! faczng = 1.0 + 0.608*rhzng*dqvsdpt*ptbar(i,j,k)
!
!**** calculate new ptprt.
!
! corr = tem1(i,j,k) -
! : ptbar(i,j,k) * ( (-wfave + dpdz)/(rhostr(i,j,k)*g) +
! : tem2(i,j,k)/(cpdcv*pbar(i,j,k))
! : + qc(i,j,k,tlevel) + qr(i,j,k,tlevel)
! : - 0.608*(rhzng*qvszng - qvbar(i,j,k)) )
! corr = corr / faczng
! if( abs(corr) .ge. pterr ) then
! iter = iter + 1
! tem1(i,j,k) = tem1(i,j,k) - corr
! goto 666
! endif
! if( iter .gt. itermax ) itermax = iter
!
!**** Update qv using tem1 & tem2, and initializing qc,qi,qs,qh.
! Note: BC of retrieved pt' & p' will be applied afterwards
! in assimptpr.f, but no such an application for qv etc.
! So we just assume here that boundary values of qv, qc, ...
! are the same as what they were.
!
! qv(i,j,k,tlevel) = rhzng * qvszng
! qc(i,j,k,tlevel) = 0.0
! qr(i,j,k,tlevel) = qr(i,j,k,tlevel) ! same
! qr(i,j,k,tlevel) = 0.0
! qi(i,j,k,tlevel) = 0.0
! qs(i,j,k,tlevel) = 0.0
! qh(i,j,k,tlevel) = 0.0
!
!
!#### Scenario No. 2: totally don't consider qv in getting ptprt.
!
! tem1(i,j,k) = ptbar(i,j,k) *
! : ( (-wfave + dpdz)/(rhostr(i,j,k)*g) +
! : tem2(i,j,k)/(cpdcv*pbar(i,j,k))
! : + qc(i,j,k,tlevel) + qr(i,j,k,tlevel) )
!
END DO
END DO
END DO
! write(6,*) ' information about ptprt retrieval via iteration:'
! write(6,*) ' itermax, pterr=',itermax, pterr
!
!
!----------------------------------------------------------------------------
! Options for estimate the perturbation temperature at the lowest level :
!
! ig=0
! To estimate the perturbation temperature tem1 at k = 1 and k = nz-1, use
! the first three terms of a Taylor series expansion of tem1 about k=3
! and k=nz-3, respectively.
!
! ig=1
! Use the zero gradient boundary conditions.
!
!----------------------------------------------------------------------------
!
!ccxxx
DO j=2,ny-2
DO i=2,nx-2
IF(ig == 0) THEN
k=1
tem1(i,j,k) = 3.0*tem1(i,j,k+1) &
-3.0*tem1(i,j,k+2) + tem1(i,j,k+3)
k=nz-1
tem1(i,j,k) = 3.0*tem1(i,j,k-1) &
-3.0*tem1(i,j,k-2) + tem1(i,j,k-3)
ELSE
tem1(i,j,1) = tem1(i,j,2)
tem1(i,j,nz-1) = tem1(i,j,nz-2)
END IF
END DO
END DO
RETURN
END SUBROUTINE retrptpr