! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE SOLVUV ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE solvuv(mptr, nx,ny,nz, exbcbufsz, dtsml1, curtsml, & 1,43 u,v,wcont,pprt, & udteb,udtwb,udtnb,udtsb, & vdteb,vdtwb,vdtnb,vdtsb, & rhostr, uforce,vforce,ubar,vbar, & x,y,z,zp, mapfct, j1,j2,j3,j3inv, & exbcbuf,rhofct, & rhostru,rhostrv,rhostrw,dtmrxrsu,dtmryrsv,wpgrad, & upgrad,vpgrad,tem1,tem2,tem3) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Coordinate the time stepping of u and v momentum equations and the ! setting of boundary conditions. ! !----------------------------------------------------------------------- ! ! ! AUTHOR: Ming Xue ! 10/10/92 ! ! MODIFICATION HISTORY: ! ! 5/20/92 (K. Droegemeier and M. Xue) ! Added full documentation. ! ! 6/07/92 ( M. Xue) ! Now only tfuture fields of u, v, w and pprt are passed in. ! ! 2/10/93 (K. Droegemeier) ! Cleaned up documentation. ! ! 4/10/93 (M. Xue & Hao Jin) ! Add the terrain. ! ! 9/1/94 (Y. Lu) ! Cleaned up documentation. ! ! 1/25/96 (Donghai Wang & Yuhe Liu) ! Added the map projection factor to ARPS governing equations. ! ! 10/16/97 (Donghai Wang) ! Using total density (rho) for the calculation of the pressure ! gradient force terms. ! ! 11/06/97 (Dan Weber) ! Added three additional levels to the mapfct array. The three ! levels (4,5,6) represent the inverse of the first three in order. ! The inverse map factors are computed to improve efficiency. ! ! 9/28/98 (Dan Weber) ! Reformulated do-loops to improve efficiency, brought in ! pre-computed variables. Note u,vforce contains dtsml and ! 1/rhostru,v. ! ! 07/23/2001 (K. Brewster) ! Added mptr to argument list. ! Added optional writing of total divergence as a diagnostic noise ! parameter. ! !----------------------------------------------------------------------- ! ! INPUT : ! ! nx Number of grid points in the x-direction (east/west) ! ny Number of grid points in the y-direction (north/south) ! nz Number of grid points in the vertical ! dtsml1 Local value of small time step size ! curtsml Local curttim at a small time step ! ! u x component of velocity at tfuture (m/s) ! v y component of velocity at tfuture (m/s) ! wcont Contravariant vertical velocity (m/s) ! ! pprt Perturbation pressure at tfuture (Pascal) ! ! udteb Time tendency of the u field at the east boundary ! udtwb Time tendency of the u field at the west boundary ! udtnb Time tendency of the u field at the north boundary ! udtsb Time tendency of the u field at the south boundary ! ! vdteb Time tendency of the v field at the east boundary ! vdtwb Time tendency of the v field at the west boundary ! vdtnb Time tendency of the v field at the north boundary ! vdtsb Time tendency of the v field at the south boundary ! ! rhostr Base state density rhobar times j3 (kg/m**3) ! ! uforce Acoustically inactive forcing terms in u-eq. ! (kg/(m*s)**2) ! vforce Acoustically inactive forcing terms in v-eq. ! (kg/(m*s)**2) ! ! ubar Base state x velocity component (m/s) ! vbar Base state y velocity component (m/s) ! ! 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) ! ! mapfct Map factors at scalar, u and v points ! ! j1 Coordinate transformation Jacobian -d(zp)/dx ! j2 Coordinate transformation Jacobian -d(zp)/dy ! j3 Coordinate transformation Jacobian d(zp)/dz ! j3inv Inverse of j3 ! ! rhostru Average rhostr at u points (kg/m**3). ! rhostrv Average rhostr at v points (kg/m**3). ! rhostrw Average rhostr at w points (kg/m**3). ! ! OUTPUT: ! ! u x component of velocity at time tfuture updated ! in time by dtsml1 (m/s) ! v y component of velocity at time tfuture updated ! in time by dtsml1 (m/s) ! w Vertical component of Cartesian velocity at tfuture ! updated in time by dtsml1 (m/s) ! wpgrad Pressure gradient term in w-eq. (kg/(m*s)**2) ! ! WORK ARRAYS: ! ! upgrad Pressure gradient term in u-eq. (kg/(m*s)**2) ! vpgrad Pressure gradient term in v-eq. (kg/(m*s)**2) ! tem1 Temporary work array ! tem2 Temporary work array ! tem3 Temporary work array ! dtmrxrsu dtsml*mapfct*avgx(rhofct)/rhostru ! dtmryrsv dtsml*mapfct*avgy(rhofct)/rhostrv ! !----------------------------------------------------------------------- ! ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! Force explicit declarations INTEGER :: mptr INTEGER :: nx, ny, nz ! Number of grid points in 3 directions REAL :: u (nx,ny,nz) ! u-velocity at tfuture (m/s) REAL :: v (nx,ny,nz) ! v-velocity at tfuture (m/s) REAL :: wcont (nx,ny,nz) ! Contravariant vertical velocity (m/s) REAL :: pprt (nx,ny,nz) ! Perturbation pressure at tfuture ! (Pascal) REAL :: udteb (ny,nz) ! Time tendency of u at east boundary REAL :: udtwb (ny,nz) ! Time tendency of u at west boundary REAL :: udtnb (nx,nz) ! Time tendency of u at north boundary REAL :: udtsb (nx,nz) ! Time tendency of u at south boundary REAL :: vdteb (ny,nz) ! Time tendency of v at east boundary REAL :: vdtwb (ny,nz) ! Time tendency of v at west boundary REAL :: vdtnb (nx,nz) ! Time tendency of v at north boundary REAL :: vdtsb (nx,nz) ! Time tendency of v at south boundary REAL :: rhostr(nx,ny,nz) ! Base state density rhobar times j3. REAL :: uforce(nx,ny,nz) ! Acoustically inactive forcing terms ! in u-momentum equation (kg/(m*s)**2) REAL :: vforce(nx,ny,nz) ! Acoustically inactive forcing terms ! in v-momentum equation (kg/(m*s)**2) REAL :: ubar(nx,ny,nz) REAL :: vbar(nx,ny,nz) REAL :: x (nx) ! x-coord. of the physical and compu- ! tational grid. Defined at u-point. REAL :: y (ny) ! y-coord. of the physical and compui- ! tational grid. Defined at v-point. REAL :: z (nz) ! z-coord. of the computational grid. ! Defined at w-point on the staggered ! grid. REAL :: zp (nx,ny,nz) ! Physical height coordinate defined at ! w-point of the staggered grid. REAL :: mapfct(nx,ny,8) ! Map factors at scalar, u and v points REAL :: j1 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as - d( zp )/d( x ). REAL :: j2 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as - d( zp )/d( y ). REAL :: j3 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as d( zp )/d( z ). REAL :: j3inv (nx,ny,nz) ! Inverse of j3 INTEGER :: exbcbufsz ! EXBC buffer size REAL :: exbcbuf( exbcbufsz ) ! EXBC buffer array REAL :: rhofct(nx,ny,nz) ! rho-factor: rhobar/rho REAL :: rhostru(nx,ny,nz) ! Averaged rhostr at u points (kg/m**3). REAL :: rhostrv(nx,ny,nz) ! Averaged rhostr at v points (kg/m**3). REAL :: rhostrw(nx,ny,nz) ! Averaged rhostr at w points (kg/m**3). REAL :: wpgrad(nx,ny,nz) ! Pressure gradient term in w-eq. ! !----------------------------------------------------------------------- ! ! Temporary WORK ARRAYS: ! !----------------------------------------------------------------------- ! REAL :: upgrad(nx,ny,nz) ! Pressure gradient term in u-eq. REAL :: vpgrad(nx,ny,nz) ! Pressure gradient term in v-eq. 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 :: dtmrxrsu(nx,ny,nz) ! dtsml*map*avgx(rhofct)/rhostru REAL :: dtmryrsv(nx,ny,nz) ! dtsml*map*avgy(rhofct)/rhostrv ! !----------------------------------------------------------------------- ! ! Misc. local variables: ! !----------------------------------------------------------------------- ! REAL :: curtsml ! Local curttim at a small time step REAL :: dtsml1 ! Local small time step REAL :: sumdiv INTEGER :: i, j, k INTEGER :: istart,iend,jstart,jend INTEGER :: ebc1,wbc1,nbc1,sbc1 ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'globcst.inc' INCLUDE 'grid.inc' ! Grid & map parameters. INCLUDE 'bndry.inc' INCLUDE 'exbc.inc' INCLUDE 'mp.inc' ! Message passing parameters. INTEGER :: noisewrt INTEGER :: ncalls(mgrdmax), nchdiv1(mgrdmax) CHARACTER (LEN=128 ) :: divfn INTEGER :: ldivfn,istat INTEGER :: mptag SAVE ncalls,nchdiv1 DATA ncalls /mgrdmax*0/ ! !----------------------------------------------------------------------- ! ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! noisewrt=0 ncalls(mptr)=ncalls(mptr) + 1 IF(noisewrt == 1 .AND. ncalls(mptr) == 1 ) THEN divfn = runname(1:lfnkey)//'.absdiv' ldivfn = 7 + lfnkey IF(nestgrd == 1) THEN WRITE(divfn((ldivfn+1):(ldivfn+4)),'(a,i2.2)')'.g',mptr ldivfn = ldivfn + 4 END IF WRITE(6,'(1x,a,a,a/,1x,a)') & 'Check to see if file ',divfn(1:ldivfn),' already exists.', & 'If so, append a version number to the filename.' CALL fnversn( divfn, ldivfn ) CALL getunit ( nchdiv1(mptr) ) OPEN(nchdiv1(mptr),FORM='formatted',STATUS='new', & FILE=divfn(1:ldivfn),IOSTAT=istat) IF( istat /= 0) THEN WRITE(6,'(/a,i2,/a/)') & ' Error occured when opening file '//divfn(1:ldivfn)// & ' using FORTRAN unit ',nchdiv1(mptr), & ' Program stopped in MAXMIN.' CALL arpsstop(' ',1) END IF WRITE(nchdiv1(mptr),'(a)') runname WRITE(nchdiv1(mptr),'(t2,a,t15,a)') 'Time_(s)','MnAbsDiv' END IF !----------------------------------------------------------------------- ! ! Divergence damping is activated if divdmp = 1. ! Otherwise, this portion of the code is skipped to save ! computations. ! !----------------------------------------------------------------------- IF( divdmp == 1 .OR. divdmp == 2 ) THEN ! !----------------------------------------------------------------------- ! ! The divergence damping terms are defined as ! ! d(cdvdmph*div)/dx for u eq., ! d(cdvdmph*div)/dy for v eq., ! d(cdvdmpv*div)/dz for w eq., ! ! where ! ! div = (difx(u*rhostr) + dify(v*rhostr) + difz(wcont*rhostr))/j3 ! !----------------------------------------------------------------------- !----------------------------------------------------------------------- ! ! Compute the momentum divergence term, defined as ! ! div = d(u*rhostr)/dx + d(v*rhostr)/dy + d(wcont*rhostr)/dz. ! ! and combine the pressure and divergence damping into one ! array so that the pressure gradient force and divergence damping ! can be calculated in a single step. ! !----------------------------------------------------------------------- DO k=1,nz-1 DO j=1,ny-1 DO i=1,nx upgrad(i,j,k)=u(i,j,k)*rhostru(i,j,k)*mapfct(i,j,5) END DO END DO END DO !call test_dump (upgrad,"XXX0upgrad",nx,ny,nz,1,0) DO k=1,nz-1 DO j=1,ny DO i=1,nx-1 vpgrad(i,j,k)=v(i,j,k)*rhostrv(i,j,k)*mapfct(i,j,6) END DO END DO END DO DO k=1,nz DO j=1,ny-1 DO i=1,nx-1 tem1(i,j,k)=wcont(i,j,k)*rhostrw(i,j,k) END DO END DO END DO IF(noisewrt == 1 .AND. MOD(ncalls(mptr),2) == 0) THEN IF(lbcopt == 2) THEN istart=MAX(2,(ngbrz+1)) iend=MIN((nx-2),(nx-ngbrz-1)) jstart=MAX(2,(ngbrz+1)) jend=MIN((ny-2),(ny-ngbrz-1)) ELSE istart=2 iend=nx-2 jstart=2 jend=ny-2 END IF sumdiv=0. DO k=2,nz-2 DO j=jstart,jend DO i=istart,iend sumdiv = sumdiv+abs(j3inv(i,j,k) & * ( mapfct(i,j,7) & * ((upgrad(i+1,j,k)-upgrad(i,j,k))*dxinv & +(vpgrad(i,j+1,k)-vpgrad(i,j,k))*dyinv) & + (tem1(i,j,k+1)-tem1(i,j,k))*dzinv )) END DO END DO END DO sumdiv=1.0E06*sumdiv/ & float((iend-istart+1)*(jend-jstart+1)*(nz-3)) write(nchdiv1(mptr),'(f10.2,f12.4)') (curtim+2*dtsml1),sumdiv END IF DO k=1,nz-1 DO j=1,ny-1 DO i=1,nx-1 tem3(i,j,k) = j3inv(i,j,k) & * ( mapfct(i,j,7) & * ((upgrad(i+1,j,k)-upgrad(i,j,k))*dxinv & +(vpgrad(i,j+1,k)-vpgrad(i,j,k))*dyinv) & + (tem1(i,j,k+1)-tem1(i,j,k))*dzinv ) END DO END DO END DO !call test_dump (upgrad,"XXXtem3_upgrad",nx,ny,nz,1,0) !call test_dump (vpgrad,"XXXtem3_vpgrad",nx,ny,nz,2,0) !call test_dump (vpgrad,"XXXtem3_vpgrad2",nx,ny,nz,1,0) !call test_dump (tem1,"XXXtem3_tem1",nx,ny,nz,3,0) !call test_dump (tem1,"XXXtem3_tem12",nx,ny,nz,1,0) ELSE DO k=1,nz-1 DO j=1,ny-1 DO i=1,nx-1 tem3(i,j,k)= 0.0 END DO END DO END DO END IF !----------------------------------------------------------------------- ! ! Compute the pressure gradient force terms for the three ! momentum equations and store the values in upgrad, vpgrad, ! and wpgrad. ! ! When divergence damping is activated (divdmp=1), these arrays also ! contain the divergence damping terms. ! !----------------------------------------------------------------------- !call test_dump (tem3,"XXXBpgrad_tem3",nx,ny,nz,1,0) CALL pgrad(nx,ny,nz, pprt, tem3, & j1,j2,j3, upgrad,vpgrad,wpgrad,tem1,tem2) !----------------------------------------------------------------------- ! ! Integrate the u, and v equations forward by one small ! timestep dtsml1 using a forward-in-time integration scheme ! (that is, forward relative to the pressure gradient terms). ! !----------------------------------------------------------------------- !call test_dump (dtmrxrsu,"XXX3dtmrxrsu",nx,ny,nz,1,0) IF( nestgrd == 1 .AND. mgrid /= 1 ) THEN DO k=2,nz-2 DO j=2,ny-2 DO i=2,nx-1 u(i,j,k)=u(i,j,k) + uforce(i,j,k) - & dtmrxrsu(i,j,k)*upgrad(i,j,k) END DO END DO END DO DO k=2,nz-2 DO j=2,ny-1 DO i=2,nx-2 v(i,j,k)=v(i,j,k) + vforce(i,j,k) - & dtmryrsv(i,j,k)*vpgrad(i,j,k) END DO END DO END DO !----------------------------------------------------------------------- ! ! Set the lateral boundary conditions for u and v given the ! time tendencies in the case of nested inner grid. ! !----------------------------------------------------------------------- DO k=2,nz-2 DO j=1,ny-1 u( 1,j,k)=u( 1,j,k)+dtsml1 * udtwb(j,k) u(nx,j,k)=u(nx,j,k)+dtsml1 * udteb(j,k) END DO END DO DO k=2,nz-2 DO i=2,nx-1 u(i, 1,k)=u(i, 1,k)+dtsml1 * udtsb(i,k) u(i,ny-1,k)=u(i,ny-1,k)+dtsml1 * udtnb(i,k) END DO END DO DO k=2,nz-2 DO j=1,ny v( 1,j,k)=v( 1,j,k)+dtsml1 * vdtwb(j,k) v(nx-1,j,k)=v(nx-1,j,k)+dtsml1 * vdteb(j,k) END DO END DO DO k=2,nz-2 DO i=2,nx-2 v(i, 1,k)=v(i, 1,k)+dtsml1 * vdtsb(i,k) v(i,ny,k)=v(i,ny,k)+dtsml1 * vdtnb(i,k) END DO END DO !----------------------------------------------------------------------- ! ! Set the top and bottom boundary conditions for u and v. ! !----------------------------------------------------------------------- !call test_dump (u,"XXXsolve_u",nx,ny,nz,1,0) ! bc's for mp not implemented for nested grids CALL acct_interrupt(bc_acct) CALL bcu(nx,ny,nz, dtsml1, u, udteb,udtwb,udtnb,udtsb, & 0,0,0,0 ,tbc,bbc) CALL acct_stop_inter !call test_dump (u,"XXXAsolve_u",nx,ny,nz,1,1) !call test_dump (v,"XXXsolve_v",nx,ny,nz,2,0) ! bc's for mp not implemented for nested grids CALL acct_interrupt(bc_acct) CALL bcv(nx,ny,nz, dtsml1, v, vdteb,vdtwb,vdtnb,vdtsb, & 0,0,0,0 ,tbc,bbc) CALL acct_stop_inter !call test_dump (v,"XXXAsolve_v",nx,ny,nz,2,1) ELSE !call test_dump (u,"XXXuBuforce",nx,ny,nz,1,0) !call test_dump (uforce,"XXXuforce",nx,ny,nz,1,0) !call test_dump (dtmrxrsu,"XXXdtmrxrsu",nx,ny,nz,1,0) !call test_dump (upgrad,"XXXupgrad",nx,ny,nz,1,0) DO k=2,nz-2 DO j=1,ny-1 DO i=2,nx-1 u(i,j,k)=u(i,j,k) + uforce(i,j,k) - & dtmrxrsu(i,j,k)*upgrad(i,j,k) END DO END DO END DO !call test_dump (dtmrxrsu,"XXXdtmrxrsu_tst",nx,ny,nz,1,0) DO k=2,nz-2 DO j=2,ny-1 DO i=1,nx-1 v(i,j,k)=v(i,j,k) + vforce(i,j,k) - & dtmryrsv(i,j,k)*vpgrad(i,j,k) END DO END DO END DO !----------------------------------------------------------------------- ! ! Set the boundary conditions for u and v. ! !----------------------------------------------------------------------- IF ( lbcopt == 1 ) THEN ebc1=ebc wbc1=wbc sbc1=sbc nbc1=nbc IF( ebc == 4 ) ebc1=0 IF( wbc == 4 ) wbc1=0 IF( nbc == 4 ) nbc1=0 IF( sbc == 4 ) sbc1=0 !call test_dump (u,"XXX1solve_u",nx,ny,nz,1,0) IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(u,nx,ny,nz,ebc,wbc,1,mptag,tem1) CALL mprecv2dew(u,nx,ny,nz,ebc,wbc,1,mptag,tem1) CALL mpsend2dns(u,nx,ny,nz,nbc1,sbc1,1,mptag,tem1) CALL mprecv2dns(u,nx,ny,nz,nbc1,sbc1,1,mptag,tem1) END IF CALL acct_interrupt(bc_acct) CALL bcu(nx,ny,nz, dtsml1, u, udteb,udtwb,udtnb,udtsb, & ebc,wbc,nbc1,sbc1,tbc,bbc) CALL acct_stop_inter !call test_dump (u,"XXX1Asolve_u",nx,ny,nz,1,1) !call test_dump (v,"XXX1solve_v",nx,ny,nz,2,0) IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(v,nx,ny,nz,ebc1,wbc1,2,mptag,tem1) CALL mprecv2dew(v,nx,ny,nz,ebc1,wbc1,2,mptag,tem1) CALL mpsend2dns(v,nx,ny,nz,nbc,sbc,2,mptag,tem1) CALL mprecv2dns(v,nx,ny,nz,nbc,sbc,2,mptag,tem1) END IF CALL acct_interrupt(bc_acct) CALL bcv(nx,ny,nz, dtsml1, v, vdteb,vdtwb,vdtnb,vdtsb, & ebc1,wbc1,nbc,sbc,tbc,bbc) CALL acct_stop_inter !call test_dump (v,"XXX1Asolve_v",nx,ny,nz,2,1) ELSE !call test_dump (u,"XXX2solve_u",nx,ny,nz,1,0) IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(u,nx,ny,nz,0,0,1,mptag,tem1) CALL mprecv2dew(u,nx,ny,nz,0,0,1,mptag,tem1) CALL mpsend2dns(u,nx,ny,nz,0,0,1,mptag,tem1) CALL mprecv2dns(u,nx,ny,nz,0,0,1,mptag,tem1) END IF CALL acct_interrupt(bc_acct) CALL bcu(nx,ny,nz, dtsml1, u, udteb,udtwb,udtnb,udtsb, & 0,0,0,0,tbc,bbc) CALL acct_stop_inter !call test_dump (u,"XXX2Asolve_u",nx,ny,nz,1,1) !call test_dump (v,"XXX2solve_v",nx,ny,nz,2,0) IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(v,nx,ny,nz,0,0,2,mptag,tem1) CALL mprecv2dew(v,nx,ny,nz,0,0,2,mptag,tem1) CALL mpsend2dns(v,nx,ny,nz,0,0,2,mptag,tem1) CALL mprecv2dns(v,nx,ny,nz,0,0,2,mptag,tem1) END IF CALL acct_interrupt(mp_acct) CALL bcv(nx,ny,nz, dtsml1, v, vdteb,vdtwb,vdtnb,vdtsb, & 0,0,0,0,tbc,bbc) !call test_dump (v,"XXX2Asolve_v",nx,ny,nz,2,1) CALL exbcuv(nx,ny,nz, curtsml, u,v, & exbcbuf(nu0exb), exbcbuf(nv0exb), & exbcbuf(nudtexb),exbcbuf(nvdtexb)) CALL acct_stop_inter !call test_dump (u,"XXX2AAsolve_u",nx,ny,nz,1,1) !call test_dump (v,"XXX2AAsolve_v",nx,ny,nz,2,1) END IF END IF RETURN END SUBROUTINE solvuv ! ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE SOLVWPEX ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE solvwpex(mptr, nx,ny,nz,exbcbufsz, dtsml1, curtsml, & 1,51 u,v,w,wcont,ptprt,pprt,phydro, & wdteb,wdtwb,wdtnb,wdtsb,pdteb,pdtwb,pdtnb,pdtsb, & rhostr,ptbar,ptbari,pbari,csndsq, & wforce,wpgrad,pforce, & x,y,z,zp, mapfct, j1,j2,j3,aj3x,aj3y,aj3z,j3inv, & rhostru,rhostrv,rhostrw, & exbcbuf,rhofct, & div,pdiv,tem1,tem2,tem3,rstpbi,rstptbi, & dtrzrstw,dxj3xm,dyj3ym,rstj3i) !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Coordinate the time stepping of the w momentum and pressure equations ! using explicit time integration scheme. Divergence damping and the ! acoustically inactive forcing terms in w and pressure equations ! have been evaluated prior to this subroutine and are passed into ! this routine. ! !----------------------------------------------------------------------- ! ! AUTHOR: Ming Xue ! 10/10/91 ! ! MODIFICATION HISTORY: ! ! 5/20/92 (K. Droegemeier and M. Xue) ! Added full documentation. ! ! 6/07/92 ( M. Xue) ! Now only tfuture fields of pprt, u, v and w are passed in. ! ! 2/10/93 (K. Droegemeier) ! Cleaned up documentation. ! ! 4/10/93 (M. Xue & Hao Jin) ! Add the terrain. ! ! 9/6/94 (M.Xue) ! Pressure perturbation buoyancy and base state pressure ! advection terms moved into the small time steps. ! ! 9/1/94 (Y. Lu) ! Cleaned up documentation. ! ! 01/28/95 (G. Bassett) ! Option added to turn off buoyancy terms (for buoyopt=0). ! ! 1/25/96 (Donghai Wang & Yuhe Liu) ! Added the map projection factor to ARPS governing equations. ! ! 4/27/1996 (M. Xue) ! Added code for peqopt=2 case. ! ! 5/6/96 (M. Xue) ! Replaced csndsq in pressure buoyancy term by cpdcv*pbar/rhobar. ! ! 10/16/97 (Donghai Wang) ! Using total density (rho) for the calculation of the pressure ! gradient force terms. ! ! 10/16/97 (Donghai Wang) ! Added the second order terms in the linerized buoyancy terms. ! ! 11/05/97 (D. Weber) ! Added phydro array for use in the bottom boundary condition for ! perturbation pressure (hydrostatic). ! ! 11/06/97 (D. Weber) ! Added three additional levels to the mapfct array. The three ! levels (4,5,6) represent the inverse of the first three in order. ! The inverse map factors are computed to improve efficiency. ! ! 9/18/98 (D. Weber) ! Added arrays aj3x,y,z,pbari,ptbari,rstpbi,rstptbi,dtrzrstw,dxj3xm, ! dyj3ym,rstj3i. ! do not alter arrays!!! ! ! 07/23/2001 (K. Brewster) ! Added mptr to argument list. ! Added optional writing of mean abs(dp/dt) as a diagnostic noise ! parameter. ! !----------------------------------------------------------------------- ! ! INPUT : ! ! nx Number of grid points in the x-direction (east/west) ! ny Number of grid points in the y-direction (north/south) ! nz Number of grid points in the vertical ! ! dtsml1 Local value of small time step size ! curtsml Local curttim at a small time step ! ! u x component of velocity at tfuture (m/s) ! v y component of velocity at tfuture (m/s) ! w Vertical component of Cartesian velocity at tfuture ! (m/s) ! wcont Contravariant vertical velocity (m/s) ! ptprt Perturbation potential temperature at all time levels ! (K) ! pprt Perturbation pressure at tfuture (Pascal) ! ! phydro Big time step forcing term for use in computing the ! hydrostatic pressure at k=1. ! ! wdteb Time tendency of the w field at the east boundary ! wdtwb Time tendency of the w field at the west boundary ! wdtnb Time tendency of the w field at the north boundary ! wdtsb Time tendency of the w field at the south boundary ! ! pdteb Time tendency of the pressure field at the east ! boundary ! pdtwb Time tendency of the pressure field at the west ! boundary ! pdtnb Time tendency of the pressure field at the north ! boundary ! pdtsb Time tendency of the pressure field at the south ! boundary ! ! rhostr Base state density rhobar times j3 (kg/m**3) ! ptbar Base state potential temperature (K) ! ptbari Inverse base state potential temperature (K) ! pbari Inverse base state pressure (Pascal) ! csndsq Sound wave speed squared. ! ! wforce Acoustically inactive forcing terms in w-eq. ! (kg/(m*s)**2) ! pforce Acoustically inactive terms in pressure eq. (Pascal/s) ! ! 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) ! ! mapfct Map factors at scalar, u and v points ! ! j1 Coordinate transformation Jacobian -d(zp)/dx ! j2 Coordinate transformation Jacobian -d(zp)/dy ! j3 Coordinate transformation Jacobian d(zp)/dz ! aj3x Avgx of the coordinate transformation Jacobian d(zp)/dz ! aj3y Avgy of the coordinate transformation Jacobian d(zp)/dz ! aj3z Avgz of the coordinate transformation Jacobian d(zp)/dz ! ! rhostru Average rhostr at u points (kg/m**3). ! rhostrv Average rhostr at v points (kg/m**3). ! rhostrw Average rhostr at w points (kg/m**3). ! ! OUTPUT: ! ! pprt Perturbation pressure at tfuture updated in time ! by stsml1 (Pascal) ! w Vertical component of Cartesian velocity at tfuture ! updated in time by dtsml1 (m/s) ! ! WORK ARRAYS: ! ! wpgrad Pressure gradient term in w-eq. (kg/(m*s)**2) ! div Velocity divergence (1/s), a local array ! pdiv Divergence term in pressure eq. ! (Pascal/s), a local array ! tem1 Temporary work array ! tem2 Temporary work array ! tem3 Temporary work array ! rstpbi rhostr*pbari ! rstptbi rhostr*ptbari ! dtrzrstw dtsml*avgz(rhofct)/rhostrw ! dxj3xm dxinv*aj3x*mapfct(i,j,5) ! dyj3ym dyinv*aj3y*mapfct(i,j,6) ! rstj3i rhostr*j3inv ! !----------------------------------------------------------------------- ! ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! Force explicit declarations INTEGER :: mptr INTEGER :: nx, ny, nz ! Number of grid points in 3 directions REAL :: curtsml ! Local curttim at a small time step REAL :: dtsml1 ! Local small time step size (s) REAL :: u (nx,ny,nz) ! u-velocity at tfuture (m/s) REAL :: v (nx,ny,nz) ! v-velocity at tfuture (m/s) REAL :: w (nx,ny,nz) ! w-velocity at tfuture (m/s) REAL :: wcont (nx,ny,nz) ! Contravariant vertical velocity (m/s) REAL :: ptprt (nx,ny,nz) ! Perturbation potential temperature (K) REAL :: pprt (nx,ny,nz) ! Perturbation pressure at tfuture ! (Pascal) REAL :: phydro(nx,ny) ! Big time step forcing for computing ! hydrostatic pprt at k=1. REAL :: wdteb (ny,nz) ! Time tendency of w at east boundary REAL :: wdtwb (ny,nz) ! Time tendency of w at west boundary REAL :: wdtnb (nx,nz) ! Time tendency of w at north boundary REAL :: wdtsb (nx,nz) ! Time tendency of w at south boundary REAL :: pdteb (ny,nz) ! Time tendency of pressure at east ! boundary REAL :: pdtwb (ny,nz) ! Time tendency of pressure at west ! boundary REAL :: pdtnb (nx,nz) ! Time tendency of pressure at north ! boundary REAL :: pdtsb (nx,nz) ! Time tendency of pressure at south ! boundary REAL :: ptbar (nx,ny,nz) ! Base state potential temperature (K) REAL :: ptbari(nx,ny,nz) ! Inverse base state pot. temperature (K) REAL :: pbari (nx,ny,nz) ! Inverse base state pressure (Pascal). REAL :: csndsq(nx,ny,nz) ! Sound wave speed squared. REAL :: rhostr(nx,ny,nz) ! Base state density rhobar times j3. REAL :: wforce(nx,ny,nz) ! Acoustically inactive forcing terms ! in w-momentum equation (kg/(m*s)**2) REAL :: pforce(nx,ny,nz) ! Acoustically inactive forcing terms ! in the pressure equation (Pascal/s) REAL :: x (nx) ! x-coord. of the physical and compu- ! tational grid. Defined at u-point. REAL :: y (ny) ! y-coord. of the physical and compu- ! tational grid. Defined at v-point. REAL :: z (nz) ! z-coord. of the computational grid. ! Defined at w-point on the staggered ! grid. REAL :: zp (nx,ny,nz) ! Physical height coordinate defined at ! w-point of the staggered grid. REAL :: mapfct(nx,ny,8) ! Map factors at scalar, u and v points REAL :: j1 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as - d( zp )/d( x ). REAL :: j2 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as - d( zp )/d( y ). REAL :: j3 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as d( zp )/d( z ). REAL :: aj3x (nx,ny,nz) ! Coordinate transformation Jacobian defined ! as d( zp )/d( z ) AVERAGED IN THE X-DIR. REAL :: aj3y (nx,ny,nz) ! Coordinate transformation Jacobian defined ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR. REAL :: aj3z (nx,ny,nz) ! Coordinate transformation Jacobian defined ! as d( zp )/d( z ) AVERAGED IN THE Z-DIR. REAL :: j3inv (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as d( zp )/d( z ). INTEGER :: exbcbufsz ! EXBC buffer size REAL :: exbcbuf( exbcbufsz ) ! EXBC buffer array REAL :: rhofct(nx,ny,nz) ! rho-factor:rhobar/rho REAL :: rhostru(nx,ny,nz) ! Averaged rhostr at u points (kg/m**3). REAL :: rhostrv(nx,ny,nz) ! Averaged rhostr at v points (kg/m**3). REAL :: rhostrw(nx,ny,nz) ! Averaged rhostr at w points (kg/m**3). ! !----------------------------------------------------------------------- ! ! Temporary work arrays: ! !----------------------------------------------------------------------- ! REAL :: wpgrad(nx,ny,nz) ! Pressure gradient term in w-eq. REAL :: div (nx,ny,nz) ! Velocity divergence (1/s) REAL :: pdiv (nx,ny,nz) ! Divergence term in pressure eq. ! (Pascal/s) 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 :: rstpbi(nx,ny,nz) ! rhostr*pbari REAL :: rstptbi(nx,ny,nz) ! rhostr*ptbari REAL :: dtrzrstw(nx,ny,nz) ! dtsml1*avgz(rhofct)/rhostrw REAL :: dxj3xm(nx,ny,nz) ! dxinv*aj3x*mapfct(i,j,5) REAL :: dyj3ym(nx,ny,nz) ! dyinv*aj3y*mapfct(i,j,6) REAL :: rstj3i(nx,ny,nz) ! rhostr*j3inv ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'bndry.inc' INCLUDE 'exbc.inc' INCLUDE 'globcst.inc' INCLUDE 'grid.inc' ! Grid & map parameters. INCLUDE 'phycst.inc' INCLUDE 'mp.inc' ! Message passing parameters. ! !----------------------------------------------------------------------- ! ! Misc. local variables: ! !----------------------------------------------------------------------- ! INTEGER :: i, j, k INTEGER :: istart,iend,jstart,jend INTEGER :: ebc1,wbc1,nbc1,sbc1 INTEGER :: wpprt ! Switch for pprt/(rhobar*csndsq) term in w-eq. INTEGER :: prgw ! Switch for rhobar*g*w term in w-eq. INTEGER :: noisewrt REAL :: prgwg5, g05 REAL :: pttem,ptem,tem,tema,temb,temc REAL :: sumdpdt CHARACTER (LEN=128 ) :: dpdtfn INTEGER :: ldpdtfn,istat INTEGER :: ncalls(mgrdmax), nchdpdt1(mgrdmax) SAVE ncalls,nchdpdt1 DATA ncalls /mgrdmax*0/ INTEGER :: mptag ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! noisewrt=0 ncalls(mptr)=ncalls(mptr) + 1 IF (noisewrt == 1 .AND. ncalls(mptr) == 1) THEN dpdtfn = runname(1:lfnkey)//'.dpdt' ldpdtfn = 5 + lfnkey IF(nestgrd == 1) THEN WRITE(dpdtfn((ldpdtfn+1):(ldpdtfn+4)),'(a,i2.2)')'.g',mptr ldpdtfn = ldpdtfn + 4 END IF WRITE(6,'(1x,a,a,a/,1x,a)') & 'Check to see if file ',dpdtfn(1:ldpdtfn),' already exists.', & 'If so, append a version number to the filename.' CALL fnversn( dpdtfn, ldpdtfn ) CALL getunit ( nchdpdt1(mptr) ) OPEN(nchdpdt1(mptr),FORM='formatted',STATUS='new', & FILE=dpdtfn(1:ldpdtfn),IOSTAT=istat) IF( istat /= 0) THEN WRITE(6,'(/a,i2,/a/)') & ' Error occured when opening file '//dpdtfn(1:ldpdtfn)// & ' using FORTRAN unit ',nchdpdt1(mptr), & ' Program stopped in SOLVWPEX.' CALL arpsstop('arpsstop called from SOLVWPEX error opening '// & 'file',1) END IF WRITE(nchdpdt1(mptr),'(a)') runname WRITE(nchdpdt1(mptr),'(t2,a,t15,a)') 'Time (s)','MnAbsdpdt' END IF g05 = g*0.5 IF( bsnesq == 1 ) THEN wpprt = 0 ! Switch for pprt/(rhobar*csndsq) term in w-eq. prgw = 0 ! Switch for rhobar*g*w term in w-eq. ELSE wpprt = 1 ! Switch for pprt/(rhobar*csndsq) term in w-eq. prgw = 1 ! Switch for rhobar*g*w term in w-eq. END IF ! !----------------------------------------------------------------------- ! ! The contribution from ptprt to the buoyancy term is calculated ! inside the small time steps if the potential temperature equation ! is solved inside small time steps, i.e., if ptsmlstp=1. ! ! The contribution from pressure perturbation to the buoyancy is ! always calculated inside the small time steps for better ! computational stability ! ! If buoyopt = 0 then turn off all buoyancy. ! !----------------------------------------------------------------------- ! tem = 0.5*(1.0-cpdcv) tema = 1.0/cpdcv IF ( buoyopt /= 0 ) THEN CALL acct_interrupt(buoy_acct) IF ( ptsmlstp == 1 ) THEN IF ( buoy2nd == 0) THEN !1st-order DO k=1,nz-1 DO j=1,ny-1 DO i=1,nx-1 tem2(i,j,k)=rstptbi(i,j,k)*ptprt(i,j,k) & -wpprt*pprt(i,j,k)*tema*rstpbi(i,j,k) END DO END DO END DO ELSE !2nd-order DO k=1,nz-1 DO j=1,ny-1 DO i=1,nx-1 pttem = ptprt(i,j,k)*ptbari(i,j,k) ptem = wpprt*pprt(i,j,k)*(tema*pbari(i,j,k)) tem2(i,j,k)=rhostr(i,j,k)*( & pttem-pttem*pttem-ptem-tem*ptem*ptem & + 0.5*pttem*ptem) END DO END DO END DO END IF ELSE IF (buoy2nd == 0) THEN !1st-order DO k=1,nz-1 DO j=1,ny-1 DO i=1,nx-1 tem2(i,j,k)= & -wpprt*pprt(i,j,k)*rstpbi(i,j,k)*tema END DO END DO END DO ELSE !2nd-order DO k=1,nz-1 DO j=1,ny-1 DO i=1,nx-1 ptem = wpprt*pprt(i,j,k)*(tema*pbari(i,j,k)) tem2(i,j,k)=-rhostr(i,j,k)*(ptem+tem*ptem*ptem ) END DO END DO END DO END IF END IF DO k=2,nz-1 DO j=1,ny-1 DO i=1,nx-1 tem1(i,j,k)=(tem2(i,j,k)+tem2(i,j,k-1))*g05 END DO END DO END DO CALL acct_stop_inter ELSE DO k=1,nz-1 DO j=1,ny-1 DO i=1,nx-1 tem1(i,j,k) = 0.0 END DO END DO END DO END IF ! !----------------------------------------------------------------------- ! ! To assume mirror symmetry about the top and bottom boundary, ! the density/temperature has zero gradient across the boundary ! but g is assumed to change sign, so that the buoyancy is zero ! at the boundary. c.f. subroutine BUOYCY. ! !----------------------------------------------------------------------- ! DO j=1,ny-1 DO i=1,nx-1 tem1(i,j,2)=0.0 tem1(i,j,nz-1)=0.0 END DO END DO !----------------------------------------------------------------------- ! ! Integrate w equations forward by one small timestep dtsml1 using ! a forward-in-time integration scheme (that is, forward relative ! to the pressure gradient terms). ! !----------------------------------------------------------------------- IF( nestgrd == 1 .AND. mgrid /= 1 ) THEN DO k=2,nz-1 DO j=2,ny-2 DO i=2,nx-2 w(i,j,k)=w(i,j,k) + wforce(i,j,k) - & (wpgrad(i,j,k)-tem1(i,j,k))*dtrzrstw(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Set the lateral boundary conditions for w given the time tendencies ! in the case of nested inner grid. ! !----------------------------------------------------------------------- ! DO k=3,nz-2 DO j=1,ny-1 w( 1,j,k)=w( 1,j,k)+dtsml1 * wdtwb(j,k) w(nx-1,j,k)=w(nx-1,j,k)+dtsml1 * wdteb(j,k) END DO END DO DO k=3,nz-2 DO i=2,nx-2 w(i, 1,k)=w(i, 1,k)+dtsml1 * wdtsb(i,k) w(i,ny-1,k)=w(i,ny-1,k)+dtsml1 * wdtnb(i,k) END DO END DO ELSE DO k=2,nz-1 DO j=1,ny-1 DO i=1,nx-1 w(i,j,k)=w(i,j,k) + wforce(i,j,k) - & (wpgrad(i,j,k)-tem1(i,j,k))*dtrzrstw(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Apply the lateral boundary conditions for w. ! ! For the open boundary case, w at the lateral boundarues are solved ! from w equation directly therefore does not need to be reset. ! !----------------------------------------------------------------------- ! !call test_dump (w,"XXXsolve_w",nx,ny,nz,3,0) IF( lbcopt == 1 ) THEN ! Internal boundary conditions ebc1=ebc wbc1=wbc sbc1=sbc nbc1=nbc IF( ebc == 4 ) ebc1=0 IF( wbc == 4 ) wbc1=0 IF( nbc == 4 ) nbc1=0 IF( sbc == 4 ) sbc1=0 !call test_dump (w,"XXX4solve_w",nx,ny,nz,3,0) IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(w,nx,ny,nz,ebc1,wbc1,3,mptag,tem3) CALL mprecv2dew(w,nx,ny,nz,ebc1,wbc1,3,mptag,tem3) CALL mpsend2dns(w,nx,ny,nz,nbc1,sbc1,3,mptag,tem3) CALL mprecv2dns(w,nx,ny,nz,nbc1,sbc1,3,mptag,tem3) END IF CALL acct_interrupt(mp_acct) CALL lbcw(nx,ny,nz,dtsml,w,wcont,wdteb,wdtwb,wdtnb,wdtsb, & ebc1,wbc1,nbc1,sbc1) CALL acct_stop_inter !call test_dump (w,"XXX4Asolve_w",nx,ny,nz,3,1) ELSE ! Apply zero gradient condition ebc1 = 3 wbc1 = 3 sbc1 = 3 nbc1 = 3 IF( ebc == 0 ) ebc1 = 0 IF( wbc == 0 ) wbc1 = 0 IF( nbc == 0 ) nbc1 = 0 IF( sbc == 0 ) sbc1 = 0 !call test_dump (w,"XXX5solve_w",nx,ny,nz,3,0) IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(w,nx,ny,nz,ebc1,wbc1,3,mptag,tem3) CALL mprecv2dew(w,nx,ny,nz,ebc1,wbc1,3,mptag,tem3) CALL mpsend2dns(w,nx,ny,nz,nbc1,sbc1,3,mptag,tem3) CALL mprecv2dns(w,nx,ny,nz,nbc1,sbc1,3,mptag,tem3) END IF CALL acct_interrupt(mp_acct) CALL lbcw(nx,ny,nz,dtsml,w,wcont,wdteb,wdtwb,wdtnb,wdtsb, & ebc1,wbc1,nbc1,sbc1) CALL acct_stop_inter !call test_dump (w,"XXX5Asolve_w",nx,ny,nz,3,1) END IF END IF !call test_dump (w,"XXXAsolve_w",nx,ny,nz,3,1) ! !----------------------------------------------------------------------- ! ! Calculate wcont at time tfuture, including the boundary ! points. Wcont at the lateral boundaries is calculated ! from boundary u, v and w. Wcont at the top and bottom ! depends on the boundary condition option. ! !----------------------------------------------------------------------- ! !call test_dump (w,"XXX1sBwc_w1",nx,ny,nz,1,0) CALL wcontra(nx,ny,nz,u,v,w,mapfct,j1,j2,j3,aj3z, & rhostr,rhostru,rhostrv,rhostrw,wcont,tem1,tem2) ! !----------------------------------------------------------------------- ! ! Set the top and bottom boundary conditions for w based on u, v and ! wcont at the top and bottom boundaries. ! !----------------------------------------------------------------------- ! CALL acct_interrupt(bc_acct) CALL vbcw(nx,ny,nz,w,wcont,tbc,bbc,u,v, & rhostr,rhostru,rhostrv,rhostrw, & j1,j2,j3) CALL acct_stop_inter IF( peqopt == 1) THEN !----------------------------------------------------------------------- ! ! Calculate the velocity divergence using newly updated velocity. ! !----------------------------------------------------------------------- tema = dzinv*dtsml1 DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 div(i,j,k) = mapfct(i,j,7) & *( u(i+1,j,k)*dxj3xm(i+1,j,k)- u(i ,j,k)*dxj3xm(i ,j,k) & + v(i,j+1,k)*dyj3ym(i,j+1,k)- v(i,j ,k)*dyj3ym(i,j ,k)) & +( wcont(i,j,k+1)*aj3z(i,j,k+1) & - wcont(i,j,k)*aj3z(i,j,k) ) * tema END DO END DO END DO !----------------------------------------------------------------------- ! ! Compute the divergence term and the base state pressure advection ! in the pressure equation. ! ! The pressure divergence term is: -rhostr*csndsq*div/j3 ! The base state pressure advection is -j3*w*d(pbar)/dzp = w*rhostr*g. ! ! These two terms are saved in pdiv. ! !----------------------------------------------------------------------- prgwg5=prgw * g05 tema = dtsml1*prgw * g05 DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 pdiv(i,j,k)= & tema*(w(i,j,k)+w(i,j,k+1))*rhostr(i,j,k) & -csndsq(i,j,k)*rstj3i(i,j,k)*div(i,j,k) END DO END DO END DO ELSE !----------------------------------------------------------------------- ! ! Calculate the density weighted mass divergence using newly ! updated velocity. Then calculate the pressure divergence term: ! -csndsq*div ! !----------------------------------------------------------------------- ! DO k= 2,nz-2 DO j= 1,ny-1 DO i= 1,nx tem1(i,j,k)=u(i,j,k)*rhostru(i,j,k)*mapfct(i,j,5) END DO END DO END DO DO k= 2,nz-2 DO j= 1,ny DO i= 1,nx-1 tem2(i,j,k)=v(i,j,k)*rhostrv(i,j,k)*mapfct(i,j,6) END DO END DO END DO DO k= 2,nz-1 DO j= 1,ny-1 DO i= 1,nx-1 tem3(i,j,k)=wcont(i,j,k)*rhostrw(i,j,k) END DO END DO END DO tema = dxinv*dtsml1 temb = dyinv*dtsml1 temc = dzinv*dtsml1 DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 pdiv(i,j,k)= -csndsq(i,j,k)*( mapfct(i,j,7) & *((tem1(i+1,j,k)-tem1(i,j,k))*tema & + (tem2(i,j+1,k)-tem2(i,j,k))*temb ) & + (tem3(i,j,k+1)-tem3(i,j,k))*temc ) END DO END DO END DO END IF ! !----------------------------------------------------------------------- ! ! Integrate forward the pressure equation by one small timestep, ! using a backward (relative to the divergence term) integration ! scheme. ! ! And set lateral boundary conditions for the pressure equation. ! !----------------------------------------------------------------------- ! IF( nestgrd == 1 .AND. mgrid /= 1 ) THEN DO k=2,nz-2 DO j=2,ny-2 DO i=2,nx-2 pprt(i,j,k)=pprt(i,j,k) & +pforce(i,j,k)+pdiv(i,j,k)*j3inv(i,j,k) END DO END DO END DO DO k=2,nz-2 DO j=1,ny-1 pprt( 1,j,k)=pprt( 1,j,k)+dtsml1 * pdtwb(j,k) pprt(nx-1,j,k)=pprt(nx-1,j,k)+dtsml1 * pdteb(j,k) END DO END DO DO k=2,nz-2 DO i=2,nx-2 pprt(i, 1,k)=pprt(i, 1,k)+dtsml1 * pdtsb(i,k) pprt(i,ny-1,k)=pprt(i,ny-1,k)+dtsml1 * pdtnb(i,k) END DO END DO ! ! Call the pprt bottom boundary condition subroutine to ! compute the hydrostatic pprt at k=1. ! CALL acct_interrupt(bc_acct) CALL pprtbbc(nx,ny,nz,g05,buoy2nd,rhostr,pprt,ptprt, & pbari,ptbari,phydro, & tem1,tem2) ! tem1 = new pprt at k=1. CALL acct_stop_inter ! !----------------------------------------------------------------------- ! ! And top and bottom boundary conditions for the pressure equation. ! !----------------------------------------------------------------------- ! ! bc's for mp not implemented for nested grids CALL acct_interrupt(mp_acct) CALL bcp(nx,ny,nz, dtsml1, pprt, pdteb, pdtwb, pdtnb, pdtsb, & tem1(1,1,1),0,0,0,0 ,tbc,bbc) CALL acct_stop_inter ELSE ! Not nested grid DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 pprt(i,j,k)=pprt(i,j,k) & +pforce(i,j,k)+pdiv(i,j,k)*j3inv(i,j,k) END DO END DO END DO IF(noisewrt == 1 .AND. MOD(ncalls(mptr),2) == 0 ) THEN IF(lbcopt == 2) THEN istart=MAX(2,(ngbrz+1)) iend=MIN((nx-2),(nx-ngbrz-1)) jstart=MAX(2,(ngbrz+1)) jend=MIN((ny-2),(ny-ngbrz-1)) ELSE istart=2 iend=nx-2 jstart=2 jend=ny-2 END IF sumdpdt=0. DO k=2,nz-2 DO j=jstart,jend DO i=istart,iend sumdpdt=sumdpdt+abs(pforce(i,j,k)+pdiv(i,j,k)*j3inv(i,j,k)) END DO END DO END DO sumdpdt=sumdpdt/ & (float((iend-istart+1)*(jend-jstart+1)*(nz-3))*dtsml1) write(nchdpdt1(mptr),'(f10.2,f12.6)') (curtim+2*dtsml1),sumdpdt END IF ! ! Call the pprt bottom boundary condition subroutine to ! compute the hydrostatic pprt at k=1. ! !call test_dump (pprt,"XXXsolve_pprt",nx,ny,nz,0,0) CALL acct_interrupt(bc_acct) CALL pprtbbc(nx,ny,nz,g05,buoy2nd,rhostr,pprt,ptprt, & pbari,ptbari,phydro, & tem1,tem2) ! tem1 = new pprt at k=1. CALL acct_stop_inter !call test_dump (pprt,"XXXAsolve_pprt",nx,ny,nz,0,1) ! !----------------------------------------------------------------------- ! ! Apply the boundary conditions for the pressure equation. ! ! For the open boundary case, the boundary value is solved from the ! equation. ! !----------------------------------------------------------------------- ! !call test_dump (pprt,"XXX1solve_pprt",nx,ny,nz,0,0) IF( lbcopt == 1 ) THEN ! Internal boundary conditions ebc1=ebc wbc1=wbc sbc1=sbc nbc1=nbc IF( ebc == 4 ) ebc1=0 IF( wbc == 4 ) wbc1=0 IF( nbc == 4 ) nbc1=0 IF( sbc == 4 ) sbc1=0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(pprt,nx,ny,nz,ebc1,wbc1,0,mptag,tem2) CALL mprecv2dew(pprt,nx,ny,nz,ebc1,wbc1,0,mptag,tem2) CALL mpsend2dns(pprt,nx,ny,nz,nbc1,sbc1,0,mptag,tem2) CALL mprecv2dns(pprt,nx,ny,nz,nbc1,sbc1,0,mptag,tem2) END IF CALL acct_interrupt(mp_acct) CALL bcp(nx,ny,nz, dtsml1, pprt, pdteb, pdtwb, pdtnb, pdtsb, & tem1(1,1,1), ebc1,wbc1,nbc1,sbc1,tbc,bbc) CALL acct_stop_inter ELSE ! External boundary condition ebc1 = 3 wbc1 = 3 sbc1 = 3 nbc1 = 3 IF( ebc == 0 ) ebc1 = 0 IF( wbc == 0 ) wbc1 = 0 IF( nbc == 0 ) nbc1 = 0 IF( sbc == 0 ) sbc1 = 0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(pprt,nx,ny,nz,ebc1,wbc1,0,mptag,tem2) CALL mprecv2dew(pprt,nx,ny,nz,ebc1,wbc1,0,mptag,tem2) CALL mpsend2dns(pprt,nx,ny,nz,nbc1,sbc1,0,mptag,tem2) CALL mprecv2dns(pprt,nx,ny,nz,nbc1,sbc1,0,mptag,tem2) END IF CALL acct_interrupt(mp_acct) CALL bcp(nx,ny,nz, dtsml1, pprt, pdteb, pdtwb, pdtnb, pdtsb, & tem1(1,1,1), 0,0,0,0,tbc,bbc) CALL exbcp(nx,ny,nz, curtsml, pprt, & exbcbuf(npr0exb),exbcbuf(nprdtexb)) CALL acct_stop_inter END IF END IF !call test_dump (pprt,"XXX1Asolve_pprt",nx,ny,nz,0,1) RETURN END SUBROUTINE solvwpex ! ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE SOLVWPIM ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE solvwpim(mptr, nx,ny,nz,exbcbufsz, dtsml1, curtsml, & 1,52 u,v,w,wcont,ptprt,pprt,phydro, & wdteb,wdtwb,wdtnb,wdtsb,pdteb,pdtwb,pdtnb,pdtsb, & rhostr,ptbar,ptbari,pbari,csndsq, & wforce,wpgrad,pforce, & x,y,z,zp, mapfct, j1,j2,j3,aj3x,aj3y,aj3z,j3inv, & trigs1,trigs2,ifax1,ifax2, & wsave1,wsave2,vwork1,vwork2, & rhostru,rhostrv,rhostrw, & exbcbuf,rhofct, & fw,fp,wcontuv,tem1,tem2,tem3,tem4,j3irst, & csj32irst,rstpbi,rstwi, & dxij3xm,dyij3ym,pbzi) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Perform the time integration of w and pressure equations using ! implicit schem in vertical direction. The acoustically inactive ! forcing terms in these equations have been evaluated prior to this ! subroutine and are stored in wforce and pforce. ! !----------------------------------------------------------------------- ! ! ! AUTHOR: M. Xue & H. Jin ! 8/20/93. ! ! 9/6/94 (M.Xue) ! A new version of vertically implicit small time step solver, ! The perturbation pressure contribution to buoyancy and the ! base state pressure advection terms are also treated implicitly ! in the vertical direction inside the small time steps. ! ! 9/1/94 (Y. Lu) ! Cleaned up documentation. ! ! 3/2/1995 (M. Xue and A. Shapiro) ! Significant bug fix in loop 600. rhostru there was mistakenly ! written as rhostrw. ! ! 10/31/95 (D. Weber) ! Added linear hydrostatic upper radiation condition for w-p. ! References are Klemp and Durran (JAS, 1983) and Chen (1991). ! Includes the use of trigs1,trigs2,ifax1,ifax2. ! ! 1/25/96 (Donghai Wang & Yuhe Liu) ! Added the map projection factor to ARPS governing equations. ! ! 4/27/1996 (M. Xue) ! Corrected the formulations of the coefficients of the tridiagonal ! equations. The oringal formulation was slightly inacurate. ! ! 5/6/96 (M. Xue) ! Replaced csndsq in pressure buoyancy term by cpdcv*pbar/rhobar. ! ! 3/11/1997 (M. Xue and D. Weber) ! Corrected a minor bug related to the radiation top boundary ! condition. ! ! 07/22/97 (D. Weber) ! Added even fft for linear hydrostatic w-p upper radiation condition. ! References are Klemp and Durran (JAS, 1983) and Chen (1991). ! Includes the use of wsave1,wsave2,vwork1,vwork2 (fftopt=2). ! ! 10/21/97 (Donghai Wang) ! Using total density (rho) in the calculation of the pressure ! gradient force terms. ! ! 10/21/97 (Donghai Wang) ! Added the second order terms in the linerized buoyancy terms. ! ! 11/05/97 (D. Weber) ! Added phydro array for use in the bottom boundary condition for ! perturbation pressure (hydrostatic). ! ! 11/06/97 (D. Weber) ! Added three additional levels to the mapfct array. The three ! levels (4,5,6) represent the inverse of the first three in order. ! The inverse map factors are computed to improve efficiency. ! Computed constants outside loops in selected loops. ! ! 9/18/98 (D. Weber) ! Added arrays aj3x,y,z,ptbari, and pbari to improve the speed ! of the code. Also added tem5-12 for pre-computing groups of ! commonly used constants. ! ! 3/18/99 (D. Weber) ! Bug fix to second order buoyancy term (do loop 350). ! ! 07/23/2001 (K. Brewster) ! Added mptr to argument list. ! Added optional writing of mean abs(dp/dt) as a diagnostic noise ! parameter. ! !----------------------------------------------------------------------- ! ! INPUT : ! ! nx Number of grid points in the x-direction (east/west) ! ny Number of grid points in the y-direction (north/south) ! nz Number of grid points in the vertical ! ! dtsml1 Local value of small time step size ! curtsml Local curttim at a small time step ! ! u x component of velocity at tfuture (m/s) ! v y component of velocity at tfuture (m/s) ! w Vertical component of Cartesian velocity at tfuture ! (m/s) ! wcont Contravariant vertical velocity (m/s) ! ptprt Perturbation potential temperature at time tpresent (K) ! pprt Perturbation pressure at time tpresent (Pascal) ! ! wdteb Time tendency of the w field at the east boundary ! wdtwb Time tendency of the w field at the west boundary ! wdtnb Time tendency of the w field at the north boundary ! wdtsb Time tendency of the w field at the south boundary ! ! pdteb Time tendency of the pressure field at the east ! boundary ! pdtwb Time tendency of the pressure field at the west ! boundary ! pdtnb Time tendency of the pressure field at the north ! boundary ! pdtsb Time tendency of the pressure field at the south ! boundary ! ! phydro Big time step forcing term for use in computing the ! hydrostatic pressure at k=1. ! ! rhostr Base state density rhobar times j3 (kg/m**3) ! ptbar Base state potential temperature (K) ! ptbari Inverse base state potential temperature (K) ! pbari Inverse base state pressure (Pascal) ! csndsq Sound wave speed squared. ! ! wforce Acoustically inactive forcing terms in w-eq. ! (kg/(m*s)**2) ! wpgrad Pressure gradient term in w-eq. (kg/(m*s)**2) ! pforce Acoustically inactive terms in pressure eq. (Pascal/s) ! ! 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) ! ! mapfct Map factors at scalar, u and v points ! ! j1 Coordinate transformation Jacobian -d(zp)/dx ! j2 Coordinate transformation Jacobian -d(zp)/dy ! j3 Coordinate transformation Jacobian d(zp)/dz ! aj3x Avgx of the coordinate transformation Jacobian d(zp)/dz ! aj3y Avgy of the coordinate transformation Jacobian d(zp)/dz ! aj3z Avgz of the coordinate transformation Jacobian d(zp)/dz ! trigs1 Array containing pre-computed trig function for ! fftopt=1. ! trigs2 Array containing pre-computed trig function for ! fftopt=1. ! ifax1 Array containing the factors of nx for fftopt=1. ! ifax2 Array containing the factors of ny for fftopt=1. ! ! vwork1 2-D work array for fftopt = 2. ! vwork2 2-D work array for fftopt = 2. ! wsave1 Work array for fftopt = 2. ! wsave2 Work array for fftopt = 2. ! ! rhostru Average rhostr at u points (kg/m**3). ! rhostrv Average rhostr at v points (kg/m**3). ! rhostrw Average rhostr at w points (kg/m**3). ! ! OUTPUT: ! ! pprt Perturbation pressure at tfuture updated in time ! by dtsml1 (Pascal) ! w Vertical component of Cartesian velocity at tfuture ! updated in time by dtsml1 (m/s) ! ! WORK ARRAYS: ! ! fw Work array to carry force terms in w-eqation. ! fp Work array to carry force terms in p-eqation. ! wcontuv Work array to carry the contributions of u & v to wcont ! tem1 Work array ! tem2 Work array ! tem3 Work array ! tem4 Work array ! j3irst j3inv*rhostr ! csj32irst csndsq*j3inv*j3inv*rhostr ! rstpbi rhostr*pbari ! rstwi 1/rhostrw ! dxij3xm dxinv*aj3x*mapfct(i,j,5) ! dyij3ym dyinv*aj3y*mapfct(i,j,6) ! pbzi 1/avgz(pbar) ! !----------------------------------------------------------------------- ! ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! Force explicit declarations INTEGER :: mptr INTEGER :: nx, ny, nz ! Number of grid points in 3 directions REAL :: dtsml1 ! Local small time step size (s) REAL :: curtsml ! Local curttim at a small time step REAL :: u (nx,ny,nz) ! u-velocity at tfuture (m/s) REAL :: v (nx,ny,nz) ! v-velocity at tfuture (m/s) REAL :: w (nx,ny,nz) ! w-velocity at tfuture (m/s) REAL :: wcont (nx,ny,nz) ! Contravariant vertical velocity (m/s) REAL :: ptprt (nx,ny,nz) ! Perturbation potential temperature (K) REAL :: pprt (nx,ny,nz) ! Perturbation pressure at tfuture ! (Pascal) REAL :: wdteb (ny,nz) ! Time tendency of w at east boundary REAL :: wdtwb (ny,nz) ! Time tendency of w at west boundary REAL :: wdtnb (nx,nz) ! Time tendency of w at north boundary REAL :: wdtsb (nx,nz) ! Time tendency of w at south boundary REAL :: pdteb (ny,nz) ! Time tendency of pressure at east ! boundary REAL :: pdtwb (ny,nz) ! Time tendency of pressure at west ! boundary REAL :: pdtnb (nx,nz) ! Time tendency of pressure at north ! boundary REAL :: pdtsb (nx,nz) ! Time tendency of pressure at south ! boundary REAL :: phydro(nx,ny) ! Big time step forcing for computing ! hydrostatic pprt at k=1. REAL :: rhostr(nx,ny,nz) ! Base state density rhobar times j3. REAL :: ptbar (nx,ny,nz) ! Base state potential temperature (K) REAL :: ptbari(nx,ny,nz) ! Inverse base state pot. temperature (K) REAL :: pbari (nx,ny,nz) ! Inverse base state pressure (Pascal). REAL :: csndsq(nx,ny,nz) ! Sound wave speed squared. REAL :: wforce(nx,ny,nz) ! Acoustically inactive forcing terms ! in w-momentum equation (kg/(m*s)**2) REAL :: wpgrad(nx,ny,nz) ! Pressure gradient term in w-eq. ! (kg/(m*s)**2) REAL :: pforce(nx,ny,nz) ! Acoustically inactive forcing terms ! in the pressure equation (Pascal/s) REAL :: x (nx) ! x-coord. of the physical and compu- ! tational grid. Defined at u-point. REAL :: y (ny) ! y-coord. of the physical and compu- ! tational grid. Defined at v-point. REAL :: z (nz) ! z-coord. of the computational grid. ! Defined at w-point on the staggered ! grid. REAL :: zp (nx,ny,nz) ! Physical height coordinate defined at ! w-point of the staggered grid. REAL :: mapfct(nx,ny,8) ! Map factors at scalar, u and v points REAL :: j1 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as - d( zp )/d( x ). REAL :: j2 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as - d( zp )/d( y ). REAL :: j3 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as d( zp )/d( z ). REAL :: aj3x (nx,ny,nz) ! Coordinate transformation Jacobian defined ! as d( zp )/d( z ) AVERAGED IN THE X-DIR. REAL :: aj3y (nx,ny,nz) ! Coordinate transformation Jacobian defined ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR. REAL :: aj3z (nx,ny,nz) ! Coordinate transformation Jacobian defined ! as d( zp )/d( z ) AVERAGED IN THE Z-DIR. REAL :: j3inv (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as d( zp )/d( z ). INTEGER :: exbcbufsz ! EXBC buffer size REAL :: exbcbuf( exbcbufsz ) ! EXBC buffer array REAL :: rhofct(nx,ny,nz) ! rho-factor: rhobar/rho REAL :: trigs1(3*(nx-1)/2+1) ! Array containing pre-computed trig ! function for fftopt=1. REAL :: trigs2(3*(ny-1)/2+1) ! Array containing pre-computed trig ! function for fftopt=1. INTEGER :: ifax1(13) ! Array containing the factors of nx for ! fftopt=1. INTEGER :: ifax2(13) ! Array containing the factors of ny for ! fftopt=1. REAL :: vwork1 (nx+1,ny+1) ! 2-D work array for fftopt = 2. REAL :: vwork2 (ny,nx+1) ! 2-D work array for fftopt = 2. REAL :: wsave1 (3*(ny-1)+15) ! Work array for fftopt = 2. REAL :: wsave2 (3*(nx-1)+15) ! Work array for fftopt = 2. REAL :: rhostru(nx,ny,nz) ! Averaged rhostr at u points (kg/m**3). REAL :: rhostrv(nx,ny,nz) ! Averaged rhostr at v points (kg/m**3). REAL :: rhostrw(nx,ny,nz) ! Averaged rhostr at w points (kg/m**3). ! !----------------------------------------------------------------------- ! ! Temporary WORK ARRAYS: ! !----------------------------------------------------------------------- ! REAL :: fp (nx,ny,nz) ! Pressure gradient term in w-eq. REAL :: fw (nx,ny,nz) ! Force in w equation.(kg/(m*s)**2) REAL :: wcontuv(nx,ny,nz) ! Contributions of u & v to wcont 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 :: j3irst(nx,ny,nz) ! j3inv*rhostr REAL :: csj32irst (nx,ny,nz) ! csndsq*j3inv*j3inv*rhostr REAL :: rstpbi(nx,ny,nz) ! rhostr*pbari REAL :: rstwi (nx,ny,nz) ! 1/rhostrw REAL :: dxij3xm(nx,ny,nz) ! dxinv*aj3x*mapfct(i,j,5) REAL :: dyij3ym(nx,ny,nz) ! dyinv*aj3y*mapfct(i,j,6) REAL :: pbzi (nx,ny,nz) ! 1/avgz(pbar) ! !----------------------------------------------------------------------- ! ! Misc. local variables: ! !----------------------------------------------------------------------- ! INTEGER :: i, j, k INTEGER :: istart,iend,jstart,jend INTEGER :: ebc1,wbc1,nbc1,sbc1 REAL :: g05,pk,nk,g05wp,g05pr INTEGER :: wpprt, prgw, itema REAL :: tema,temb,w1,w2,nrho INTEGER :: buoy2swt !Switch for 1st-order or 2nd-order in buoyancy REAL :: ptemk,ptemk1,pttemk,pttemk1 INTEGER :: noisewrt INTEGER :: mptag ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'globcst.inc' INCLUDE 'grid.inc' ! Grid & map parameters. INCLUDE 'bndry.inc' INCLUDE 'exbc.inc' INCLUDE 'phycst.inc' ! Physical constants INCLUDE 'mp.inc' ! Message passing parameters. REAL :: sumdpdt CHARACTER (LEN=128 ) :: dpdtfn INTEGER :: ldpdtfn,istat INTEGER :: ncalls(mgrdmax), nchdpdt1(mgrdmax) SAVE ncalls,nchdpdt1 DATA ncalls /mgrdmax*0/ ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! IF( bsnesq == 1 ) THEN wpprt = 0 ! Switch for pprt/(rhobar*csndsq) term in w-eq. prgw = 0 ! Switch for rhobar*g*w term in w-eq. ELSE wpprt = 1 ! Switch for pprt/(rhobar*csndsq) term in w-eq. prgw = 1 ! Switch for rhobar*g*w term in w-eq. END IF g05 = g*0.5 g05wp = g05*wpprt g05pr = g05*prgw noisewrt = 0 ncalls(mptr) = ncalls(mptr) + 1 IF (noisewrt == 1 .AND. ncalls(mptr) == 1) THEN dpdtfn = runname(1:lfnkey)//'.dpdt' ldpdtfn = 5 + lfnkey IF(nestgrd == 1) THEN WRITE(dpdtfn((ldpdtfn+1):(ldpdtfn+4)),'(a,i2.2)')'.g',mptr ldpdtfn = ldpdtfn + 4 END IF WRITE(6,'(1x,a,a,a/,1x,a)') & 'Check to see if file ',dpdtfn(1:ldpdtfn),' already exists.', & 'If so, append a version number to the filename.' CALL fnversn( dpdtfn, ldpdtfn ) CALL getunit ( nchdpdt1(mptr) ) OPEN(nchdpdt1(mptr),FORM='formatted',STATUS='new', & FILE=dpdtfn(1:ldpdtfn),IOSTAT=istat) IF( istat /= 0) THEN WRITE(6,'(/a,i2,/a/)') & ' Error occured when opening file '//dpdtfn(1:ldpdtfn)// & ' using FORTRAN unit ',nchdpdt1(mptr), & ' Program stopped in SOLVWPIM.' CALL arpsstop('arpsstop called from SOLVWPIM error opening '// & 'file',1) END IF WRITE(nchdpdt1(mptr),'(a)') runname WRITE(nchdpdt1(mptr),'(t2,a,t15,a)') 'Time (s)','MnAbsdpdt' END IF !----------------------------------------------------------------------- ! ! Calculate the horizontal velocity divergence using newly updated ! u and v velocity plus half vertical divergence from wcont, and ! store the result in tem3. ! ! Namely, tem3 = difx(u*avgx(j3))+dify(v*avgy(j3))+ ! (1-tacoef)*difz(wcont*avgz(j3)) ! ! note tem9=dtsml*aj3x*mapfct(5)*dxinv ! note tem10=dtsml*aj3y*mapfct(6)*dyinv !----------------------------------------------------------------------- tema = dtsml1*(1.0-tacoef)*dzinv DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 tem3(i,j,k) = mapfct(i,j,7) & * ( (u(i+1,j,k)*dxij3xm(i+1,j,k) & -u(i,j,k)*dxij3xm(i,j,k)) & + (v(i,j+1,k)*dyij3ym(i,j+1,k) & -v(i,j,k)*dyij3ym(i,j,k)) ) & +(wcont(i,j,k+1)*aj3z(i,j,k+1)-wcont(i,j,k)*aj3z(i,j,k)) & *tema END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Compute the forcing terms in pressure equation ! ! fp = dtsml/j3 *(pforce-rhobar*csndsq*tem3+(1-tacoef)*rhostr*g*w) ! ! note pforce includes dtsml1 and j3inv... ! ! rhostr*g*w is the base state pressure advection term. ! !----------------------------------------------------------------------- ! tema = dtsml1*g05pr*(1.0-tacoef) DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 fp(i,j,k)=pforce(i,j,k) & -csj32irst(i,j,k)*tem3(i,j,k) & +tema*(w(i,j,k)+w(i,j,k+1))*j3irst(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Compute the first two terms in the contravariant vertical ! velocity formulation: ! ! wcontuv = (avgx(avgz(ustr)*j1)+avgy(avgz(vstr)*j2))/rhostrw ! !----------------------------------------------------------------------- ! IF( ternopt == 0 ) THEN DO k=2,nz-1 DO j=1,ny-1 DO i=1,nx-1 wcontuv(i,j,k)=0.0 END DO END DO END DO ELSE DO k= 1,nz-1 DO j= 1,ny-1 DO i= 1,nx tem1(i,j,k)=u(i,j,k)*rhostru(i,j,k) END DO END DO END DO DO k= 1,nz-1 DO j= 1,ny DO i= 1,nx-1 tem2(i,j,k)=v(i,j,k)*rhostrv(i,j,k) END DO END DO END DO DO k= 2,nz-1 DO j= 1,ny-1 DO i= 1,nx-1 wcontuv(i,j,k)=((tem1(i ,j,k)+tem1(i ,j,k-1))*j1(i ,j,k) & +(tem1(i+1,j,k)+tem1(i+1,j,k-1))*j1(i+1,j,k) & +(tem2(i ,j,k)+tem2(i ,j,k-1))*j2(i ,j,k) & +(tem2(i,j+1,k)+tem2(i,j+1,k-1))*j2(i,j+1,k)) & *mapfct(i,j,8) * rstwi(i,j,k) END DO END DO END DO DO j=1,ny-1 DO i=1,nx-1 wcontuv(i,j,nz-1)=0.0 wcontuv(i,j,2) = ((u(i ,j,2)+u(i ,j,1))*j1(i,j,2) & +(u(i+1,j,2)+u(i+1,j,1))*j1(i+1,j,2) & +(v(i,j ,2)+v(i,j ,1))*j2(i,j,2) & +(v(i,j+1,2)+v(i,j+1,1))*j2(i,j+1,2)) & *mapfct(i,j,8) END DO END DO END IF ! !----------------------------------------------------------------------- ! ! Average rhofct at w points, stored in tem4 ! !----------------------------------------------------------------------- ! CALL avgsw(rhofct,nx,ny,nz, 1,nx-1, 1,ny-1,tem4) ! !----------------------------------------------------------------------- ! ! Compute the right-hand-side forcing term in tridiagonal linear ! equation. Array w is used to store this forcing term. ! ! First, we add the contribution of pressure perturbation to the ! buoyancy to wforce and wpgrad. ! ! This term has a form of - rhostr*g*pprt/(cpdcv*pbar), ! !----------------------------------------------------------------------- ! tema = g05wp/cpdcv IF ( buoy2nd == 0) THEN !1st-order buoy2swt = 0 !Switch for 1st-order or 2nd-order ELSE !2nd-order buoy2swt = 1 END IF temb = 0.5*buoy2swt*(1.0-cpdcv)/cpdcv DO k=3,nz-2 DO j=1,ny-1 DO i=1,nx-1 ptemk = pprt(i,j,k )*pbari(i,j,k ) ! new code... ptemk1= pprt(i,j,k-1)*pbari(i,j,k-1) fw(i,j,k) = wforce(i,j,k)-tem4(i,j,k)*(wpgrad(i,j,k) & +rhostrw(i,j,k)*(ptemk+ptemk1+ & temb*(ptemk*ptemk+ptemk1*ptemk1)) & *tema) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! When potential temperature equation is solved within small time ! steps, the contribution from ptprt to buoyancy term is calculated ! here. ! !----------------------------------------------------------------------- ! IF( ptsmlstp == 1 ) THEN tema = 1.0/(2.0*cpdcv) DO k=3,nz-2 DO j=1,ny-1 DO i=1,nx-1 ptemk = pprt(i,j,k )*pbari(i,j,k ) ptemk1= pprt(i,j,k-1)*pbari(i,j,k-1) pttemk = ptprt(i,j,k )*ptbari(i,j,k ) pttemk1= ptprt(i,j,k-1)*ptbari(i,j,k-1) fw(i,j,k)=fw(i,j,k)+ & rhostrw(i,j,k)*(pttemk+pttemk1 & -buoy2swt*(pttemk*pttemk+pttemk1*pttemk1 & +tema*(ptemk*pttemk + ptemk1*pttemk1))) & *g05*tem4(i,j,k) END DO END DO END DO END IF ! !----------------------------------------------------------------------- ! ! tem3=fp-dtsml*rhostr*csndsq*tacoef* d(wcontuv)/dz /(j3*j3) ! !----------------------------------------------------------------------- ! tema = tacoef*dtsml1*dzinv DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 tem3(i,j,k)=fp(i,j,k)-tema*csj32irst(i,j,k) & *(wcontuv(i,j,k+1)-wcontuv(i,j,k)) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! fw=fw-tacoef*d(tem3)/dz-g*tacoef*avgz(rhostr*tem3/(cpdcv*pbar))) ! !----------------------------------------------------------------------- ! tema = g05wp/cpdcv DO k=3,nz-2 DO j=1,ny-1 DO i=1,nx-1 fw(i,j,k)=fw(i,j,k)-tacoef*tem4(i,j,k)*( & (tem3(i,j,k)-tem3(i,j,k-1))*dzinv + & (rstpbi(i,j,k )*tem3(i,j,k ) & +rstpbi(i,j,k-1)*tem3(i,j,k-1))*tema) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! fw=fw*dtsml/rhostr + w ! !----------------------------------------------------------------------- ! DO k=3,nz-2 DO j=1,ny-1 DO i=1,nx-1 fw(i,j,k)=dtsml1*(fw(i,j,k)*rstwi(i,j,k)) + w(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Prepare the left-hand-side coefficents for tridiagonal ! equation set: ! ! A(k)*w(k-1)+B(k)*w(k)+C(k)*w(k+1)=D(k) for k=3,nz-2 ! ! w(2) and w(nz-1) are used as the boundary conditions. ! ! Due to the lack of work arrays, we are storing the coefficients ! A in rhostru, B in rhostrv, and C in rhostrw. D is stored in fw. ! ! rhostru, rhostrv and rhostrw are re-calculated from rhostr after ! they have been used. ! !----------------------------------------------------------------------- ! DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 tem1(i,j,k)= g05pr*j3irst(i,j,k) tem2(i,j,k)= dzinv*csj32irst(i,j,k) END DO END DO END DO tema = (dtsml1*tacoef)**2 * wpprt*g/cpdcv temb = (dtsml1*tacoef)**2 * dzinv DO k=3,nz-2 DO j=1,ny-1 DO i=1,nx-1 pk = tem4(i,j,k)*tema*pbzi(i,j,k) nk = tem4(i,j,k)*temb*rstwi(i,j,k) rhostru(i,j,k)= (-nk+pk)*(tem1(i,j,k-1)+tem2(i,j,k-1)) rhostrw(i,j,k)= ( nk+pk)*(tem1(i,j,k )-tem2(i,j,k )) rhostrv(i,j,k)= 1 & +nk*(tem1(i,j,k)+tem2(i,j,k)-tem1(i,j,k-1)+tem2(i,j,k-1)) & +pk*(tem1(i,j,k)+tem2(i,j,k)+tem1(i,j,k-1)-tem2(i,j,k-1)) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Reset fw on the boundaries using the top and bottom boundary ! conditions of w. ! ! w=0.0 at k=nz-1. At the lower boundary, wcont=0.0, therefore ! w=-wcontuv, where wcontuv was calculated in loop 240. ! !----------------------------------------------------------------------- ! DO j=1,ny-1 DO i=1,nx-1 fw(i,j,3) =fw(i,j,3)+wcontuv(i,j,2)*rhostru(i,j,3) fw(i,j,nz-2)=fw(i,j,nz-2)+0.0*rhostrw(i,j,nz-2) END DO END DO ! !----------------------------------------------------------------------- ! ! Call the tridiagonal solver for either a rigid (tbc=1) or open upper ! boundary condition for w (tbc=4). ! ! For tbc=4, we have a choice of fft's for the upper boundary: ! fftopt =1, periodic fft for linearized hydrostatic radiation condition. ! fftopt =2, even fft for linearized hydrostatic radiation condition. ! ! The references are Klemp and Durran Jas (1983) and Chen (MWR) 1991. ! ! w1 is the coef for w(nz-1) and w2 is the coef. for w(nz-2) in the ! pressure equation. The pressure equation is solved at p(nz-2) ! for w(nz-1). tem2(i,j,nz-2) is the summation of the known terms ! in the pressure equation. The only unknowns are p(nz-2), w(nz-1) ! and w(nz-1) at the new time level. In the tridiagonal solver ! the elimination step is performed and w(nz-2) is given in termsx ! of w(nz-1) and known terms. THe next step is to use the rad. ! condition (in fourier space): ! ! ! p = N * rhobar * w(nz-1) / abs(kx+ky) ! ! The end result is a relation for w(nz-1) given known quantities. ! Trigs1 and trigs2 are the predetermined trig functions used in the ! fft program in tridiag. ! !----------------------------------------------------------------------- IF(tbc == 4)THEN ! apply linear radiation condition to w at nz-1. tema = rhostr(nx/2,ny/2,nz-2)*csndsq(nx/2,ny/2,nz-2)* & j3inv(nx/2,ny/2,nz-2) temb = dtsml1*j3inv(nx/2,ny/2,nz-2) w2=temb*tacoef*(tema*dzinv+g05*prgw*rhostr(nx/2,ny/2,nz-2)) w1=temb*tacoef*(-tema*dzinv+g05*prgw*rhostr(nx/2,ny/2,nz-2)) DO j=1,ny-1 DO i=1,nx-1 tem2(i,j,2)=pprt(i,j,nz-2)+tem3(i,j,nz-2) END DO END DO nrho=SQRT(g/ptbar(nx/2,ny/2,nz-2)*(ptbar(nx/2,ny/2,nz-1) & -ptbar(nx/2,ny/2,nz-3))*dzinv*0.5) & *rhostr(nx/2,ny/2,nz-2)*j3inv(nx/2,ny/2,nz-2) END IF ! !----------------------------------------------------------------------- ! ! NOTE: tem2(1,1,4) is passed into subroutine tridiag and becomes ! a 2-D array of size (nx+1,ny+1). ! !----------------------------------------------------------------------- ! CALL tridiag(nx,ny,nz,rhostru,rhostrv,rhostrw,fw,tem1, & tem2(1,1,1),tem2(1,1,2),w1,w2,nrho,tem2(1,1,3),trigs1,trigs2, & ifax1,ifax2,wsave1,wsave2,vwork1,vwork2,tem2(1,1,4)) ! !----------------------------------------------------------------------- ! ! Restore rhostru, rhostrv and rhostrw after they have been used ! are work arrays. ! !----------------------------------------------------------------------- ! CALL rhouvw(nx,ny,nz,rhostr,rhostru,rhostrv,rhostrw) ! !----------------------------------------------------------------------- ! ! On exit of tridiag, the interior solution of w is stored in fw. ! !----------------------------------------------------------------------- IF(tbc == 4)THEN ! set itema = nz-1 itema = nz-1 ELSE ! set itema = nz-2 itema = nz-2 END IF IF( nestgrd /= 1 .OR. mgrid == 1 ) THEN ! For non-nesting case or the ! base-grid of the nested case DO k=3,itema DO j=1,ny-1 DO i=1,nx-1 w(i,j,k) = fw(i,j,k) END DO END DO END DO !call test_dump (pprt,"XXX2solve_pprt",nx,ny,nz,0,0) IF ( lbcopt == 1 ) THEN ! Internal boundary condition ebc1=ebc wbc1=wbc sbc1=sbc nbc1=nbc IF( ebc == 4 ) ebc1=0 IF( wbc == 4 ) wbc1=0 IF( nbc == 4 ) nbc1=0 IF( sbc == 4 ) sbc1=0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(w,nx,ny,nz,ebc1,wbc1,3,mptag,tem3) CALL mprecv2dew(w,nx,ny,nz,ebc1,wbc1,3,mptag,tem3) CALL mpsend2dns(w,nx,ny,nz,nbc1,sbc1,3,mptag,tem3) CALL mprecv2dns(w,nx,ny,nz,nbc1,sbc1,3,mptag,tem3) END IF CALL acct_interrupt(mp_acct) CALL lbcw(nx,ny,nz,dtsml1,w,wcont,wdteb,wdtwb,wdtnb,wdtsb, & ebc1,wbc1,nbc1,sbc1) CALL acct_stop_inter ELSE ! External boundary condition ebc1 = 3 wbc1 = 3 sbc1 = 3 nbc1 = 3 IF( ebc == 0 ) ebc1 = 0 IF( wbc == 0 ) wbc1 = 0 IF( nbc == 0 ) nbc1 = 0 IF( sbc == 0 ) sbc1 = 0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(w,nx,ny,nz,ebc1,wbc1,3,mptag,tem3) CALL mprecv2dew(w,nx,ny,nz,ebc1,wbc1,3,mptag,tem3) CALL mpsend2dns(w,nx,ny,nz,nbc1,sbc1,3,mptag,tem3) CALL mprecv2dns(w,nx,ny,nz,nbc1,sbc1,3,mptag,tem3) END IF CALL acct_interrupt(mp_acct) CALL lbcw(nx,ny,nz,dtsml1,w,wcont,wdteb,wdtwb,wdtnb,wdtsb, & ebc1,wbc1,nbc1,sbc1) CALL acct_stop_inter END IF ELSE ! For nested interior grid DO k=3,itema DO j=2,ny-2 DO i=2,nx-2 w(i,j,k) = fw(i,j,k) END DO END DO END DO DO k=3,nz-2 DO j=1,ny-1 w( 1,j,k)=w( 1,j,k)+dtsml1 * wdtwb(j,k) w(nx-1,j,k)=w(nx-1,j,k)+dtsml1 * wdteb(j,k) END DO END DO DO k=3,nz-2 DO i=2,nx-2 w(i, 1,k)=w(i, 1,k)+dtsml1 * wdtsb(i,k) w(i,ny-1,k)=w(i,ny-1,k)+dtsml1 * wdtnb(i,k) END DO END DO END IF !call test_dump (pprt,"XXX2Asolve_pprt",nx,ny,nz,0,1) ! !----------------------------------------------------------------------- ! ! Calculate wcont at time tfuture, including the boundary ! points. Wcont at the lateral boundaries is calculated ! from boundary u, v and w. Wcont at the top and bottom ! depends on the boundary condition option. ! !----------------------------------------------------------------------- ! !call test_dump (w,"XXX2sBwc_w1",nx,ny,nz,1,0) CALL wcontra(nx,ny,nz,u,v,w,mapfct,j1,j2,j3,aj3z, & rhostr,rhostru,rhostrv,rhostrw,wcont,tem1,tem2) ! !----------------------------------------------------------------------- ! ! Set the top and bottom boundary conditions for w based on u, v and ! wcont at the top and bottom boundaries. ! !----------------------------------------------------------------------- ! CALL acct_interrupt(bc_acct) CALL vbcw(nx,ny,nz,w,wcont,tbc,bbc,u,v, & rhostr,rhostru,rhostrv,rhostrw, & j1,j2,j3) CALL acct_stop_inter ! !----------------------------------------------------------------------- ! ! Calculate the new pressure ! ! pprt(new) = pprt(old)+fp+dtsml*tacoef/j3* ! (rhostr*g*avg(w)-rhostr/j3*csndsq*difz(j3*wcont)) ! !----------------------------------------------------------------------- tema = tacoef*dtsml1*g05pr temb = tacoef*dtsml1*dzinv IF( nestgrd == 1 .AND. mgrid /= 1 ) THEN ! For nested interior grid DO k=2,nz-2 DO j=2,ny-2 DO i=2,nx-2 pprt(i,j,k)=pprt(i,j,k) + fp(i,j,k) & +tema*j3irst(i,j,k)*(w(i,j,k+1)+w(i,j,k)) & -temb*csj32irst(i,j,k)* & (aj3z(i,j,k+1)*wcont(i,j,k+1)-aj3z(i,j,k)*wcont(i,j,k)) END DO END DO END DO DO k=2,nz-2 DO j=1,ny-1 pprt( 1,j,k)=pprt( 1,j,k)+dtsml1 * pdtwb(j,k) pprt(nx-1,j,k)=pprt(nx-1,j,k)+dtsml1 * pdteb(j,k) END DO END DO DO k=2,nz-2 DO i=2,nx-2 pprt(i, 1,k)=pprt(i, 1,k)+dtsml1 * pdtsb(i,k) pprt(i,ny-1,k)=pprt(i,ny-1,k)+dtsml1 * pdtnb(i,k) END DO END DO ! ! Call the pprt bottom boundary condition subroutine to ! compute the hydrostatic pprt at k=1. ! CALL acct_interrupt(bc_acct) CALL pprtbbc(nx,ny,nz,g05,buoy2swt,rhostr,pprt,ptprt, & pbari,ptbari,phydro, & tem1,tem2) ! tem1 = new pprt at k=1. CALL acct_stop_inter ! bc's for mp not implemented for nested grids CALL acct_interrupt(mp_acct) CALL bcp(nx,ny,nz, dtsml1, pprt, pdteb, pdtwb, pdtnb, pdtsb, & tem1(1,1,1), 0,0,0,0,tbc,bbc) CALL acct_stop_inter ELSE ! For non-nesting case or the ! base-grid of the nested case DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 pprt(i,j,k)=pprt(i,j,k) + fp(i,j,k) & +tema*j3irst(i,j,k)*(w(i,j,k+1)+w(i,j,k)) & -temb*csj32irst(i,j,k)* & (aj3z(i,j,k+1)*wcont(i,j,k+1)-aj3z(i,j,k)*wcont(i,j,k)) END DO END DO END DO IF (noisewrt == 1 .AND. MOD(ncalls(mptr),2) == 0 ) THEN IF(lbcopt == 2) THEN istart=MAX(2,(ngbrz+1)) iend=MIN((nx-2),(nx-ngbrz-1)) jstart=MAX(2,(ngbrz+1)) jend=MIN((ny-2),(ny-ngbrz-1)) ELSE istart=2 iend=nx-2 jstart=2 jend=ny-2 END IF sumdpdt=0. DO k=2,nz-2 DO j=jstart,jend DO i=istart,iend sumdpdt=sumdpdt+abs(fp(i,j,k) & +tema*j3irst(i,j,k)*(w(i,j,k+1)+w(i,j,k)) & -temb*csj32irst(i,j,k)* & (aj3z(i,j,k+1)*wcont(i,j,k+1)-aj3z(i,j,k)*wcont(i,j,k))) END DO END DO END DO sumdpdt=sumdpdt/ & (float((iend-istart+1)*(jend-jstart+1)*(nz-3))*dtsml1) write(nchdpdt1(mptr),'(f10.2,f12.6)') (curtim+2*dtsml1),sumdpdt END IF ! ! Call the pprt bottom boundary condition subroutine to ! compute the hydrostatic pprt at k=1. ! CALL acct_interrupt(bc_acct) CALL pprtbbc(nx,ny,nz,g05,buoy2swt,rhostr,pprt,ptprt, & pbari,ptbari,phydro, & tem1,tem2) ! tem1 = new pprt at k=1. CALL acct_stop_inter ! !----------------------------------------------------------------------- ! ! Apply the boundary conditions for the pressure equation. ! ! For the open boundary case, the boundary value of pprt is ! predicted by the pressure equation. ! !----------------------------------------------------------------------- ! !call test_dump (pprt,"XXX3solve_pprt",nx,ny,nz,0,0) IF( lbcopt == 1 ) THEN ! Internal boundary conditions ebc1=ebc wbc1=wbc sbc1=sbc nbc1=nbc IF( ebc == 4 ) ebc1=0 IF( wbc == 4 ) wbc1=0 IF( nbc == 4 ) nbc1=0 IF( sbc == 4 ) sbc1=0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(pprt,nx,ny,nz,ebc1,wbc1,0,mptag,tem2) CALL mprecv2dew(pprt,nx,ny,nz,ebc1,wbc1,0,mptag,tem2) CALL mpsend2dns(pprt,nx,ny,nz,nbc1,sbc1,0,mptag,tem2) CALL mprecv2dns(pprt,nx,ny,nz,nbc1,sbc1,0,mptag,tem2) END IF CALL acct_interrupt(mp_acct) CALL bcp(nx,ny,nz, dtsml1, pprt, pdteb, pdtwb, pdtnb, pdtsb, & tem1(1,1,1), ebc1,wbc1,nbc1,sbc1,tbc,bbc) CALL acct_stop_inter ELSE ! External boundary condition IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(pprt,nx,ny,nz,0,0,0,mptag,tem2) CALL mprecv2dew(pprt,nx,ny,nz,0,0,0,mptag,tem2) CALL mpsend2dns(pprt,nx,ny,nz,0,0,0,mptag,tem2) CALL mprecv2dns(pprt,nx,ny,nz,0,0,0,mptag,tem2) END IF CALL acct_interrupt(mp_acct) CALL bcp(nx,ny,nz, dtsml1, pprt, pdteb, pdtwb, pdtnb, pdtsb, & tem1(1,1,1), 0,0,0,0,tbc,bbc) CALL exbcp(nx,ny,nz, curtsml, pprt, & exbcbuf(npr0exb),exbcbuf(nprdtexb)) CALL acct_stop_inter END IF END IF !call test_dump (pprt,"XXX3Asolve_pprt",nx,ny,nz,0,1) RETURN END SUBROUTINE solvwpim !################################################################## !################################################################## !###### ###### !###### SUBROUTINE SOLVWPIM1 ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE solvwpim1(nx,ny,nz,exbcbufsz, dtsml1, curtsml, & 1,49 u,v,w,wcont,ptprt,pprt,phydro, & wdteb,wdtwb,wdtnb,wdtsb,pdteb,pdtwb,pdtnb,pdtsb, & rhostr,ptbar,ptbari,pbari,csndsq, & wforce,wpgrad,pforce, & x,y,z,zp, mapfct, j1,j2,j3,aj3z,j3inv, & trigs1,trigs2,ifax1,ifax2, & wsave1,wsave2,vwork1,vwork2, & rhostru,rhostrv,rhostrw, & exbcbuf,rhofct, & fw,fp,tem1,tem2,tem3,tem4,tem5, & rstpbi,rstptbi,rstwi,pbzi,rstj3i) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Perform the time integration of w and pressure equations using ! implicit scheme in vertical direction. The acoustically inactive ! forcing terms in these equations have been evaluated prior to this ! subroutine and are stored in wforce and pforce. ! ! This routine is for peqopt=2. ! !----------------------------------------------------------------------- ! ! ! AUTHOR: M. Xue ! 4/26/1996. ! Written for peqopt=2 based on SOLVWPIM. ! ! MODIFICATION HISTORY: ! ! 07/22/97 (D. Weber) ! Added wsave1,wsave2,vwork1,vwork2 for use in the even fft version ! of the upper w-p radiation condition (fftopt=2). ! ! 10/21/97 (Donghai Wang) ! Using total density (rho) in the calculation of the pressure ! gradient force terms. ! ! 10/21/97 (Donghai Wang) ! Added the second order terms in the linerized buoyancy terms. ! ! 11/05/97 (D. Weber) ! Added phydro array for use in the bottom boundary condition for ! perturbation pressure (hydrostatic). ! ! 11/06/97 (D. Weber) ! Added three additional levels to the mapfct array. The three ! levels (4,5,6) represent the inverse of the first three in order. ! The inverse map factors are computed to improve efficiency. ! Removed multiplication of constants from loops. ! ! 9/18/98 (D. Weber) ! Added arrays aj3z ptbari,pbari,rstpbi,rstptbi,rstwi,pbzi, ! rstj3i to improve code efficiency. ! !----------------------------------------------------------------------- ! ! INPUT : ! ! nx Number of grid points in the x-direction (east/west) ! ny Number of grid points in the y-direction (north/south) ! nz Number of grid points in the vertical ! ! dtsml1 Local value of small time step size ! curtsml Local curttim at a small time step ! ! u x component of velocity at tfuture (m/s) ! v y component of velocity at tfuture (m/s) ! w Vertical component of Cartesian velocity at tfuture ! (m/s) ! wcont Contravariant vertical velocity (m/s) ! ptprt Perturbation potential temperature at time tpresent (K) ! pprt Perturbation pressure at time tpresent (Pascal) ! ! wdteb Time tendency of the w field at the east boundary ! wdtwb Time tendency of the w field at the west boundary ! wdtnb Time tendency of the w field at the north boundary ! wdtsb Time tendency of the w field at the south boundary ! ! pdteb Time tendency of the pressure field at the east ! boundary ! pdtwb Time tendency of the pressure field at the west ! boundary ! pdtnb Time tendency of the pressure field at the north ! boundary ! pdtsb Time tendency of the pressure field at the south ! boundary ! ! phydro Big time step forcing term for use in computing the ! hydrostatic pressure at k=1. ! ! rhostr Base state density rhobar times j3 (kg/m**3) ! ptbar Base state potential temperature (K) ! ptbari Inverse base state potential temperature (K) ! pbari Inverse base state pressure (Pascal) ! csndsq Sound wave speed squared. ! ! wforce Acoustically inactive forcing terms in w-eq. ! (kg/(m*s)**2) ! wpgrad Pressure gradient term in w-eq. (kg/(m*s)**2) ! pforce Acoustically inactive terms in pressure eq. (Pascal/s) ! ! 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) ! ! mapfct Map factors at scalar, u and v points ! ! j1 Coordinate transformation Jacobian -d(zp)/dx ! j2 Coordinate transformation Jacobian -d(zp)/dy ! j3 Coordinate transformation Jacobian d(zp)/dz ! aj3z Avgz of the coordinate transformation Jacobian d(zp)/dz ! trigs1 Array containing pre-computed trig function for ! fftopt=1. ! trigs2 Array containing pre-computed trig function for ! fftopt=1. ! ifax1 Array containing the factors of nx for fftopt=1. ! ifax2 Array containing the factors of ny for fftopt=1. ! ! vwork1 2-D work array for fftopt=2. ! vwork2 2-D work array for fftopt=2. ! wsave1 Work array for fftopt=2. ! wsave2 Work array for fftopt=2. ! ! rhostru Average rhostr at u points (kg/m**3). ! rhostrv Average rhostr at v points (kg/m**3). ! rhostrw Average rhostr at w points (kg/m**3). ! ! OUTPUT: ! ! pprt Perturbation pressure at tfuture updated in time ! by dtsml1 (Pascal) ! w Vertical component of Cartesian velocity at tfuture ! updated in time by dtsml1 (m/s) ! ! WORK ARRAYS: ! ! fw Work array to carry force terms in w-eqation. ! fp Work array to carry force terms in p-eqation. ! tem1 Work array ! tem2 Work array ! tem3 Work array ! tem4 Work array ! tem5 Work array ! rstpbi pbari*rhostr ! rstptbi ptbari*rhostr ! rstwi 1/rhostrw ! pbzi 2/avgz(pbar) ! rstj3i rhostr*j3inv ! !----------------------------------------------------------------------- ! ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! Force explicit declarations INTEGER :: nx, ny, nz ! Number of grid points in 3 directions REAL :: dtsml1 ! Local small time step size (s) REAL :: curtsml ! Local curttim at a small time step REAL :: u (nx,ny,nz) ! u-velocity at tfuture (m/s) REAL :: v (nx,ny,nz) ! v-velocity at tfuture (m/s) REAL :: w (nx,ny,nz) ! w-velocity at tfuture (m/s) REAL :: wcont (nx,ny,nz) ! Contravariant vertical velocity (m/s) REAL :: ptprt (nx,ny,nz) ! Perturbation potential temperature (K) REAL :: pprt (nx,ny,nz) ! Perturbation pressure at tfuture ! (Pascal) REAL :: wdteb (ny,nz) ! Time tendency of w at east boundary REAL :: wdtwb (ny,nz) ! Time tendency of w at west boundary REAL :: wdtnb (nx,nz) ! Time tendency of w at north boundary REAL :: wdtsb (nx,nz) ! Time tendency of w at south boundary REAL :: pdteb (ny,nz) ! Time tendency of pressure at east ! boundary REAL :: pdtwb (ny,nz) ! Time tendency of pressure at west ! boundary REAL :: pdtnb (nx,nz) ! Time tendency of pressure at north ! boundary REAL :: pdtsb (nx,nz) ! Time tendency of pressure at south ! boundary REAL :: phydro(nx,ny) ! Big time step forcing for computing ! hydrostatic pprt at k=1. REAL :: rhostr(nx,ny,nz) ! Base state density rhobar times j3. REAL :: ptbar (nx,ny,nz) ! Base state potential temperature (K) REAL :: ptbari(nx,ny,nz) ! Inverse base state pot. temperature (K) REAL :: pbari (nx,ny,nz) ! Inverse base state pressure (Pascal). REAL :: csndsq(nx,ny,nz) ! Sound wave speed squared. REAL :: wforce(nx,ny,nz) ! Acoustically inactive forcing terms ! in w-momentum equation (kg/(m*s)**2) REAL :: wpgrad(nx,ny,nz) ! Pressure gradient term in w-eq. ! (kg/(m*s)**2) REAL :: pforce(nx,ny,nz) ! Acoustically inactive forcing terms ! in the pressure equation (Pascal/s) REAL :: x (nx) ! x-coord. of the physical and compu- ! tational grid. Defined at u-point. REAL :: y (ny) ! y-coord. of the physical and compu- ! tational grid. Defined at v-point. REAL :: z (nz) ! z-coord. of the computational grid. ! Defined at w-point on the staggered ! grid. REAL :: zp (nx,ny,nz) ! Physical height coordinate defined at ! w-point of the staggered grid. REAL :: mapfct(nx,ny,8) ! Map factors at scalar, u and v points REAL :: j1 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as - d( zp )/d( x ). REAL :: j2 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as - d( zp )/d( y ). REAL :: j3 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as d( zp )/d( z ). REAL :: aj3z (nx,ny,nz) ! Coordinate transformation Jacobian defined ! as d( zp )/d( z ) AVERAGED IN THE Z-DIR. REAL :: j3inv (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as d( zp )/d( z ). INTEGER :: exbcbufsz ! EXBC buffer size REAL :: exbcbuf( exbcbufsz ) ! EXBC buffer array REAL :: rhofct(nx,ny,nz) ! rho-factor: rhobar/rho REAL :: trigs1(3*(nx-1)/2+1) ! Array containing pre-computed trig ! function for fftopt=1. REAL :: trigs2(3*(ny-1)/2+1) ! Array containing pre-computed trig ! function for fftopt=1. INTEGER :: ifax1(13) ! Array containing the factors of nx ! for fftopt=1. INTEGER :: ifax2(13) ! Array containing the factors of ny ! for fftopt=1. REAL :: vwork1 (nx+1,ny+1) ! 2-D work array for fftopt=2 option. REAL :: vwork2 (ny,nx+1) ! 2-D work array for fftopt=2 option. REAL :: wsave1 (3*(ny-1)+15) ! Work array for fftopt=2 option. REAL :: wsave2 (3*(nx-1)+15) ! Work array for fftopt=2 option. REAL :: rhostru(nx,ny,nz) ! Averaged rhostr at u points (kg/m**3). REAL :: rhostrv(nx,ny,nz) ! Averaged rhostr at v points (kg/m**3). REAL :: rhostrw(nx,ny,nz) ! Averaged rhostr at w points (kg/m**3). ! !----------------------------------------------------------------------- ! ! Temporary WORK ARRAYS: ! !----------------------------------------------------------------------- ! REAL :: fp (nx,ny,nz) ! Pressure gradient term in w-eq. REAL :: fw (nx,ny,nz) ! Force in w equation.(kg/(m*s)**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 :: rstpbi(nx,ny,nz) ! pbari*rhostr REAL :: rstptbi(nx,ny,nz) ! ptbari*rhostr REAL :: rstwi (nx,ny,nz) ! 1/rhostrw REAL :: pbzi (nx,ny,nz) ! 2/avgz(pbar) REAL :: rstj3i(nx,ny,nz) ! rhostr*j3inv ! !----------------------------------------------------------------------- ! ! Misc. local variables: ! !----------------------------------------------------------------------- ! INTEGER :: i, j, k INTEGER :: ebc1,wbc1,nbc1,sbc1 REAL :: g05,pk,nk,g05wp INTEGER :: wpprt, itema REAL :: tema,temb,w1,w2,nrho INTEGER :: prgw INTEGER :: buoy2swt !Switch for 1st-order or 2nd-order in buoyancy INTEGER :: mptag ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'globcst.inc' INCLUDE 'grid.inc' ! Grid & map parameters. INCLUDE 'bndry.inc' INCLUDE 'exbc.inc' INCLUDE 'phycst.inc' ! Physical constants INCLUDE 'mp.inc' ! Message passing parameters. ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! IF( bsnesq == 1 ) THEN wpprt = 0 ! Switch for pprt/(rhobar*csndsq) term in w-eq. ELSE wpprt = 1 ! Switch for pprt/(rhobar*csndsq) term in w-eq. END IF prgw = 0 g05 = g*0.5 g05wp = g05*wpprt ! !----------------------------------------------------------------------- ! ! Calculate the horizontal velocity divergence using newly updated ! u and v velocity plus half vertical divergence from wcont, and ! store the result in tem3. ! ! Namely, tem3 = difx(u*avgx(j3))+dify(v*avgy(j3))+ ! (1-tacoef)*difz(wcont*avgz(j3)) ! !----------------------------------------------------------------------- ! DO k= 2,nz-2 DO j= 1,ny-1 DO i= 1,nx tem1(i,j,k)=u(i,j,k)*rhostru(i,j,k)*mapfct(i,j,5) END DO END DO END DO DO k= 2,nz-2 DO j= 1,ny DO i= 1,nx-1 tem2(i,j,k)=v(i,j,k)*rhostrv(i,j,k)*mapfct(i,j,6) END DO END DO END DO DO k= 2,nz-1 DO j= 1,ny-1 DO i= 1,nx-1 tem3(i,j,k)=wcont(i,j,k)*rhostrw(i,j,k) END DO END DO END DO DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 tem4(i,j,k)=mapfct(i,j,7) & *((tem1(i+1,j,k)-tem1(i,j,k))*dxinv & +(tem2(i,j+1,k)-tem2(i,j,k))*dyinv) & +(tem3(i,j,k+1)-tem3(i,j,k))*dzinv*(1.0-tacoef) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Compute the forcing terms in pressure equation ! ! fp = dtsml/j3 *(pforce-csndsq*tem4) ! ! rhostr*g*w is the base state pressure advection term. ! !----------------------------------------------------------------------- ! DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 ! fp(i,j,k)=dtsml1*j3inv(i,j,k) * ! : (pforce(i,j,k)-csndsq(i,j,k)*tem4(i,j,k)) fp(i,j,k)=pforce(i,j,k) -dtsml1*j3inv(i,j,k)* & csndsq(i,j,k)*tem4(i,j,k) END DO END DO END DO !----------------------------------------------------------------------- ! ! Compute two more terms in fp related to coordinate transformation: ! ! tem3 = (avgx(avgz(ustr)*j1)+avgy(avgz(vstr)*j2))/avgz(j3) ! !----------------------------------------------------------------------- ! IF( ternopt /= 0 ) THEN DO k= 1,nz-1 DO j= 1,ny-1 DO i= 1,nx tem1(i,j,k)=u(i,j,k)*rhostru(i,j,k) END DO END DO END DO DO k= 1,nz-1 DO j= 1,ny DO i= 1,nx-1 tem2(i,j,k)=v(i,j,k)*rhostrv(i,j,k) END DO END DO END DO DO k= 2,nz-1 DO j= 1,ny-1 DO i= 1,nx-1 tem3(i,j,k)=((tem1(i ,j,k)+tem1(i ,j,k-1))*j1(i ,j,k) & +(tem1(i+1,j,k)+tem1(i+1,j,k-1))*j1(i+1,j,k) & +(tem2(i ,j,k)+tem2(i ,j,k-1))*j2(i ,j,k) & +(tem2(i,j+1,k)+tem2(i,j+1,k-1))*j2(i,j+1,k)) & *mapfct(i,j,8)/aj3z(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! fp=fp-(dtsml/j3)*csndsq*tacoef* d(tem3)/dz ! !----------------------------------------------------------------------- ! DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 fp(i,j,k)=fp(i,j,k) & -dtsml1*j3inv(i,j,k)*csndsq(i,j,k) & *tacoef*(tem3(i,j,k+1)-tem3(i,j,k))*dzinv END DO END DO END DO END IF ! !----------------------------------------------------------------------- ! ! Average rhofct at w points, stored in tem5 ! !----------------------------------------------------------------------- ! CALL avgsw(rhofct,nx,ny,nz, 1,nx-1, 1,ny-1,tem5) ! !----------------------------------------------------------------------- ! ! Compute the right-hand-side forcing term in tridiagonal linear ! equation. Array w is used to store this forcing term. ! !----------------------------------------------------------------------- !----------------------------------------------------------------------- ! ! fw=wforce-wpgrad-tacoef*d(fp)/dz ! -g*avgz(rhostr*(pprt+taceof*pfrc)/(gamma*pbar)) ! !----------------------------------------------------------------------- ! IF ( buoy2nd == 0) THEN !1st-order buoy2swt = 0 !Switch for 1st-order or 2nd-order ELSE !2nd-order buoy2swt = 1 END IF tema = 0.5*buoy2swt*(1.0-cpdcv)/cpdcv temb = 1.0/cpdcv DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 ! tem1(i,j,k)=tem6(i,j,k)*((pprt(i,j,k)+tacoef*fp(i,j,k)) tem1(i,j,k)=rstpbi(i,j,k)*((pprt(i,j,k)+tacoef*fp(i,j,k)) & +tema*pprt(i,j,k)*pprt(i,j,k) & *pbari(i,j,k))*temb END DO END DO END DO ! !----------------------------------------------------------------------- ! ! When potential temperature equation is solved within small time ! steps, the contribution from ptprt to buoyancy term is calculated ! here. ! !----------------------------------------------------------------------- ! IF( ptsmlstp == 1 ) THEN DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 ! tem2(i,j,k)= ptprt(i,j,k)*tem7(i,j,k) tem2(i,j,k)= ptprt(i,j,k)*rstptbi(i,j,k) & *(1.0-buoy2swt*ptprt(i,j,k)*ptbari(i,j,k)) END DO END DO END DO ELSE DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 tem2(i,j,k)= 0.0 END DO END DO END DO END IF tema = tacoef*dzinv DO k=3,nz-2 DO j=1,ny-1 DO i=1,nx-1 fw(i,j,k) = wforce(i,j,k)-tem5(i,j,k)*(wpgrad(i,j,k) & +tema*(fp(i,j,k)-fp(i,j,k-1)) & +g05wp*(tem1(i,j,k)+tem1(i,j,k-1)) & -g05 *(tem2(i,j,k)+tem2(i,j,k-1))) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! fw=fw*dtsml/rhostr + w ! !----------------------------------------------------------------------- ! DO k=3,nz-2 DO j=1,ny-1 DO i=1,nx-1 ! fw(i,j,k)=fw(i,j,k)*dtsml1*tem8(i,j,k) + w(i,j,k) fw(i,j,k)=fw(i,j,k)*dtsml1*rstwi(i,j,k) + w(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Prepare the left-hand-side coefficents for tridiagonal ! equation set: ! ! A(k)*w(k-1)+B(k)*w(k)+C(k)*w(k+1)=D(k) for k=3,nz-2 ! ! w(2) and w(nz-1) are used as the boundary conditions. ! ! Due to the lack of work arrays, we are storing the coefficients ! A in rhostru, B in rhostrv, and C in rhostrw. D is stored in fw. ! ! rhostru, rhostrv and rhostrw are re-calculated from rhostr after ! they have been used. ! !----------------------------------------------------------------------- ! DO k=2,nz-1 DO j=1,ny-1 DO i=1,nx-1 ! tem4(i,j,k)=0.5*(tem10(i,j,k) +tem10(i,j,k-1)) tem4(i,j,k)=0.5*(rstj3i(i,j,k)+ rstj3i(i,j,k-1)) END DO END DO END DO tema = (dtsml1*tacoef)**2 * wpprt*g*dzinv /cpdcv temb = (dtsml1*tacoef*dzinv)**2 DO k=3,nz-2 DO j=1,ny-1 DO i=1,nx-1 ! pk = tem5(i,j,k)*tema*tem9(i,j,k) pk = tem5(i,j,k)*tema*pbzi(i,j,k) nk = tem5(i,j,k)*temb*rstwi(i,j,k) ! nk = tem5(i,j,k)*temb*tem8(i,j,k) tem1(i,j,k)= (-nk+pk)*csndsq(i,j,k-1)*j3inv(i,j,k-1) tem3(i,j,k)=-( nk+pk)*csndsq(i,j,k )*j3inv(i,j,k ) tem2(i,j,k)= 1-tem4(i,j,k)*(tem1(i,j,k)+tem3(i,j,k)) tem1(i,j,k)=tem1(i,j,k)*tem4(i,j,k-1) tem3(i,j,k)=tem3(i,j,k)*tem4(i,j,k+1) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Reset fw on the boundaries using the top and bottom boundary ! conditions of w. ! !----------------------------------------------------------------------- ! DO j=1,ny-1 DO i=1,nx-1 w(i,j,nz-1)=0.0 w(i,j,2) =-((u(i ,j,2)+u(i ,j,1))*j1(i,j,2) & +(u(i+1,j,2)+u(i+1,j,1))*j1(i+1,j,2) & +(v(i,j ,2)+v(i,j ,1))*j2(i,j,2) & +(v(i,j+1,2)+v(i,j+1,1))*j2(i,j+1,2)) & *mapfct(i,j,8) END DO END DO DO j=1,ny-1 DO i=1,nx-1 fw(i,j,3) =fw(i,j, 3)-w(i,j, 2)*tem1(i,j, 3) fw(i,j,nz-2)=fw(i,j,nz-2)-w(i,j,nz-1)*tem3(i,j,nz-2) END DO END DO ! !----------------------------------------------------------------------- ! ! Call the tridiagonal solver for either a rigid or open upper ! boundary condition for w. ! ! tbc = 4, periodic fft for linearized hydrostatic radiation condition. ! tbc = 6, even fft for linearized hydrostatic radiation condition. ! The references are Klemp and Durran Jas (1983) and Chen (MWR) 1991. ! ! w1 is the coef for w(nz-1) and w2 is the coef. for w(nz-2 in the ! pressure equation. The pressure equation is solved at p(nz-2 ! for w(nz-1). tem4(i,j,nz-2) is the summation of the known terms ! in the pressure equation. The only unknowns are p(nz-2), w(nz-1) ! and w(nz-1) at the new time level. In the tridiagonal solver ! the elimination step is performed and w(nz-2) is given in termsx ! of w(nz-1) and known terms. THe next step is to use the rad. ! condition (in fourier space): ! ! ! p = N * rhobar * w(nz-1) / abs(kx+ky) ! ! The end result is a relation for w(nz-1) given known quantities. ! Trigs1 and trigs2 are the predetermined trig functions used in the ! fft program in tridiag. ! !----------------------------------------------------------------------- IF(tbc == 4)THEN ! apply linear radiation condition to w at nz-1. tema = rhostr(nx/2,ny/2,nz-2)*csndsq(nx/2,ny/2,nz-2)* & j3inv(nx/2,ny/2,nz-2) temb = dtsml1*j3inv(nx/2,ny/2,nz-2) w2=temb*tacoef*(tema*dzinv+g05*prgw*rhostr(nx/2,ny/2,nz-2)) w1=temb*tacoef*(-tema*dzinv+g05*prgw*rhostr(nx/2,ny/2,nz-2)) DO j=1,ny-1 DO i=1,nx-1 tem4(i,j,2)=pprt(i,j,nz-2)+fp(i,j,nz-2) END DO END DO nrho=SQRT(g/ptbar(nx/2,ny/2,nz-2)*(ptbar(nx/2,ny/2,nz-1) & -ptbar(nx/2,ny/2,nz-3))*dzinv*0.5) & *rhostr(nx/2,ny/2,nz-2)*j3inv(nx/2,ny/2,nz-2) END IF ! !----------------------------------------------------------------------- ! ! NOTE: tem4(1,1,4) is passed into subroutine tridiag and becomes ! a 2-D array of size (nx+1,ny+1). ! ! rhostrw is used as a work array in tridiag. ! !----------------------------------------------------------------------- ! CALL tridiag(nx,ny,nz,tem1,tem2,tem3,fw,rhostrw, & tem4(1,1,1),tem4(1,1,2),w1,w2,nrho,tem4(1,1,3), & trigs1,trigs2,ifax1,ifax2,wsave1,wsave2,vwork1,vwork2, & tem4(1,1,4)) CALL avgsw(rhostr,nx,ny,nz, 1,nx-1, 1,ny-1, rhostrw) ! call TRIDIAG_old(nx,ny,nz,tem1,tem2,tem3,fw, tem4) ! !----------------------------------------------------------------------- ! ! On exit of tridiag, the interior solution of w is stored in fw. ! !----------------------------------------------------------------------- IF(tbc == 4)THEN ! set itema = nz-1 itema = nz-1 ELSE ! set itema = nz-2 itema = nz-2 END IF IF( nestgrd /= 1 .OR. mgrid == 1 ) THEN ! For non-nesting case or the ! base-grid of the nested case DO k=3,itema DO j=1,ny-1 DO i=1,nx-1 w(i,j,k) = fw(i,j,k) END DO END DO END DO !call test_dump (pprt,"XXX4solve_pprt",nx,ny,nz,0,0) IF ( lbcopt == 1 ) THEN ! Internal boundary condition ebc1=ebc wbc1=wbc sbc1=sbc nbc1=nbc IF( ebc == 4 ) ebc1=0 IF( wbc == 4 ) wbc1=0 IF( nbc == 4 ) nbc1=0 IF( sbc == 4 ) sbc1=0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(w,nx,ny,nz,ebc1,wbc1,3,mptag,tem3) CALL mprecv2dew(w,nx,ny,nz,ebc1,wbc1,3,mptag,tem3) CALL mpsend2dns(w,nx,ny,nz,nbc1,sbc1,3,mptag,tem3) CALL mprecv2dns(w,nx,ny,nz,nbc1,sbc1,3,mptag,tem3) END IF CALL acct_interrupt(mp_acct) CALL lbcw(nx,ny,nz,dtsml1,w,wcont,wdteb,wdtwb,wdtnb,wdtsb, & ebc1,wbc1,nbc1,sbc1) CALL acct_stop_inter ELSE ! External boundary condition ebc1 = 3 wbc1 = 3 sbc1 = 3 nbc1 = 3 IF( ebc == 0 ) ebc1 = 0 IF( wbc == 0 ) wbc1 = 0 IF( nbc == 0 ) nbc1 = 0 IF( sbc == 0 ) sbc1 = 0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(w,nx,ny,nz,ebc1,wbc1,3,mptag,tem3) CALL mprecv2dew(w,nx,ny,nz,ebc1,wbc1,3,mptag,tem3) CALL mpsend2dns(w,nx,ny,nz,nbc1,sbc1,3,mptag,tem3) CALL mprecv2dns(w,nx,ny,nz,nbc1,sbc1,3,mptag,tem3) END IF CALL acct_interrupt(mp_acct) CALL lbcw(nx,ny,nz,dtsml1,w,wcont,wdteb,wdtwb,wdtnb,wdtsb, & ebc1,wbc1,nbc1,sbc1) CALL acct_stop_inter END IF ELSE ! For nested interior grid DO k=3,itema DO j=2,ny-2 DO i=2,nx-2 w(i,j,k) = fw(i,j,k) END DO END DO END DO DO k=3,nz-2 DO j=1,ny-1 w( 1,j,k)=w( 1,j,k)+dtsml1 * wdtwb(j,k) w(nx-1,j,k)=w(nx-1,j,k)+dtsml1 * wdteb(j,k) END DO END DO DO k=3,nz-2 DO i=2,nx-2 w(i, 1,k)=w(i, 1,k)+dtsml1 * wdtsb(i,k) w(i,ny-1,k)=w(i,ny-1,k)+dtsml1 * wdtnb(i,k) END DO END DO END IF !call test_dump (pprt,"XXX4Asolve_pprt",nx,ny,nz,0,1) ! !----------------------------------------------------------------------- ! ! Calculate wcont at time tfuture, including the boundary ! points. Wcont at the lateral boundaries is calculated ! from boundary u, v and w. Wcont at the top and bottom ! depends on the boundary condition option. ! !----------------------------------------------------------------------- ! !call test_dump (w,"XXX3sBwc_w1",nx,ny,nz,1,0) CALL wcontra(nx,ny,nz,u,v,w,mapfct,j1,j2,j3,aj3z, & rhostr,rhostru,rhostrv,rhostrw,wcont,tem1,tem2) ! !----------------------------------------------------------------------- ! ! Set the top and bottom boundary conditions for w based on u, v and ! wcont at the top and bottom boundaries. ! !----------------------------------------------------------------------- ! CALL acct_interrupt(bc_acct) CALL vbcw(nx,ny,nz,w,wcont,tbc,bbc,u,v, & rhostr,rhostru,rhostrv,rhostrw, & j1,j2,j3) CALL acct_stop_inter ! !----------------------------------------------------------------------- ! ! Calculate the new pressure ! ! pprt(new)=pprt(old)+fp-dtsml/j3*tacoef*csndsq*difz(rhobar*w)) ! !----------------------------------------------------------------------- ! tema = tacoef*dtsml1*dzinv DO k=2,nz-1 DO j=1,ny-1 DO i=1,nx-1 ! tem1(i,j,k)= 0.5*(tem10(i,j,k )+tem10(i,j,k-1)) tem1(i,j,k)= 0.5*(rstj3i(i,j,k )+rstj3i(i,j,k-1)) END DO END DO END DO IF( nestgrd == 1 .AND. mgrid /= 1 ) THEN ! For nested interior grid DO k=2,nz-2 DO j=2,ny-2 DO i=2,nx-2 pprt(i,j,k) = pprt(i,j,k) + fp(i,j,k) & - tema*j3inv(i,j,k)*csndsq(i,j,k) & * (tem1(i,j,k+1)*w(i,j,k+1)-tem1(i,j,k)*w(i,j,k)) END DO END DO END DO DO k=2,nz-2 DO j=1,ny-1 pprt( 1,j,k)=pprt( 1,j,k)+dtsml1 * pdtwb(j,k) pprt(nx-1,j,k)=pprt(nx-1,j,k)+dtsml1 * pdteb(j,k) END DO END DO DO k=2,nz-2 DO i=2,nx-2 pprt(i, 1,k)=pprt(i, 1,k)+dtsml1 * pdtsb(i,k) pprt(i,ny-1,k)=pprt(i,ny-1,k)+dtsml1 * pdtnb(i,k) END DO END DO ! ! Call the pprt bottom boundary condition subroutine to ! compute the hydrostatic pprt at k=1. ! CALL acct_interrupt(bc_acct) CALL pprtbbc(nx,ny,nz,g05,buoy2swt,rhostr,pprt,ptprt, & pbari,ptbari,phydro, & tem1,tem2) ! tem1 = new pprt at k=1. CALL acct_stop_inter ! bc's for mp not implemented for nested grids CALL acct_interrupt(mp_acct) CALL bcp(nx,ny,nz, dtsml1, pprt, pdteb, pdtwb, pdtnb, pdtsb, & tem1(1,1,1), 0,0,0,0 ,tbc,bbc) CALL acct_stop_inter ELSE ! For non-nesting case or the ! base-grid of the nested case DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 pprt(i,j,k) = pprt(i,j,k) + fp(i,j,k) & - tema*j3inv(i,j,k)*csndsq(i,j,k) & * (tem1(i,j,k+1)*w(i,j,k+1)-tem1(i,j,k)*w(i,j,k)) END DO END DO END DO ! ! Call the pprt bottom boundary condition subroutine to ! compute the hydrostatic pprt at k=1. ! CALL acct_interrupt(bc_acct) CALL pprtbbc(nx,ny,nz,g05,buoy2swt,rhostr,pprt,ptprt, & pbari,ptbari,phydro, & tem1,tem2) ! tem1 = new pprt at k=1. CALL acct_stop_inter ! !----------------------------------------------------------------------- ! ! Apply the boundary conditions for the pressure equation. ! ! For the open boundary case, the boundary value of pprt is ! predicted by the pressure equation. ! !----------------------------------------------------------------------- ! !call test_dump (pprt,"XXX5solve_pprt",nx,ny,nz,0,0) IF( lbcopt == 1 ) THEN ! Internal boundary conditions ebc1=ebc wbc1=wbc sbc1=sbc nbc1=nbc IF( ebc == 4 ) ebc1=0 IF( wbc == 4 ) wbc1=0 IF( nbc == 4 ) nbc1=0 IF( sbc == 4 ) sbc1=0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(pprt,nx,ny,nz,ebc1,wbc1,0,mptag,tem2) CALL mprecv2dew(pprt,nx,ny,nz,ebc1,wbc1,0,mptag,tem2) CALL mpsend2dns(pprt,nx,ny,nz,nbc1,sbc1,0,mptag,tem2) CALL mprecv2dns(pprt,nx,ny,nz,nbc1,sbc1,0,mptag,tem2) END IF CALL acct_interrupt(mp_acct) CALL bcp(nx,ny,nz, dtsml1, pprt, pdteb, pdtwb, pdtnb, pdtsb, & tem1(1,1,1), ebc1,wbc1,nbc1,sbc1,tbc,bbc) CALL acct_stop_inter ELSE ! External boundary condition IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(pprt,nx,ny,nz,0,0,0,mptag,tem2) CALL mprecv2dew(pprt,nx,ny,nz,0,0,0,mptag,tem2) CALL mpsend2dns(pprt,nx,ny,nz,0,0,0,mptag,tem2) CALL mprecv2dns(pprt,nx,ny,nz,0,0,0,mptag,tem2) END IF CALL acct_interrupt(mp_acct) CALL bcp(nx,ny,nz, dtsml1, pprt, pdteb, pdtwb, pdtnb, pdtsb, & tem1(1,1,1), 0,0,0,0,tbc,bbc) CALL exbcp(nx,ny,nz, curtsml, pprt, & exbcbuf(npr0exb),exbcbuf(nprdtexb)) CALL acct_stop_inter END IF END IF !call test_dump (pprt,"XXX5Asolve_pprt",nx,ny,nz,0,1) RETURN END SUBROUTINE solvwpim1 ! ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE TRIDIAG ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE tridiag(nx,ny,nz,a,b,c,d, tem2, tem1, temxy2,w1,w2, & 2,2 nrho,work,trigs1,trigs2,ifax1,ifax2, & wsave1,wsave2,vwork1,vwork2, & temxy1) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Solve a tridiagonal linear equation. ! ! The tridiagonal equation set to be solved is ! ! a(k)*w(k-1)+b(k)*w(k)+c(k)*w(k+1)=d(k) for k=3,nz-2 ! ! given w(2) and w(nz-1) as the boundary conditions. ! ! The solution w(k) is stored directly into d(k). ! ! Reference: Numerical Recipes: FORTRAN Version, 1989. Page 40. ! !----------------------------------------------------------------------- ! ! AUTHOR: Ming Xue ! 9/9/94 ! ! MODIFICATION HISTORY: ! ! 10/31/95 (D. Weber) ! Added linear hydrostatic upper radiation condition for w-p. ! References are Klemp and Durran (JAS, 1983) and Chen (1991). ! Includes the use of trigs1,trigs2,ifax1,ifax2. ! ! 07/22/97 (D. Weber) ! Added linear hydrostatic upper radiation condition for w-p using ! an even fft (fftopt=2). ! !----------------------------------------------------------------------- ! ! INPUT : ! ! nx Number of grid points in the x-direction ! ny Number of grid points in the y-direction ! nz Number of grid points in the vertical ! ! a lhs coefficient of tridigonal eqations ! b lhs coefficient of tridigonal eqations ! c lhs coefficient of tridigonal eqations ! d rhs coefficient of tridigonal eqations ! temxy2 Pforce array at nz-2. ! trigs1 Array containing pre-computed trig function for ! fftopt=1. ! trigs2 Array containing pre-computed trig function for ! fftopt=1. ! ifax1 Array containing the factors of nx for fftopt=1. ! ifax2 Array containing the factors of ny for fftopt=1. ! ! vwork1 2-D work array for fftopt=2 option. ! vwork2 2-D work array for fftopt=2 option. ! wsave1 Work array for fftopt=2. ! wsave2 Work array for fftopt=2. ! ! OUTPUT: ! ! d The solution w. ! ! WORK ARRAYS: ! ! temxy1 Work array at nz-2. ! tem1 Work array ! tem2 Work array ! work Work array for fft. ! !----------------------------------------------------------------------- ! ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! Force explicit declarations ! ! Include files: ! INCLUDE 'bndry.inc' INCLUDE 'globcst.inc' INTEGER :: nx, ny, nz ! Number of grid points in 3 directions REAL :: a (nx,ny,nz) ! lhs coefficient of tridigonal eqations REAL :: b (nx,ny,nz) ! lhs coefficient of tridigonal eqations REAL :: c (nx,ny,nz) ! lhs coefficient of tridigonal eqations REAL :: d (nx,ny,nz) ! rhs coefficient of tridigonal eqations ! The contains solution w on exit. REAL :: temxy2(nx,ny) ! Pforce array at nz-2. REAL :: trigs1(3*(nx-1)/2+1) ! Array containing pre-computed trig ! function for fftopt=1. REAL :: trigs2(3*(ny-1)/2+1) ! Array containing pre-computed trig ! function for fftopt=1. INTEGER :: ifax1(13) ! Array containing the factors of nx for ! fftopt=1. INTEGER :: ifax2(13) ! Array containing the factors of ny for ! fftopt=1. REAL :: vwork1 (nx+1,ny+1) ! 2-D work array for fftopt=2. REAL :: vwork2 (ny,nx+1) ! 2-D work array for fftopt=2. REAL :: wsave1 (3*(ny-1)+15) ! Work array for fftopt=2. REAL :: wsave2 (3*(nx-1)+15) ! Work array for fftopt=2. REAL :: temxy1(nx+1,ny+1) ! Work array at nz-2. REAL :: tem1 (nx,ny) ! 2-D work array. REAL :: tem2 (nx,ny,nz) ! 3-D work array. REAL :: work (ny,nx) ! 2-D work array for fft code. ! !----------------------------------------------------------------------- ! ! Misc. local variables: ! !----------------------------------------------------------------------- ! INTEGER :: i, j, k REAL :: nrho REAL :: w1,w2,wc ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! DO j=1,ny-1 DO i=1,nx-1 d(i,j,3)=d(i,j,3)/b(i,j,3) tem1(i,j)=b(i,j,3) END DO END DO DO k=4,nz-2 DO j=1,ny-1 DO i=1,nx-1 tem2(i,j,k) = c(i,j,k-1)/tem1(i,j) tem1(i,j)=b(i,j,k)-a(i,j,k)*tem2(i,j,k) d(i,j,k)=(d(i,j,k)-a(i,j,k)*d(i,j,k-1))/tem1(i,j) END DO END DO END DO IF(tbc == 4)THEN ! apply upper radiation boundary condition. ! ! Computing the new c(nz-2) (which is stored in nz-1).... ! DO j=1,ny-1 DO i=1,nx-1 tem2(i,j,nz-1) = c(i,j,nz-2)/tem1(i,j) END DO END DO wc = tem2(nx/2,ny/2,nz-1) ! coef. for w(nz-1) in tri. elim. phase ! ! Combining the pforce array and d(nz-2) from the elimination phase. ! Note: these arrays are a function of x and/or y. All others variables ! are determined from base state which are not a function ! of x,y. (note: zflat must be at or below the height of scalar nz-2) ! DO j=1,ny-1 DO i=1,nx-1 temxy1(i,j) = temxy2(i,j) + w2*d(i,j,nz-2) END DO END DO !----------------------------------------------------------------------- ! ! Call the upper radiation subroutine to update w at the top (nz-2) ! !----------------------------------------------------------------------- IF(fftopt == 2)THEN ! call the even vfftpack fft... CALL uprad3(nx,ny,w1,w2,wc,nrho,wsave1,wsave2,vwork1,vwork2, & temxy1,work) ELSE IF(fftopt == 1)THEN ! call the periodic fft.... CALL uprad1(nx,ny,w1,w2,wc,nrho,ifax1,ifax2,trigs1,trigs2, & temxy1,work) END IF ! end of fftopt.... DO j=1,ny-1 DO i=1,nx-1 d(i,j,nz-1) = temxy1(i,j) END DO END DO !----------------------------------------------------------------------- ! ! Perform the back substitution phase of the tridiagonal solver. ! !----------------------------------------------------------------------- DO k=nz-2,3,-1 DO j=1,ny-1 DO i=1,nx-1 d(i,j,k)=d(i,j,k)-tem2(i,j,k+1)*d(i,j,k+1) END DO END DO END DO ELSE IF(tbc /= 4)THEN ! perform backsubtitution for other bc's. DO k=nz-3,3,-1 DO j=1,ny-1 DO i=1,nx-1 d(i,j,k)=d(i,j,k)-tem2(i,j,k+1)*d(i,j,k+1) END DO END DO END DO END IF ! end of tbc loop... RETURN END SUBROUTINE tridiag ! ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE SOLVPT_LRG ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE solvpt_lrg(nx,ny,nz, exbcbufsz, dtbig1, & 1,20 ptprt, ptdteb,ptdtwb,ptdtnb,ptdtsb, & rhostr,rhostri,ptforce, exbcbuf, tem1) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Coordinate the time integration of the potential temperature ! equation in large time steps. ! !----------------------------------------------------------------------- ! ! AUTHOR: Ming Xue ! 10/10/91 ! ! MODIFICATION HISTORY: ! ! 9/17/94 (M. Xue) ! Rewritten for small time step integration of ptprt equation. ! ! 11/6/1995 (M. Xue) ! Added option for fourth order vertical advection for ptbar. ! ! 4/17/96 (M. Xue) ! Removed the block for 4th order advection of ptbar. ! ! 4/24/1997 (M. Xue) ! Rewrote as SOLVPT_LRG based on SOLVPT. ! ! 10/5/1998 (Dan Weber) ! Added rhostri for efficiency. ! !----------------------------------------------------------------------- ! ! INPUT : ! ! nx Number of grid points in the x-direction (east/west) ! ny Number of grid points in the y-direction (north/south) ! nz Number of grid points in the vertical ! ! dtbig1 The big time step size for this call (s) ! ! ptprt Perturbation potential temperature at times tpast and ! tpresent (K) ! ! ptdteb Time tendency of the ptprt field at the east boundary ! ptdtwb Time tendency of the ptprt field at the west boundary ! ptdtnb Time tendency of the ptprt field at the north boundary ! ptdtsb Time tendency of the ptprt field at the south boundary ! ! rhostr Base state density rhobar times j3 (kg/m**3) ! rhostri Inverse base state density rhobar times j3 (kg/m**3) ! ! ptforce Gravity wave inactive forcing terms in pt-eq. ! (K*kg/(m**3*s)) ! ! OUTPUT: ! ! ptprt Perturbation potential temperature at time tfuture (K) ! !----------------------------------------------------------------------- ! ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! Force explicit declarations INCLUDE 'timelvls.inc' INTEGER :: nx, ny, nz ! Number of grid points in 3 directions REAL :: dtbig1 ! The big time step size for this call ! (s) REAL :: ptprt (nx,ny,nz,nt) ! Perturbation potential temperature (K) REAL :: ptdteb(ny,nz) ! Time tendency of ptprt at east ! boundary REAL :: ptdtwb(ny,nz) ! Time tendency of ptprt at west ! boundary REAL :: ptdtnb(nx,nz) ! Time tendency of ptprt at north ! boundary REAL :: ptdtsb(nx,nz) ! Time tendency of ptprt at south ! boundary REAL :: rhostr(nx,ny,nz) ! Base state density rhobar times j3. REAL :: rhostri(nx,ny,nz) ! Inverse base state density rhobar times j3. REAL :: ptforce(nx,ny,nz) ! Gravity wave inactive forcing terms ! in potential temperature eq. ! (K*kg/(m**3*s)) INTEGER :: exbcbufsz ! EXBC buffer size REAL :: exbcbuf( exbcbufsz ) ! EXBC buffer array REAL :: tem1(nx,ny,nz) ! Work array ! !----------------------------------------------------------------------- ! ! Misc. local variables: ! !----------------------------------------------------------------------- ! INTEGER :: i, j, k, tstrtlvl INTEGER :: ebc1,wbc1,nbc1,sbc1 REAL :: deltat INTEGER :: mptag ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'globcst.inc' INCLUDE 'bndry.inc' INCLUDE 'exbc.inc' INCLUDE 'mp.inc' ! Message passing parameters. ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! !----------------------------------------------------------------------- ! ! Integrate forward by one timestep the potential temperature ! equation. When PT-eq. is integrated inside small time steps, ! it is stepped forward by a small time step, otherwise, it is ! stepped forward by a large time step using leapfrog scheme ! (i.e. 2*dtbig1 from ptprt at tpast). ! !----------------------------------------------------------------------- ! IF(sadvopt == 4) THEN ! Forward-based FCT scheme deltat = dtbig1 tstrtlvl = tpresent ELSE deltat = dtbig1*2 tstrtlvl = tpast END IF IF( nestgrd == 1 .AND. mgrid /= 1 ) THEN DO k=2,nz-2 DO j=2,ny-2 DO i=2,nx-2 ptprt(i,j,k,tfuture)=ptprt(i,j,k,tstrtlvl) & +deltat*ptforce(i,j,k)*rhostri(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Integrate PT equation and the boundary conditions for a nested grid. ! !----------------------------------------------------------------------- ! DO k=2,nz-2 DO i=1,nx-1 ptprt(i, 1,k,tfuture)= & 2*ptprt(i, 1,k,tpresent)-ptprt(i, 1,k,tpast) ptprt(i,ny-1,k,tfuture)= & 2*ptprt(i,ny-1,k,tpresent)-ptprt(i,ny-1,k,tpast) END DO END DO DO k=2,nz-2 DO j=2,ny-2 ptprt( 1,j,k,tfuture)= & 2*ptprt( 1,j,k,tpresent)-ptprt( 1,j,k,tpast) ptprt(nx-1,j,k,tfuture)= & 2*ptprt(nx-1,j,k,tpresent)-ptprt(nx-1,j,k,tpast) END DO END DO ! bc's for mp not implemented for nested grids CALL acct_interrupt(mp_acct) CALL bcsclr(nx,ny,nz, deltat*0.5 , & ptprt(1,1,1,tstrtlvl),ptprt(1,1,1,tpresent), & ptprt(1,1,1,tfuture),ptdteb,ptdtwb,ptdtnb,ptdtsb, & 0,0,0,0 ,tbc,bbc) CALL acct_stop_inter ELSE ! !----------------------------------------------------------------------- ! ! Integrate PT equation and the boundary conditions for a base grid. ! !----------------------------------------------------------------------- ! DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 ptprt(i,j,k,tfuture)=ptprt(i,j,k,tstrtlvl) & +deltat*ptforce(i,j,k)*rhostri(i,j,k) END DO END DO END DO !call test_dump (ptprt,"XXXsolve_ptprt",nx,ny,nz,0,0) IF ( lbcopt == 1 ) THEN ! Internal boundary conditions ebc1=ebc wbc1=wbc sbc1=sbc nbc1=nbc IF( ebc == 4 ) ebc1=0 IF( wbc == 4 ) wbc1=0 IF( nbc == 4 ) nbc1=0 IF( sbc == 4 ) sbc1=0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(ptprt(1,1,1,tfuture),nx,ny,nz,ebc1,wbc1,0,mptag,tem1) CALL mprecv2dew(ptprt(1,1,1,tfuture),nx,ny,nz,ebc1,wbc1,0,mptag,tem1) CALL mpsend2dns(ptprt(1,1,1,tfuture),nx,ny,nz,nbc1,sbc1,0,mptag,tem1) CALL mprecv2dns(ptprt(1,1,1,tfuture),nx,ny,nz,nbc1,sbc1,0,mptag,tem1) END IF CALL acct_interrupt(mp_acct) CALL bcsclr(nx,ny,nz, deltat*0.5 , & ptprt(1,1,1,tstrtlvl),ptprt(1,1,1,tpresent), & ptprt(1,1,1,tfuture),ptdteb,ptdtwb,ptdtnb,ptdtsb, & ebc1,wbc1,nbc1,sbc1,tbc,bbc) CALL acct_stop_inter ELSE ! External boundary condition IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(ptprt(1,1,1,tfuture),nx,ny,nz,0,0,0,mptag,tem1) CALL mprecv2dew(ptprt(1,1,1,tfuture),nx,ny,nz,0,0,0,mptag,tem1) CALL mpsend2dns(ptprt(1,1,1,tfuture),nx,ny,nz,0,0,0,mptag,tem1) CALL mprecv2dns(ptprt(1,1,1,tfuture),nx,ny,nz,0,0,0,mptag,tem1) END IF CALL acct_interrupt(mp_acct) CALL bcsclr(nx,ny,nz, deltat*0.5 , & ptprt(1,1,1,tstrtlvl),ptprt(1,1,1,tpresent), & ptprt(1,1,1,tfuture),ptdteb,ptdtwb,ptdtnb,ptdtsb, & 0,0,0,0,tbc,bbc) CALL exbcpt(nx,ny,nz, curtim+dtbig, ptprt(1,1,1,tfuture), & exbcbuf(npt0exb),exbcbuf(nptdtexb)) CALL acct_stop_inter END IF END IF !call test_dump (ptprt,"XXXAsolve_ptprt",nx,ny,nz,0,1) RETURN END SUBROUTINE solvpt_lrg ! ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE SOLVPT_SML ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE solvpt_sml(nx,ny,nz, exbcbufsz, dtbig1,dtsml1,curtsml, & 1,21 ptprt,w, ptdteb,ptdtwb,ptdtnb,ptdtsb, & ptbar,rhostr,rhostri,rhostrw,j3,aj3z,ptforce, & exbcbuf, & ptadv,tem1) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Coordinate the time integration of the potential temperature ! equation in small time steps. ! !----------------------------------------------------------------------- ! ! AUTHOR: Ming Xue ! 10/10/91 ! ! MODIFICATION HISTORY: ! ! 9/17/94 (M. Xue) ! Rewritten for small time step integration of ptprt equation. ! ! 11/6/1995 (M. Xue) ! Added option for fourth order vertical advection for ptbar. ! ! 4/17/96 (M. Xue) ! Removed the block for 4th order advection of ptbar. ! ! 4/24/1997 (M. Xue) ! Rewrote as SOLVPT_SML based on SOLVPT. ! ! 9/18/1998 (D. Weber) ! Added array aj3z and rhostri,w for efficiency. ! !----------------------------------------------------------------------- ! ! INPUT : ! ! nx Number of grid points in the x-direction (east/west) ! ny Number of grid points in the y-direction (north/south) ! nz Number of grid points in the vertical ! ! dtbig1 The big time step size for this call (s) ! dtsml1 The big time step size for this call (s) ! curtsml Current time during small time step integration. ! ! ptprt Perturbation potential temperature at times tpast and ! tpresent (K) ! w Vertical component of Cartesian velocity ! ! ptdteb Time tendency of the ptprt field at the east boundary ! ptdtwb Time tendency of the ptprt field at the west boundary ! ptdtnb Time tendency of the ptprt field at the north boundary ! ptdtsb Time tendency of the ptprt field at the south boundary ! ! ptbar Base state potential temperature (K) ! rhostr Base state density rhobar times j3 (kg/m**3) ! rhostri Inverse base state density rhobar times j3 (kg/m**3) ! rhostrw rhostr averaged to w-point. ! ! j3 Coordinate transformation Jacobian d(zp)/dz ! aj3z Avgz of the coordinate transformation Jacobian d(zp)/dz ! ! ptforce Gravity wave inactive forcing terms in pt-eq. ! (K*kg/(m**3*s)) ! ! OUTPUT: ! ! ptprt Perturbation potential temperature at time tfuture (K) ! ! WORK ARRAYS: ! ! ptadv Advection of base state potential temperature ! tem1 Temporary work array. ! !----------------------------------------------------------------------- ! ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! Force explicit declarations INCLUDE 'timelvls.inc' INTEGER :: nx, ny, nz ! Number of grid points in 3 directions REAL :: dtbig1 ! The big time step size for this call ! (s) REAL :: dtsml1 ! The big time step size for this call ! (s) REAL :: curtsml ! Current time during small time step ! integration. REAL :: ptprt (nx,ny,nz,nt) ! Perturbation potential temperature (K) REAL :: w (nx,ny,nz,nt) ! Total w-velocity (m/s) REAL :: ptdteb(ny,nz) ! Time tendency of ptprt at east ! boundary REAL :: ptdtwb(ny,nz) ! Time tendency of ptprt at west ! boundary REAL :: ptdtnb(nx,nz) ! Time tendency of ptprt at north ! boundary REAL :: ptdtsb(nx,nz) ! Time tendency of ptprt at south ! boundary REAL :: ptbar (nx,ny,nz) ! Base state potential temperature (K) REAL :: rhostr(nx,ny,nz) ! Base state density rhobar times j3. REAL :: rhostri(nx,ny,nz) ! Inverse base state density rhobar times j3. REAL :: rhostrw(nx,ny,nz) ! rhostr averaged to w-point. REAL :: j3 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as d( zp )/d( z ). REAL :: aj3z (nx,ny,nz) ! Coordinate transformation Jacobian defined ! as d( zp )/d( z ) AVERAGED IN THE Z-DIR. REAL :: ptforce(nx,ny,nz) ! Gravity wave inactive forcing terms ! in potential temperature eq. ! (K*kg/(m**3*s)) INTEGER :: exbcbufsz ! EXBC buffer size REAL :: exbcbuf( exbcbufsz ) ! EXBC buffer array REAL :: ptadv (nx,ny,nz) ! Temporary array to store base state ! potential temperature advection. REAL :: tem1 (nx,ny,nz) ! Temporary work array ! !----------------------------------------------------------------------- ! ! Misc. local variables: ! !----------------------------------------------------------------------- ! INTEGER :: i, j, k, onvf INTEGER :: ebc1,wbc1,nbc1,sbc1 REAL :: deltat, dz05 , time INTEGER :: mptag ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'globcst.inc' INCLUDE 'grid.inc' ! Grid & map parameters. INCLUDE 'bndry.inc' INCLUDE 'exbc.inc' INCLUDE 'mp.inc' ! Message passing parameters. ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! !----------------------------------------------------------------------- ! ! Integrate forward by one timestep the potential temperature ! equation. When PT-eq. is integrated inside small time steps, ! it is stepped forward by a small time step, otherwise, it is ! stepped forward by a large time step using leapfrog scheme ! (i.e. 2*dtbig1 from ptprt at tpast). ! !----------------------------------------------------------------------- ! deltat = dtsml1 time = curtsml ! !----------------------------------------------------------------------- ! ! Base state potential temperature advection. This term is added to ! the array ptadv to yield the total potential temperature advection. ! ! ptbar is assumed to be independent of physical x and y, therefore ! d(ptbar)/dx and d(ptbar)/dy for constant z are zero, the base state ! advection is -w*d(ptbar)/dzp = -w/j3*d(ptbar)/dz. ! ! This term is responsible for internal gravity waves, when potential ! temperature equation is solved inside the small time steps, this ! term is evaluated inside the small time steps. ! !----------------------------------------------------------------------- ! ! dz05 = dz*0.5 DO k=2,nz-1 DO j=1,ny-1 DO i=1,nx-1 tem1(i,j,k)=rhostrw(i,j,k)*w(i,j,k,tfuture) & *(ptbar(i,j,k)-ptbar(i,j,k-1)) & *dzinv/aj3z(i,j,k) END DO END DO END DO onvf = 0 CALL avgz(tem1 , onvf, & nx,ny,nz, 1,nx-1, 1,ny-1, 2,nz-2, ptadv) IF( nestgrd == 1 .AND. mgrid /= 1 ) THEN DO k=2,nz-2 DO j=2,ny-2 DO i=2,nx-2 ptprt(i,j,k,tfuture)=ptprt(i,j,k,tfuture) & +deltat*(ptforce(i,j,k)-ptadv(i,j,k))*rhostri(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Integrate PT equation and the boundary conditions for a nested grid. ! !----------------------------------------------------------------------- ! DO k=2,nz-2 DO j=1,ny-1 ptprt( 1,j,k,tfuture)=ptprt( 1,j,k,tfuture) & +deltat* ptdtwb(j,k) ptprt(nx-1,j,k,tfuture)=ptprt(nx-1,j,k,tfuture) & +deltat* ptdteb(j,k) END DO END DO DO k=2,nz-2 DO i=2,nx-2 ptprt(i, 1,k,tfuture)=ptprt(i, 1,k,tfuture) & +deltat* ptdtsb(i,k) ptprt(i,ny-1,k,tfuture)=ptprt(i,ny-1,k,tfuture) & +deltat* ptdtnb(i,k) END DO END DO ! bc's for mp not implemented for nested grids CALL acct_interrupt(mp_acct) CALL bcsclr(nx,ny,nz, deltat*0.5 , & ptprt(1,1,1,tfuture),ptprt(1,1,1,tpresent), & ptprt(1,1,1,tfuture),ptdteb,ptdtwb,ptdtnb,ptdtsb, & 0,0,0,0 ,tbc,bbc) CALL acct_stop_inter ELSE ! !----------------------------------------------------------------------- ! ! Integrate PT equation and the boundary conditions for a base grid. ! !----------------------------------------------------------------------- ! DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 ptprt(i,j,k,tfuture)=ptprt(i,j,k,tfuture) & +deltat*(ptforce(i,j,k)-ptadv(i,j,k))*rhostri(i,j,k) END DO END DO END DO !call test_dump (ptprt,"XXX1solve_ptprt",nx,ny,nz,0,0) IF ( lbcopt == 1 ) THEN ! Internal boundary conditions ebc1=ebc wbc1=wbc sbc1=sbc nbc1=nbc IF( ebc == 4 ) ebc1=0 IF( wbc == 4 ) wbc1=0 IF( nbc == 4 ) nbc1=0 IF( sbc == 4 ) sbc1=0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(ptprt(1,1,1,tfuture),nx,ny,nz,ebc1,wbc1,0,mptag,tem1) CALL mprecv2dew(ptprt(1,1,1,tfuture),nx,ny,nz,ebc1,wbc1,0,mptag,tem1) CALL mpsend2dns(ptprt(1,1,1,tfuture),nx,ny,nz,nbc1,sbc1,0,mptag,tem1) CALL mprecv2dns(ptprt(1,1,1,tfuture),nx,ny,nz,nbc1,sbc1,0,mptag,tem1) END IF CALL acct_interrupt(mp_acct) CALL bcsclr(nx,ny,nz, deltat*0.5 , & ptprt(1,1,1,tfuture),ptprt(1,1,1,tpresent), & ptprt(1,1,1,tfuture),ptdteb,ptdtwb,ptdtnb,ptdtsb, & ebc1,wbc1,nbc1,sbc1,tbc,bbc) CALL acct_stop_inter ELSE ! External boundary condition IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(ptprt(1,1,1,tfuture),nx,ny,nz,0,0,0,mptag,tem1) CALL mprecv2dew(ptprt(1,1,1,tfuture),nx,ny,nz,0,0,0,mptag,tem1) CALL mpsend2dns(ptprt(1,1,1,tfuture),nx,ny,nz,0,0,0,mptag,tem1) CALL mprecv2dns(ptprt(1,1,1,tfuture),nx,ny,nz,0,0,0,mptag,tem1) END IF CALL acct_interrupt(mp_acct) CALL bcsclr(nx,ny,nz, deltat*0.5 , & ptprt(1,1,1,tfuture),ptprt(1,1,1,tpresent), & ptprt(1,1,1,tfuture),ptdteb,ptdtwb,ptdtnb,ptdtsb, & 0,0,0,0,tbc,bbc) CALL exbcpt(nx,ny,nz, time , ptprt(1,1,1,tfuture), & exbcbuf(npt0exb),exbcbuf(nptdtexb)) CALL acct_stop_inter END IF END IF !call test_dump (ptprt,"XXX1Asolve_ptprt",nx,ny,nz,0,1) RETURN END SUBROUTINE solvpt_sml ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE SOLVQV ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! ! SUBROUTINE solvqv(nx,ny,nz, exbcbufsz, dtbig1, & 1,32 qv,u,v,wcont, ustr,vstr,wstr, & qvdteb,qvdtwb,qvdtnb,qvdtsb, & rhostr,rhostri,qvbar,kmh,kmv,rprntl,qvsflx,pbldpth, & x,y,z,zp,mapfct,j1,j2,j3,aj3x,aj3y,j3inv,qvcumsrc, & usflx,vsflx,ptsflx,ptsfc,qvsfc,ptbar,ptprt, & exbcbuf,bcrlx, & qadv,qmix, & tem1,tem2,tem3,tem4,tem5,tem6,tem7,tem8, & tem1_0,tem2_0,tem3_0) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Coordinate the time integration of the equation for water vapor ! specific humidity qv, and the setting of boundary conditions. ! !----------------------------------------------------------------------- ! ! AUTHOR: Ming Xue ! 10/10/91 ! ! MODIFICATION HISTORY: ! ! 5/20/92 (M. Xue) ! Added full documentation. ! ! 2/10/93 (K. Droegemeier) ! Cleaned up documentation. ! ! 4/10/93 (M. Xue & Hao Jin) ! Add the terrain. ! ! 8/22/95 (M. Xue) ! Added ptcumsrc term to the right hand side of qv equation. ! It was omitted before. ! ! 08/30/95 (M. Xue and Y. Liu) ! Changed EXBC for water variables to zero-gradient when the ! variables are missing in the boundary file. ! ! 08/30/95 (Yuhe Liu) ! Fixed a bug which double computes the qv advection and mixing. ! ! 1/25/96 (Donghai Wang & Yuhe Liu) ! Added the map projection factor to ARPS governing equations. ! ! 4/1/96 (Donghai Wang, X. Song and M. Xue) ! Added the implicit treatment for the vertical mixing. ! ! 3/24/1997 (M. Xue) ! Code to handle the case of forward time integration added. ! ! 7/10/1997 (Fanyou Kong -- CMRP) ! Added the positive definite advection scheme option (sadvopt = 5) ! ! 7/17/1998 (M. Xue) ! Changed call to ADVQFCT. ! ! 9/18/1998 (D. Weber) ! Added arrays aj3x,y, u,v,wstr,rhostri do not alter! ! !----------------------------------------------------------------------- ! ! INPUT : ! ! nx Number of grid points in the x-direction (east/west) ! ny Number of grid points in the y-direction (north/south) ! nz Number of grid points in the vertical ! ! dtbig1 The big time step size (s) ! ! qv Water vapor specific humidity at tpast and tpresent ! (kg/kg) ! ! u x component of velocity at all time levels (m/s) ! v y component of velocity at all time levels (m/s) ! wcont Contravariant vertical velocity (m/s) ! ! ustr Appropriate ustr for advection. ! vstr Appropriate vstr for advection. ! wstr Appropriate wstr for advection. ! ! qvdteb Time tendency of the qv field at the east boundary ! qvdtwb Time tendency of the qv field at the west boundary ! qvdtnb Time tendency of the qv field at the north boundary ! qvdtsb Time tendency of the qv field at the south boundary ! ! rhostr Base state density rhobar times j3 (kg/m**3) ! rhostri Inverse base state density rhobar times j3 (kg/m**3) ! qvbar Base state water vapor specific humidity (kg/kg) ! ! kmh Horizontal turb. mixing coef. for momentum ( m**2/s ) ! kmv Vertical turb. mixing coef. for momentum ( m**2/s ) ! rprntl Reciprocal of Prandtl number ! ! qvsflx Surface flux of moisture (kg/(m**2*s)). ! pbldpth Planetary boundary layer depth (m) ! ! 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) ! ! mapfct Map factors at scalar points ! ! j1 Coordinate transformation Jacobian -d(zp)/dx ! j2 Coordinate transformation Jacobian -d(zp)/dy ! j3 Coordinate transformation Jacobian d(zp)/dz ! aj3x Avgx of the coordinate transformation Jacobian d(zp)/dz ! aj3y Avgy of the coordinate transformation Jacobian d(zp)/dz ! qvcumsrc Source term in qv-equation due to cumulus parameterization ! ! OUTPUT: ! ! qv Water vapor specific humidity at time tfuture (kg/kg) ! ! WORK ARRAYS: ! ! qadv Advection term of water vapor eq. (kg/(m**3*s)). ! A local array. ! qmix Total mixing in water vapor eq. (kg/(m**3*s)). ! A local array. ! tem1 Temporary work array. ! tem2 Temporary work array. ! tem3 Temporary work array. ! tem4 Temporary work array. ! tem5 Temporary work array. ! tem6 Temporary work array. ! tem6 Temporary work array. ! tem7 Temporary work array. ! tem8 Temporary work array. ! ! tem1_0 Temporary work array. ! tem2_0 Temporary work array. ! tem3_0 Temporary work array. ! !----------------------------------------------------------------------- ! ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! Force explicit declarations INCLUDE 'timelvls.inc' INTEGER :: nx, ny, nz ! Number of grid points in 3 directions REAL :: dtbig1 ! Local big time step REAL :: qv (nx,ny,nz,nt) ! Water vapor specific humidity (kg/kg) REAL :: u (nx,ny,nz,nt) ! Total u-velocity (m/s) REAL :: v (nx,ny,nz,nt) ! Total v-velocity (m/s) REAL :: wcont (nx,ny,nz) ! Contravariant vertical velocity (m/s) REAL :: ustr (nx,ny,nz) ! Appropriate ustr for advection. REAL :: vstr (nx,ny,nz) ! Appropriate vstr for advection. REAL :: wstr (nx,ny,nz) ! Appropriate wstr for advection. REAL :: qvdteb(ny,nz) ! Time tendency of qv at east boundary REAL :: qvdtwb(ny,nz) ! Time tendency of qv at west boundary REAL :: qvdtnb(nx,nz) ! Time tendency of qv at north boundary REAL :: qvdtsb(nx,nz) ! Time tendency of qv at south boundary REAL :: rhostr(nx,ny,nz) ! Base state density rhobar times j3. REAL :: rhostri(nx,ny,nz) ! Inverse base state density rhobar times j3. REAL :: qvbar (nx,ny,nz) ! Base state water vapor specific ! humidity (kg/kg) REAL :: kmh (nx,ny,nz) ! Horizontal turb. mixing coef. for ! momentum. ( m**2/s ) REAL :: kmv (nx,ny,nz) ! Vertical turb. mixing coef. for ! momentum. ( m**2/s ) REAL :: rprntl(nx,ny,nz) ! Reciprocal of Prandtl number REAL :: usflx(nx,ny) ! Surface flux of u-momentum REAL :: vsflx(nx,ny) ! Surface flux of v-momentum REAL :: ptsflx(nx,ny) ! Surface heat flux (K*kg/(m*s**2)) REAL :: qvsflx(nx,ny) ! Surface flux of moisture (kg/(m**2*s)) REAL :: pbldpth(nx,ny,nt) ! Planetary boundary layer depth (m) REAL :: x (nx) ! x-coord. of the physical and compu- ! tational grid. Defined at u-point. REAL :: y (ny) ! y-coord. of the physical and compu- ! tational grid. Defined at v-point. REAL :: z (nz) ! z-coord. of the computational grid. ! Defined at w-point on the staggered ! grid. REAL :: zp (nx,ny,nz) ! Physical height coordinate defined at ! w-point of the staggered grid. REAL :: mapfct(nx,ny,8) ! Map factors at scalar points REAL :: j1 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as - d( zp )/d( x ). REAL :: j2 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as - d( zp )/d( y ). REAL :: j3 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as d( zp )/d( z ). REAL :: aj3x (nx,ny,nz) ! Coordinate transformation Jacobian defined ! as d( zp )/d( z ) AVERAGED IN THE X-DIR. REAL :: aj3y (nx,ny,nz) ! Coordinate transformation Jacobian defined ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR. REAL :: j3inv (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as d( zp )/d( z ). REAL :: qvcumsrc(nx,ny,nz) ! Source in qv-equation due to cumulus ! parameterization REAL :: ptbar (nx,ny,nz) ! Base state potential temperature (K) REAL :: ptprt (nx,ny,nz,nt) ! Perturbation potential temperature REAL :: ptsfc(nx,ny) ! Potential temperature at the ground level (K) REAL :: qvsfc(nx,ny) ! Effective qv at the surface (kg/kg) INTEGER :: exbcbufsz ! EXBC buffer size REAL :: exbcbuf( exbcbufsz ) ! EXBC buffer array REAL :: bcrlx (nx,ny) ! EXBC relaxation coefficients REAL :: qadv(nx,ny,nz) ! Advection of water vapor (kg/(m**3*s)) ! A local array. REAL :: qmix(nx,ny,nz) ! Total mixing of water vapor ! (kg/(m**3*s)) ! A local array. 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 :: tem8 (nx,ny,nz) ! Temporary work array REAL :: tem1_0(0:nx,0:ny,0:nz) ! Temporary work array. REAL :: tem2_0(0:nx,0:ny,0:nz) ! Temporary work array. REAL :: tem3_0(0:nx,0:ny,0:nz) ! Temporary work array. ! !----------------------------------------------------------------------- ! ! Misc. local variables: ! !----------------------------------------------------------------------- ! INTEGER :: i,j,k INTEGER :: tstrtlvl ! Starting level of time integration REAL :: deltat INTEGER :: ebc1,wbc1,nbc1,sbc1, qflag INTEGER :: mptag ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'bndry.inc' INCLUDE 'exbc.inc' INCLUDE 'globcst.inc' INCLUDE 'mp.inc' ! Message passing parameters. ! !----------------------------------------------------------------------- ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! !----------------------------------------------------------------------- ! ! Compute the advection term of the water vapor specific humidity ! equation and store the result in array qadv. ! !----------------------------------------------------------------------- ! CALL set_acct(advs_acct) IF(sadvopt == 4) THEN ! Forward-based FCT scheme deltat = dtbig1 tstrtlvl = tpresent ELSE deltat = dtbig1*2 tstrtlvl = tpast END IF IF (sadvopt == 1 .OR. sadvopt == 2 .OR. sadvopt == 3 ) THEN ! 2nd or 4th order advection CALL advq(nx,ny,nz,qv,u,v,wcont,ustr,vstr,wstr, & rhostr,qvbar, mapfct, & qadv, & tem1,tem2,tem3,tem4) ELSE IF( sadvopt == 4.OR.sadvopt == 5) THEN ! FCT advection CALL advqfct(nx,ny,nz,dtbig1,qv,u,v,wcont, ustr,vstr,wstr, & rhostr,rhostri,mapfct,j3,qadv, & tem1,tem2,tem3,tem4,tem5,tem6,tem7,tem8, & tem1_0,tem2_0,tem3_0) END IF CALL set_acct(cmix_acct) ! !----------------------------------------------------------------------- ! ! Compute the mixing terms for the water vapor specific humidity ! equation. This includes both physical and computational ! mixing. Store the result in array qmix. ! !----------------------------------------------------------------------- ! CALL mixqv(nx,ny,nz, & qv(1,1,1,tstrtlvl),rhostr,qvbar,kmh,kmv,rprntl,qvsflx, & pbldpth(1,1,tpresent), & x,y,z,zp, mapfct, j1,j2,j3,aj3x,aj3y,j3inv, & usflx,vsflx,ptsflx,ptsfc,qvsfc,ptbar,ptprt, & qmix, & tem1,tem2,tem3,tem4,tem5,tem6) ! !----------------------------------------------------------------------- ! ! Call BRLXQ to calculate the boundary relaxation and computation ! mixing for qv ! ! qmix = qmix + qvexbc_term ! !----------------------------------------------------------------------- ! IF ( lbcopt == 2 .AND. mgrid == 1 ) THEN CALL acct_interrupt(bc_acct) qflag = 1 CALL brlxq(nx,ny,nz, deltat*0.5, qflag, qv,rhostr, qmix, & exbcbuf(nqv0exb), exbcbuf(nqc0exb), & exbcbuf(nqr0exb), exbcbuf(nqi0exb), & exbcbuf(nqs0exb), exbcbuf(nqh0exb), & exbcbuf(nqvdtexb),exbcbuf(nqcdtexb), & exbcbuf(nqrdtexb),exbcbuf(nqidtexb), & exbcbuf(nqsdtexb),exbcbuf(nqhdtexb),bcrlx, & tem1,tem2,tem3,tem4) CALL acct_stop_inter END IF ! !----------------------------------------------------------------------- ! ! Calculate qvforce, store the result in tem1. ! !----------------------------------------------------------------------- ! DO k=1,nz-1 DO j=1,ny-1 DO i=1,nx-1 tem1(i,j,k)=-qadv(i,j,k)+rhostr(i,j,k)*qvcumsrc(i,j,k) & +qmix(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Treat the vertically implicit mixing term. ! !----------------------------------------------------------------------- ! IF (trbvimp == 1) THEN ! Vertical implicit application CALL set_acct(tmix_acct) DO k=1,nz-1 DO j=1,ny-1 DO i=1,nx-1 tem2(i,j,k)=rhostr(i,j,k)*kmv(i,j,k)*rprntl(i,j,k) & *j3inv(i,j,k)*j3inv(i,j,k) END DO END DO END DO CALL vmiximps(nx,ny,nz,deltat*0.5,qv(1,1,1,tstrtlvl),rhostr, & tem2,tem1,tem3,tem4,tem5,tem6) END IF ! !----------------------------------------------------------------------- ! ! Integrate forward by one timestep the water vapor specific humidity ! equation, yielding qv at time = tfuture. ! !----------------------------------------------------------------------- ! IF( nestgrd == 1 .AND. mgrid /= 1 ) THEN CALL set_acct(tinteg_acct) DO k=2,nz-2 DO j=2,ny-2 DO i=2,nx-2 qv(i,j,k,tfuture)=qv(i,j,k,tstrtlvl) & +deltat*tem1(i,j,k)*rhostri(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Set the boundary conditions on qv for an adaptive (nested) ! grid run. If using only one grid, this portion of the code is ! skipped....proceed to next comment block. ! !----------------------------------------------------------------------- ! DO k=2,nz-2 DO i=1,nx-1 qv(i, 1,k,tfuture)= & 2*qv(i, 1,k,tpresent)-qv(i, 1,k,tpast) qv(i,ny-1,k,tfuture)= & 2*qv(i,ny-1,k,tpresent)-qv(i,ny-1,k,tpast) END DO END DO DO k=2,nz-2 DO j=2,ny-2 qv( 1,j,k,tfuture)= & 2*qv( 1,j,k,tpresent)-qv( 1,j,k,tpast) qv(nx-1,j,k,tfuture)= & 2*qv(nx-1,j,k,tpresent)-qv(nx-1,j,k,tpast) END DO END DO ! bc's for mp not implemented for nested grids CALL acct_interrupt(bc_acct) CALL bcqv(nx,ny,nz, deltat*0.5, & qv,qvbar, qvdteb,qvdtwb,qvdtnb,qvdtsb, & 0,0,0,0,tbc,bbc) CALL acct_stop_inter ELSE DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 qv(i,j,k,tfuture)=qv(i,j,k,tstrtlvl) & +deltat*tem1(i,j,k)*rhostri(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Set the boundary conditions on qv for a NON-adaptive (uniform) ! grid run. ! !----------------------------------------------------------------------- ! CALL set_acct(bc_acct) !call test_dump (qv,"XXXsolve_qv",nx,ny,nz,0,0) IF ( lbcopt == 1 ) THEN ebc1=ebc wbc1=wbc sbc1=sbc nbc1=nbc IF( ebc == 4 ) ebc1=0 IF( wbc == 4 ) wbc1=0 IF( nbc == 4 ) nbc1=0 IF( sbc == 4 ) sbc1=0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(qv(1,1,1,tfuture),nx,ny,nz,ebc1,wbc1,0,mptag,tem2) CALL mprecv2dew(qv(1,1,1,tfuture),nx,ny,nz,ebc1,wbc1,0,mptag,tem2) CALL mpsend2dns(qv(1,1,1,tfuture),nx,ny,nz,nbc1,sbc1,0,mptag,tem2) CALL mprecv2dns(qv(1,1,1,tfuture),nx,ny,nz,nbc1,sbc1,0,mptag,tem2) END IF CALL acct_interrupt(mp_acct) CALL bcqv(nx,ny,nz, dtbig1, & qv,qvbar, qvdteb,qvdtwb,qvdtnb,qvdtsb, & ebc1,wbc1,nbc1,sbc1,tbc,bbc) CALL acct_stop_inter ELSE ebc1 = 3 wbc1 = 3 sbc1 = 3 nbc1 = 3 IF( ebc == 0 ) ebc1 = 0 IF( wbc == 0 ) wbc1 = 0 IF( nbc == 0 ) nbc1 = 0 IF( sbc == 0 ) sbc1 = 0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew(qv(1,1,1,tfuture),nx,ny,nz,ebc1,wbc1,0,mptag,tem2) CALL mprecv2dew(qv(1,1,1,tfuture),nx,ny,nz,ebc1,wbc1,0,mptag,tem2) CALL mpsend2dns(qv(1,1,1,tfuture),nx,ny,nz,nbc1,sbc1,0,mptag,tem2) CALL mprecv2dns(qv(1,1,1,tfuture),nx,ny,nz,nbc1,sbc1,0,mptag,tem2) END IF CALL acct_interrupt(mp_acct) CALL bcqv(nx,ny,nz, dtbig1, & qv,qvbar, qvdteb,qvdtwb,qvdtnb,qvdtsb, & ebc1,wbc1,nbc1,sbc1,tbc,bbc) qflag = 1 CALL exbcq(nx,ny,nz, qflag, curtim+dtbig,qv(1,1,1,tfuture), & exbcbuf(nqv0exb), exbcbuf(nqvdtexb)) CALL acct_stop_inter END IF END IF !call test_dump (qv,"XXXAsolve_qv",nx,ny,nz,0,1) RETURN END SUBROUTINE solvqv ! ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE SOLVQ ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE solvq(nx,ny,nz, exbcbufsz, dtbig1, qflag, & 5,31 q,u,v,wcont, ustr,vstr,wstr, & qdteb,qdtwb,qdtnb,qdtsb, & rhostr,rhostri,kmh,kmv,rprntl, & x,y,z,zp, mapfct, j1,j2,j3,aj3x,aj3y,j3inv, & qccumsrc,qrcumsrc,qicumsrc,qscumsrc, & exbcbuf,bcrlx, & qadv,qmix, & tem1,tem2,tem3,tem4,tem5,tem6,tem7,tem8, & tem1_0,tem2_0,tem3_0) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! Coordinate the time integration of the equations for the water ! substance quantities qc,qr,qi,qs and qh, i.e. all water variables ! except the water vapor specific humidity qv. ! !----------------------------------------------------------------------- ! ! ! AUTHOR: Ming Xue ! 10/10/91 ! ! MODIFICATION HISTORY: ! ! 5/20/92 (K. Droegemeier and M. Xue) ! Added full documentation. ! ! 2/10/93 (K. Droegemeier) ! Cleaned up documentation. ! ! 8/12/95 (M. Xue) ! Added flag qflag. ! ! 1/25/96 (Donghai Wang & Yuhe Liu) ! Added the map projection factor to ARPS governing equations. ! ! 4/1/96 (Donghai Wang, X. Song and M. Xue) ! Added the implicit treatment for the vertical mixing. ! ! 3/24/1997 (M. Xue) ! Code to handle the case of forward time integration added. ! ! 7/10/1997 (Fanyou Kong -- CMRP) ! Added the positive definite advection scheme option (sadvopt = 5) ! ! 4/15/1998 (Donghai Wang) ! Added the source terms to the right hand terms of the qc,qr,qi,qs ! equations due to the K-F cumulus parameterization. ! ! 7/17/1998 (M. Xue) ! Changed call to ADVQFCT. ! ! 9/18/1998 (D. Weber) ! Added arrays aj3x,y, u,v,wstr,rhostri, do not alter! ! !----------------------------------------------------------------------- ! ! INPUT : ! ! nx Number of grid points in the x-direction (east/west) ! ny Number of grid points in the y-direction (north/south) ! nz Number of grid points in the vertical ! ! dtbig1 The big time step size (s) ! qflag Indicator for water/ice species ! ! q One of the liquid or ice variables at tpast and ! tpresent (kg/kg) ! ! u x component of velocity at all time levels (m/s) ! v y component of velocity at all time levels (m/s) ! wcont Contravariant vertical velocity (m/s) ! ustr Appropriate ustr for advection. ! vstr Appropriate vstr for advection. ! wstr Appropriate wstr for advection. ! ! qdteb Time tendency of liquid/ice variable q at east boundary ! qdtwb Time tendency of liquid/ice variable q at west boundary ! qdtnb Time tendency of liquid/ice variable q at north ! boundary ! qdtsb Time tendency of liquid/ice variable q at south ! boundary ! ! rhostr Base state density rhobar times j3 (kg/m**3) ! rhostri Inverse base state density rhobar times j3 (kg/m**3) ! ! kmh Horizontal turb. mixing coef. for momentum ( m**2/s ) ! kmv Vertical turb. mixing coef. for momentum ( m**2/s ) ! rprntl Reciprocal of Prandtl number ! ! 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) ! ! mapfct Map factors at scalar points ! ! j1 Coordinate transformation Jacobian -d(zp)/dx ! j2 Coordinate transformation Jacobian -d(zp)/dy ! j3 Coordinate transformation Jacobian d(zp)/dz ! aj3x Avgx of the coordinate transformation Jacobian d(zp)/dz ! aj3y Avgy of the coordinate transformation Jacobian d(zp)/dz ! qccumsrc Source term in qc-equation due to cumulus parameterization ! qrcumsrc Source term in qr-equation due to cumulus parameterization ! qicumsrc Source term in qi-equation due to cumulus parameterization ! qscumsrc Source term in qs-equation due to cumulus parameterization ! ! ! OUTPUT: ! ! q Liquid/ice variable q at tfuture (kg/kg) ! ! WORK ARRAYS: ! ! qadv Advection term of water variable eq. (kg/(m**3*s)). ! A local array. ! qmix Total mixing in water variable eq. (kg/(m**3*s)). ! A local array. ! tem1 Temporary work array. ! tem2 Temporary work array. ! tem3 Temporary work array. ! tem4 Temporary work array. ! tem5 Temporary work array. ! tem6 Temporary work array. ! tem7 Temporary work array. ! tem8 Temporary work array. ! ! tem1_0 Temporary work array. ! tem2_0 Temporary work array. ! tem3_0 Temporary work array. ! !----------------------------------------------------------------------- ! ! !----------------------------------------------------------------------- ! ! Variable Declarations: ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! Force explicit declarations INCLUDE 'timelvls.inc' INTEGER :: nx, ny, nz ! Number of grid points in 3 directions REAL :: dtbig1 ! Local big time step INTEGER :: qflag ! Indicator for water/ice species REAL :: q (nx,ny,nz,nt) ! One of the water/ice variables (kg/kg) REAL :: u (nx,ny,nz,nt) ! Total u-velocity (m/s) REAL :: v (nx,ny,nz,nt) ! Total v-velocity (m/s) REAL :: wcont (nx,ny,nz) ! Contravariant vertical velocity (m/s) REAL :: ustr (nx,ny,nz) ! Appropriate ustr for advection (m/s) REAL :: vstr (nx,ny,nz) ! Appropriate vstr for advection (m/s) REAL :: wstr (nx,ny,nz) ! Appropriate wstr for advection (m/s) REAL :: qdteb(ny,nz) ! Time tendency of liquid/ice at ! e-boundary REAL :: qdtwb(ny,nz) ! Time tendency of liquid/ice at ! w-boundary REAL :: qdtnb(nx,nz) ! Time tendency of liquid/ice at ! n-boundary REAL :: qdtsb(nx,nz) ! Time tendency of liquid/ice at ! s-boundary REAL :: rhostr(nx,ny,nz) ! Base state density rhobar times j3. REAL :: rhostri(nx,ny,nz) ! Inverse base state density rhobar times j3. REAL :: kmh (nx,ny,nz) ! Horizontal turb. mixing coef. for ! momentum. ( m**2/s ) REAL :: kmv (nx,ny,nz) ! Vertical turb. mixing coef. for ! momentum. ( m**2/s ) REAL :: rprntl(nx,ny,nz) ! Reciprocal of Prandtl number REAL :: x (nx) ! x-coord. of the physical and compu- ! tational grid. Defined at u-point. REAL :: y (ny) ! y-coord. of the physical and compu- ! tational grid. Defined at v-point. REAL :: z (nz) ! z-coord. of the computational grid. ! Defined at w-point on the staggered ! grid. REAL :: zp (nx,ny,nz) ! Physical height coordinate defined at ! w-point of the staggered grid. REAL :: mapfct(nx,ny,8) ! Map factors at scalar points REAL :: j1 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as - d( zp )/d( x ). REAL :: j2 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as - d( zp )/d( y ). REAL :: j3 (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as d( zp )/d( z ). REAL :: aj3x (nx,ny,nz) ! Coordinate transformation Jacobian defined ! as d( zp )/d( z ) AVERAGED IN THE X-DIR. REAL :: aj3y (nx,ny,nz) ! Coordinate transformation Jacobian defined ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR. REAL :: j3inv (nx,ny,nz) ! Coordinate transformation Jacobian ! defined as d( zp )/d( z ). REAL :: qccumsrc(nx,ny,nz) ! Source in qc-equation due to cumulus ! parameterization REAL :: qrcumsrc(nx,ny,nz) ! Source in qr-equation due to cumulus ! parameterization REAL :: qicumsrc(nx,ny,nz) ! Source in qi-equation due to cumulus ! parameterization REAL :: qscumsrc(nx,ny,nz) ! Source in qs-equation due to cumulus ! parameterization INTEGER :: exbcbufsz ! EXBC buffer size REAL :: exbcbuf( exbcbufsz ) ! EXBC buffer array REAL :: bcrlx (nx,ny) ! EXBC relaxation coefficients REAL :: qadv(nx,ny,nz) ! Advection of water/ice substance ! (kg/(m**3*s)). A local array. REAL :: qmix(nx,ny,nz) ! Total mixing of water/ice substance ! (kg/(m**3*s)). A local array. 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 :: tem8 (nx,ny,nz) ! Temporary work array REAL :: tem1_0(0:nx,0:ny,0:nz) ! automatic work array REAL :: tem2_0(0:nx,0:ny,0:nz) ! automatic work array REAL :: tem3_0(0:nx,0:ny,0:nz) ! automatic work array ! !----------------------------------------------------------------------- ! ! Misc. local variables: ! !----------------------------------------------------------------------- ! INTEGER :: i,j,k INTEGER :: tstrtlvl REAL :: deltat INTEGER :: ebc1,wbc1,nbc1,sbc1 INTEGER :: nq0exb,nqdtexb INTEGER :: mptag ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'bndry.inc' INCLUDE 'exbc.inc' INCLUDE 'globcst.inc' INCLUDE 'mp.inc' ! Message passing parameters. ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! !----------------------------------------------------------------------- ! ! Compute the advection term for a general water substance ! q and store the result in qadv. ! !----------------------------------------------------------------------- ! CALL set_acct(advs_acct) IF(sadvopt == 4) THEN ! Forward-based FCT scheme deltat = dtbig1 tstrtlvl = tpresent ELSE deltat = dtbig1*2 tstrtlvl = tpast END IF IF (sadvopt == 1 .OR. sadvopt == 2 .OR. sadvopt == 3 ) THEN ! 2nd or 4th order centerd sc DO i=1,nx DO j=1,ny DO k=1,nz tem7(i,j,k) = 0.0 END DO END DO END DO CALL advq(nx,ny,nz,q,u,v,wcont,ustr,vstr,wstr, & rhostr, tem7, mapfct, & qadv, & tem1,tem2,tem3,tem4) ELSE IF( sadvopt == 4 .OR. sadvopt == 5 ) THEN ! FCT advection CALL advqfct(nx,ny,nz,dtbig1,q,u,v,wcont, ustr,vstr,wstr, & rhostr,rhostri,mapfct,j3,qadv, & tem1,tem2,tem3,tem4,tem5,tem6,tem7,tem8, & tem1_0,tem2_0,tem3_0) END IF ! !----------------------------------------------------------------------- ! ! Compute the mixing terms for the general water substance (q) ! equation, including both physical and computational mixing. ! Store the result in array qmix. ! !----------------------------------------------------------------------- ! CALL set_acct(cmix_acct) CALL mixq(nx,ny,nz, & q(1,1,1,tstrtlvl),rhostr,kmh,kmv,rprntl, & x,y,z,zp,mapfct, j1,j2,j3,aj3x,aj3y,j3inv, & qmix, & tem1,tem2,tem3,tem4,tem5,tem6) ! !----------------------------------------------------------------------- ! ! Call BRLXQ to added to qmix the additional boundary relaxation and ! spatial mixing in the boundary zone ! ! qmix = qmix + qexbc_term ! !----------------------------------------------------------------------- ! IF ( lbcopt == 2 .AND. mgrid == 1 ) THEN CALL acct_interrupt(bc_acct) CALL brlxq(nx,ny,nz, deltat*0.5, qflag, q,rhostr, qmix, & exbcbuf(nqv0exb), exbcbuf(nqc0exb), & exbcbuf(nqr0exb), exbcbuf(nqi0exb), & exbcbuf(nqs0exb), exbcbuf(nqh0exb), & exbcbuf(nqvdtexb),exbcbuf(nqcdtexb), & exbcbuf(nqrdtexb),exbcbuf(nqidtexb), & exbcbuf(nqsdtexb),exbcbuf(nqhdtexb),bcrlx, & tem1,tem2,tem3,tem4) CALL acct_stop_inter END IF ! !----------------------------------------------------------------------- ! ! Calculate qforce, store the result in tem1. ! !----------------------------------------------------------------------- ! DO k=1,nz-1 DO j=1,ny-1 DO i=1,nx-1 tem1(i,j,k)=-qadv(i,j,k)+qmix(i,j,k) IF(qflag == 2) THEN tem1(i,j,k)= tem1(i,j,k)+rhostr(i,j,k)*qccumsrc(i,j,k) ELSE IF(qflag == 3) THEN tem1(i,j,k)= tem1(i,j,k)+rhostr(i,j,k)*qrcumsrc(i,j,k) ELSE IF(qflag == 4) THEN tem1(i,j,k)= tem1(i,j,k)+rhostr(i,j,k)*qicumsrc(i,j,k) ELSE IF(qflag == 5) THEN tem1(i,j,k)= tem1(i,j,k)+rhostr(i,j,k)*qscumsrc(i,j,k) ELSE END IF END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Treat the vertically implicit mixing term. ! !----------------------------------------------------------------------- ! IF (trbvimp == 1) THEN ! Vertical implicit application CALL set_acct(tmix_acct) DO k=1,nz-1 DO j=1,ny-1 DO i=1,nx-1 tem2(i,j,k)=rhostr(i,j,k)*kmv(i,j,k)*rprntl(i,j,k) & *j3inv(i,j,k)*j3inv(i,j,k) END DO END DO END DO CALL vmiximps(nx,ny,nz,deltat*0.5,q(1,1,1,tstrtlvl),rhostr, & tem2,tem1,tem3,tem4,tem5,tem6) END IF ! !----------------------------------------------------------------------- ! ! Integrate forward by one timestep the general water substance ! (q) equation, yielding q at time = tfuture. ! !----------------------------------------------------------------------- ! CALL set_acct(tinteg_acct) IF( nestgrd == 1 .AND. mgrid /= 1 ) THEN DO k=2,nz-2 DO j=2,ny-2 DO i=2,nx-2 q(i,j,k,tfuture)=q(i,j,k,tstrtlvl) & +deltat*tem1(i,j,k)*rhostri(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Set the boundary conditions on q for an adaptive (nested) ! grid run. If using only one grid, this portion of the code is ! skipped....proceed to next comment block. ! !----------------------------------------------------------------------- ! DO k=2,nz-2 DO i=1,nx-1 q(i, 1,k,tfuture)=2*q(i, 1,k,tpresent)-q(i, 1,k,tpast) q(i,ny-1,k,tfuture)=2*q(i,ny-1,k,tpresent)-q(i,ny-1,k,tpast) END DO END DO DO k=2,nz-2 DO j=2,ny-2 q( 1,j,k,tfuture)=2*q( 1,j,k,tpresent)-q( 1,j,k,tpast) q(nx-1,j,k,tfuture)=2*q(nx-1,j,k,tpresent)-q(nx-1,j,k,tpast) END DO END DO ! bc's for mp not implemented for nested grids CALL acct_interrupt(bc_acct) CALL bcq(nx,ny,nz, dtbig1, q, qdteb,qdtwb,qdtnb,qdtsb, & 0,0,0,0,tbc,bbc) CALL acct_stop_inter ELSE DO k=2,nz-2 DO j=1,ny-1 DO i=1,nx-1 q(i,j,k,tfuture)=q(i,j,k,tstrtlvl) & +deltat*tem1(i,j,k)*rhostri(i,j,k) END DO END DO END DO ! !----------------------------------------------------------------------- ! ! Set the boundary conditions on q for a NON-adaptive (uniform) ! grid run. ! !----------------------------------------------------------------------- ! !call test_dump (q,"XXXsolve_q",nx,ny,nz,0,0) IF ( lbcopt == 1 ) THEN ebc1=ebc wbc1=wbc sbc1=sbc nbc1=nbc IF( ebc == 4 ) ebc1=0 IF( wbc == 4 ) wbc1=0 IF( nbc == 4 ) nbc1=0 IF( sbc == 4 ) sbc1=0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew( CALL mprecv2dew( CALL mpsend2dns( CALL mprecv2dns( END IF CALL acct_interrupt(bc_acct) CALL bcq(nx,ny,nz, dtbig1, q, qdteb,qdtwb,qdtnb,qdtsb, & ebc1,wbc1,nbc1,sbc1,tbc,bbc) CALL acct_stop_inter ELSE ebc1 = 3 wbc1 = 3 sbc1 = 3 nbc1 = 3 IF( ebc == 0 ) ebc1 = 0 IF( wbc == 0 ) wbc1 = 0 IF( nbc == 0 ) nbc1 = 0 IF( sbc == 0 ) sbc1 = 0 IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend2dew( CALL mprecv2dew( CALL mpsend2dns( CALL mprecv2dns( END IF CALL acct_interrupt(bc_acct) CALL bcq(nx,ny,nz, dtbig1, q, qdteb,qdtwb,qdtnb,qdtsb, & ebc1,wbc1,nbc1,sbc1,tbc,bbc) ! Zero-gradient condition will be ! reset if exbc data is available for q IF ( qflag == 1 ) THEN nq0exb = nqv0exb nqdtexb = nqvdtexb ELSE IF ( qflag == 2 ) THEN nq0exb = nqc0exb nqdtexb = nqcdtexb ELSE IF ( qflag == 3 ) THEN nq0exb = nqr0exb nqdtexb = nqrdtexb ELSE IF ( qflag == 4 ) THEN nq0exb = nqi0exb nqdtexb = nqidtexb ELSE IF ( qflag == 5 ) THEN nq0exb = nqs0exb nqdtexb = nqsdtexb ELSE IF ( qflag == 6 ) THEN nq0exb = nqh0exb nqdtexb = nqhdtexb END IF CALL exbcq(nx,ny,nz, qflag, curtim+dtbig,q(1,1,1,tfuture), & exbcbuf(nq0exb),exbcbuf(nqdtexb)) CALL acct_stop_inter END IF END IF !call test_dump (q,"XXXAsolve_q",nx,ny,nz,0,1) RETURN END SUBROUTINE solvq ! ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE UPRAD1 ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE uprad1(nx,ny,w1,w2,wc,nrho,ifax1,ifax2,trigs1,trigs2, & 1,8 temxy1,work) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! To apply the upper radiation condition using a periodic 1 or 2-D ! fft. The variable temxy1 contains input information and is ! overwritten with the final w (at nz-1) on exit. ! ! In the case of the open boundary, a linear hydrostatic relation ! between vertical velocity and pressure is used in fourier space. ! The use of fast fourier transform is required for this condition. ! ! The fft routine used is FFT991 obtained from NCAR. It is a ! version of the one used by ECMWF. Before fft991 is called, set99 ! is called to setup the variables needed for the transform routine. ! (init3d.f) ! !----------------------------------------------------------------------- ! ! AUTHOR: Dan Weber ! 07/22/1997. ! ! Modification History: ! !----------------------------------------------------------------------- ! ! INPUT: ! ! nx Number of grid points in the x-direction. ! ny Number of grid points in the y-direction. ! ! w1 Pre-fft w(nz-1) coefficient. ! w2 Pre-fft w(nz-2) coefficient. ! wc Pre-fft w(nz-1) coefficient from the reduction ! phase of the tridiaginal solver. ! ! trigs1 Array containing pre-computed trig function for ! fftopt=1. ! trigs2 Array containing pre-computed trig function for ! fftopt=1. ! ifax1 Array containing the factors of nx for fftopt=1. ! ifax2 Array containing the factors of ny for fftopt=1. ! ! OUTPUT: ! ! ! temxy1 On input known forcing term, on output final w at nz-1. ! ! ! WORK ARRAYS: ! ! ! work 2-D work array for fft code. ! ! !----------------------------------------------------------------------- ! ! !----------------------------------------------------------------------- ! ! Variable Declarations. ! !----------------------------------------------------------------------- ! IMPLICIT NONE INTEGER :: nx ! Number of grid points in the x-direction. INTEGER :: ny ! Number of grid points in the y-direction. REAL :: w1 ! pre-fft w(nz-1) coefficient. REAL :: w2 ! pre-fft w(nz-2) coefficient. REAL :: wc ! pre-fft w(nz-1) coefficient from the ! reduction phase of the tridiagonal solver. REAL :: trigs1(3*(nx-1)/2+1) ! Array containing pre-computed trig ! function for fftopt=1. REAL :: trigs2(3*(ny-1)/2+1) ! Array containing pre-computed trig ! function for fftopt=1. INTEGER :: ifax1(13) ! Array containing the factors of nx for ! fftopt=1. INTEGER :: ifax2(13) ! Array containing the factors of ny for ! fftopt=1. REAL :: temxy1 (nx+1,ny+1) ! On input known forcing term, ! on output final w at nz-1. REAL :: work (ny,nx) ! 2-D work array for fft code. ! !----------------------------------------------------------------------- ! ! Misc. local variables: ! !----------------------------------------------------------------------- ! INTEGER :: i,j,itema,itemb REAL :: eps,kx,ky,pi,nrho,tema,temb,temc,temd,teme,temf,temg ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'globcst.inc' INCLUDE 'grid.inc' ! Grid & map parameters. INCLUDE 'bndry.inc' !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !----------------------------------------------------------------------- ! ! Perform the fft on temxy1 ! !----------------------------------------------------------------------- IF(ny == 4)THEN ! 1-d transform in x, note nx must be ODD! itema = 1 itemb = nx CALL fft991(temxy1,work,trigs1,ifax1,1,nx+1,nx-1,1,-1) ELSE IF(nx == 4)THEN ! 1-d transform in y, note ny must be ODD! itema = ny itemb = 1 CALL fft991(temxy1,work,trigs2,ifax2,nx+1,1,ny-1,1,-1) ELSE ! Do 2-d transform, note nx,ny must be ODD! itema = ny itemb = nx CALL fft991(temxy1,work,trigs1,ifax1,1,nx+1,nx-1,ny-1,-1) CALL fft991(temxy1,work,trigs2,ifax2,nx+1,1,ny-1,nx,-1) END IF ! end of run type if block. !----------------------------------------------------------------------- ! ! Compute the wave space w at nz-1. ! !----------------------------------------------------------------------- eps= 1.0E-8 pi = 4.0*ATAN(1.0) tema = pi/(nx-2) temb = pi/(ny-2) temc = 2.0*dxinv temd = 2.0*dyinv temf = w1-w2*wc temg = eps - nrho DO j=1,itema ! note: kx and ky are in finite difference form. ky = temd*SIN(INT((j-1)*0.5+0.001)*temb) ky = ky*ky DO i=1,itemb kx = temc*SIN(INT((i-1)*0.5+0.001)*tema) teme =SQRT(kx*kx+ky) temxy1(i,j)=-teme*temxy1(i,j)/(teme*temf+temg) END DO END DO !----------------------------------------------------------------------- ! ! Perform the reverse fft on temxy1 to obtain w(nz-1) in real space. ! !----------------------------------------------------------------------- IF(ny == 4)THEN ! 1-d transform in x, note nx must be ODD! CALL fft991(temxy1,work,trigs1,ifax1,1,nx+1,nx-1,1,1) DO j=2,ny-1 DO i=1,nx-1 temxy1(i,j) = temxy1(i,1) END DO END DO ELSE IF(nx == 4)THEN ! 1-d transform in y, note ny must be ODD! CALL fft991(temxy1,work,trigs2,ifax2,nx+1,1,ny-1,1,1) DO j=1,ny-1 DO i=2,nx-1 temxy1(i,j) = temxy1(1,j) END DO END DO ELSE ! Do 2-d transform, note nx,ny must be ODD! CALL fft991(temxy1,work,trigs2,ifax2,nx+1,1,ny-1,nx, 1) CALL fft991(temxy1,work,trigs1,ifax1,1,nx+1,nx-1,ny-1, 1) END IF ! end of run type if block. RETURN END SUBROUTINE uprad1 ! ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE UPRAD3 ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE uprad3(nx,ny,w1,w2,wc,nrho,wsave1,wsave2,vwork1,vwork2, & 1,8 temxy1,work) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! To apply the upper radiation condition using an even (vfftpack) ! sequence fft. The variable temxy1 contains input information and ! is overwritten with the updated w (at nz-1) on exit. ! ! In the case of the open boundary, a linear, hydrostatic relation ! between vertical velocity to pressure is used in fourier space. ! The use of fast fourier transform is NOT required for this ! option but is recommended. If nx and ny are not of special ! character, then a basic fourier transform is used. ! ! The fft routine used is vcost from the vfftpack software suite ! available at PSC. ! ! Before vcost is called, the arrays wsave1,wsave2,vwork1,vwork2 ! must be initialized (init3d.f). ! !----------------------------------------------------------------------- ! ! AUTHOR: Dan Weber ! 07/22/1997. ! ! ! Modification History: ! !----------------------------------------------------------------------- ! ! INPUT: ! ! nx Number of grid points in the x-direction. ! ny Number of grid points in the y-direction. ! ! w1 Pre-fft w(nz-1) coefficient. ! w2 Pre-fft w(nz-2) coefficient. ! wc Pre-fft w(nz-1) coefficient from the reduction ! phase of the tridiaginal solver. ! ! vwork1 2-D work array for fftopt=2 option. ! vwork2 2-D work array for fftopt=2 option. ! wsave1 Work array for fftopt=2 option. ! wsave2 Work array for fftopt=2 option. ! ! OUTPUT: ! ! ! temxy1 On input known forcing term, on output final w at nz-1. ! ! ! WORK ARRAYS: ! ! ! work 2-D work array for fft code. ! ! !----------------------------------------------------------------------- ! ! !----------------------------------------------------------------------- ! ! Variable Declarations. ! !----------------------------------------------------------------------- IMPLICIT NONE INTEGER :: nx ! Number of grid points in the x ! direction. INTEGER :: ny ! Number of grid points in the y ! direction. REAL :: w1 ! Pre-fft w(nz-1) coefficient. REAL :: w2 ! Pre-fft w(nz-2) coefficient. REAL :: wc ! Pre-fft w(nz-1) coefficient from the ! reduction phase of the tridiagonal ! solver. REAL :: vwork1 (nx+1,ny+1) ! 2-D work array for fftopt=2. REAL :: vwork2 (ny,nx+1) ! 2-D work array for fftopt=2. REAL :: wsave1 (3*(ny-1)+15) ! Work array for fftopt=2. REAL :: wsave2 (3*(nx-1)+15) ! Work array for fftopt=2. REAL :: temxy1 (nx+1,ny+1) ! On input known forcing term, ! on output final w at nz-1. REAL :: work (ny,nx) ! 2-D work array (global) ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'globcst.inc' INCLUDE 'grid.inc' ! Grid & map parameters. INCLUDE 'bndry.inc' ! !----------------------------------------------------------------------- ! ! Misc. local variables: ! !----------------------------------------------------------------------- ! INTEGER :: i,j REAL :: kx,ky,pi,tema,temb,temc,temd,teme,temf REAL :: eps,nrho ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !----------------------------------------------------------------------- ! ! Perform the fft on temxy1. ! !----------------------------------------------------------------------- IF(ny == 4)THEN ! 1-d transform in x. DO i=1,nx-1 ! swap temxy1(i,j) array into work(j,i) work(1,i) = temxy1(i,1) END DO CALL vcost(1,nx-1,work,vwork2,ny,wsave2) DO i=1,nx-1 ! swap back for computations.... temxy1(i,1) = work(1,i) END DO ELSE IF(nx == 4)THEN ! 1-d transform in y. CALL vcost(1,ny-1,temxy1,vwork1,nx+1,wsave1) ELSE ! Do 2-d transform. CALL vcost(nx-1,ny-1,temxy1,vwork1,nx+1,wsave1) DO j=1,ny-1 ! swapping arrays. DO i=1,nx-1 work(j,i) = temxy1(i,j) END DO END DO CALL vcost(ny-1,nx-1,work,vwork2,ny,wsave2) DO j=1,ny-1 ! swapping arrays for computations. DO i=1,nx-1 temxy1(i,j) = work(j,i) END DO END DO END IF ! end of run type if block. !----------------------------------------------------------------------- ! ! Compute the wave space w at nz-1. ! !----------------------------------------------------------------------- eps = 1.0E-13 pi = 4.0*ATAN(1.0) tema = 0.5*pi/(nx-2) ! finite difference form. temb = 0.5*pi/(ny-2) ! finite difference form. temc = 2.0*dxinv temd = 2.0*dyinv teme = w1-w2*wc temf = eps - nrho temxy1(1,1) = -temxy1(1,1)/(teme+temf) ! first part of 2-d case. IF(ny == 4)THEN ! perform computations in x direction. DO i=2,nx-1 ! compute from i=2,nx-1 and j=1... kx = temc*SIN(INT(i-1)*tema) kx = SQRT(kx*kx) temxy1(i,1)=-kx*temxy1(i,1)/(kx*teme+temf) END DO ELSE IF(nx == 4)THEN ! perform computations in y direction. DO j=2,ny-1 ! compute from j=2,ny-1 and i=1. ky = temd*SIN(INT(j-1)*temb) ky = SQRT(ky*ky) temxy1(1,j)=-ky*temxy1(1,j)/(ky*teme+temf) END DO ELSE ! compute the 2-D version. DO i=2,nx-1 ! compute from i=2,nx-1 and j=1. kx = temc*SIN(INT(i-1)*tema) kx = SQRT(kx*kx) temxy1(i,1)=-kx*temxy1(i,1)/(kx*teme+temf) END DO DO j=2,ny-1 ! compute from i=1,j=2,ny-1. ky = temd*SIN(INT(j-1)*temb) ky = SQRT(ky*ky) temxy1(1,j)=-ky*temxy1(1,j)/(ky*teme+temf) END DO DO j=2,ny-1 ! compute from i=2,nx-1,j=2,ny-1. ky = temd*SIN(INT(j-1)*temb) ky = ky*ky DO i=2,nx-1 kx = temc*SIN(INT(i-1)*tema) kx =SQRT(kx*kx+ky) temxy1(i,j)=-kx*temxy1(i,j)/(kx*teme+temf) END DO END DO END IF ! end of the run type if block. !----------------------------------------------------------------------- ! ! Perform the reverse fft on temxy1 to obtain w in real space. ! !----------------------------------------------------------------------- IF(ny == 4)THEN ! 1-d transform in x, note nx must be EVEN! DO i=1,nx-1 work(1,i) = temxy1(i,1) END DO CALL vcost(1,nx-1,work,vwork2,ny,wsave2) DO j=1,ny-1 DO i=1,nx-1 temxy1(i,j) = work(1,i) END DO END DO ELSE IF(nx == 4)THEN ! 1-d transform in y, note ny must be EVEN! CALL vcost(1,ny-1,temxy1,vwork1,nx+1,wsave1) DO j=1,ny-1 DO i=1,nx-1 temxy1(i,j) = temxy1(1,j) END DO END DO ELSE ! Do 2-d transform, note nx,ny must be EVEN! DO j=1,ny-1 ! swapping arrays. DO i=1,nx-1 work(j,i) = temxy1(i,j) END DO END DO CALL vcost(ny-1,nx-1,work,vwork2,ny,wsave2) DO j=1,ny-1 ! swapping arrays. DO i=1,nx-1 temxy1(i,j) = work(j,i) END DO END DO CALL vcost(nx-1,ny-1,temxy1,vwork1,nx+1,wsave1) END IF ! end of runopt if block, w (nz-1) is updated. RETURN END SUBROUTINE uprad3 ! ! !################################################################## !################################################################## !###### ###### !###### SUBROUTINE PPRTBBC ###### !###### ###### !###### Developed by ###### !###### Center for Analysis and Prediction of Storms ###### !###### University of Oklahoma ###### !###### ###### !################################################################## !################################################################## ! SUBROUTINE pprtbbc(nx,ny,nz,g05,buoy2swt,rhostr,pprt,ptprt, & 6,8 pbari,ptbari,phydro, & pprt1,tem1) ! !----------------------------------------------------------------------- ! ! PURPOSE: ! ! To compute the perturbation pressure below the ground (scalar k=1) ! The technique uses the perturbation hydrostatic relation obtained ! from the model vertical momentum equation. The technique is ! summarized here. ! ! The calculation of the hydrostatic pressure bottom boundary ! condition involves two steps. The first step is used to ! approximate the second order pprt term in the buoyancy term ! and the second step obtains the final pprt at k=1. ! ! Step A: pprt(1)=D=(pprt(2) - F - dz*phydro + 2.0*A*B)/(1-C) ! ! where, A = dz*g*avgz(rhobar*J3)/(2*cpdcv) ! B = pprt(i,j,2)/pbar(i,j,2) ! C = A/pbar(i,j,1) ! F = alpha*div*(1)-alpha*div*(2) not included.... ! note: ! D = the intermediate result pprt(1) for use in the ! second order pprt term ! ! Step B: pprt(1) = D + A*(1/cpdcv -1)*(B*B + E*E)/(1.0-C) ! ! where, E = D/pbar(i,j,1) ! ! The result is stored in phydro(i,j) and passed into bcp to set ! pprt(i,j,1). ! ! !----------------------------------------------------------------------- ! ! AUTHOR: Dan Weber ! 11/06/1997. ! ! ! Modification History: ! ! 3/18/99 (D. Weber) ! Bug fix to second order terms. !----------------------------------------------------------------------- ! ! !----------------------------------------------------------------------- ! ! INPUT : ! ! nx Number of grid points in the x-direction (east/west) ! ny Number of grid points in the y-direction (north/south) ! nz Number of grid points in the vertical ! ! ptprt Perturbation potential temperature at time tpresent (K) ! pprt Perturbation pressure at time tpresent (Pascal) ! ! phydro Big time step forcing term for use in computing the ! hydrostatic pressure at k=1. ! ! rhostr Base state density rhobar times j3 (kg/m**3) ! ptbari Inverse base state potential temperature (K) ! pbari Inverse base state pressure (Pascal) ! ! OUTPUT: ! ! pprt1 Holds pprt(i,j,1) via hydrostatic balance. ! ! WORK ARRAYS: ! ! tem2 Work array. ! !----------------------------------------------------------------------- ! ! Variable Declarations. ! !----------------------------------------------------------------------- ! IMPLICIT NONE ! Force explicit declarations INTEGER :: nx, ny, nz ! Number of grid points in 3 directions REAL :: ptprt (nx,ny,nz) ! Perturbation potential temperature (K) REAL :: pprt (nx,ny,nz) ! Perturbation pressure at tfuture ! (Pascal) REAL :: phydro(nx,ny) ! Big time step forcing for computing ! hydrostatic pprt at k=1. REAL :: rhostr(nx,ny,nz) ! Base state density rhobar times j3. REAL :: ptbari(nx,ny,nz) ! Inverse base state pot. temperature (K) REAL :: pbari (nx,ny,nz) ! Inverse base state pressure (Pascal). REAL :: pprt1 (nx,ny) ! pprt1 ! !----------------------------------------------------------------------- ! ! Temporary WORK ARRAYS: ! !----------------------------------------------------------------------- ! REAL :: tem1 (nx,ny,nz) ! Temporary work array ! !----------------------------------------------------------------------- ! ! Misc. local variables: ! !----------------------------------------------------------------------- ! INTEGER :: i, j REAL :: g05 REAL :: tema,temb,a,b,c,d,e INTEGER :: buoy2swt !Switch for 1st-order or 2nd-order in buoyancy REAL :: ptemk,ptemk1,pttemk,pttemk1 INTEGER :: mptag ! !----------------------------------------------------------------------- ! ! Include files: ! !----------------------------------------------------------------------- ! INCLUDE 'bndry.inc' INCLUDE 'globcst.inc' INCLUDE 'grid.inc' ! Grid & map parameters. INCLUDE 'phycst.inc' ! Physical constants INCLUDE 'mp.inc' ! Message passing parameters. ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! ! Beginning of executable code... ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! IF( ptsmlstp == 1 ) THEN ! add in the 1st and 2nd order pt terms. tema = 0.5/cpdcv DO j=1,ny-1 DO i=1,nx-1 ptemk = pprt(i,j,2)*pbari(i,j,2) ! new code..... ptemk1= pprt(i,j,1)*pbari(i,j,1) pttemk = ptprt(i,j,2)*ptbari(i,j,2) pttemk1= ptprt(i,j,1)*ptbari(i,j,1) temb = 0.5*(rhostr(i,j,1)+rhostr(i,j,2)) pprt1(i,j)=phydro(i,j)+temb*g05*(pttemk+pttemk1 & -buoy2swt*(tema*(ptemk*pttemk+ptemk1*pttemk1) & +pttemk*pttemk+pttemk1*pttemk1)) END DO END DO ELSE DO j=1,ny-1 DO i=1,nx-1 pprt1(i,j)= phydro(i,j) END DO END DO END IF tema =buoy2swt*0.5*(1.0/cpdcv -1.0) temb = dz*g*0.25/cpdcv DO j=1,ny-1 DO i=1,nx-1 ! compute the intermediate result... a = temb*(rhostr(i,j,2)+rhostr(i,j,1)) b = pprt(i,j,2)*pbari(i,j,2) c = a*pbari(i,j,1) d = (pprt(i,j,2) - dz*pprt1(i,j) + a*b) / (1.0-c) ! compute the final pprt(i,j,1).... e = d*pbari(i,j,1) pprt1(i,j) = d + a*tema*(b*b + e*e) / (1.0-c) END DO END DO !call test_dump (pprt1,"XXXsolve_pprt1",nx,ny,1,0,0) IF (mp_opt > 0) THEN CALL acct_interrupt(mp_acct) CALL mpsend1dew(pprt1,nx,ny,ebc,wbc,0,mptag,tem1) CALL mprecv1dew(pprt1,nx,ny,ebc,wbc,0,mptag,tem1) CALL mpsend1dns(pprt1,nx,ny,nbc,sbc,0,mptag,tem1) CALL mprecv1dns(pprt1,nx,ny,nbc,sbc,0,mptag,tem1) END IF CALL acct_interrupt(bc_acct) CALL bcs2d(nx,ny,pprt1, ebc,wbc,nbc,sbc) CALL acct_stop_inter !call test_dump (pprt1,"XXXAsolve_pprt1",nx,ny,1,0,1) RETURN END SUBROUTINE pprtbbc