! ! !################################################################## !################################################################## !###### ###### !###### 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