Blame | Last modification | View Log | Download | RSS feed
program ptos
C ******************************************************************
C
C NAME:
C p2s
C
C Purpose
C -------
C
C Calculates secondary data files from primary data files
C (based upon IVE-routines).
C
C calling:
C p2s [-m] file variable-list [-s] [-o]
C
C example:
C p2s P911201_00 TH PV CH QX
C
C p2s -m #returns man-page
C
C Authors
C ------
C
C H. Wernli April 96
C D.N. Bresch 980311
C
C Modifications
C -------------
C completely rewritten by D.N. Bresch 980311 for F90
C and many more variables added (nearly all available in IVE)
C
C ADD YOUR OWN VARIABLES AT ALL PLACES WITH (++)
C for easy simple calculations, see VEL, M, B
C for complicated calculations, see VORT, QX and PVR
C
C Remarks
C -------
C ZB is only read once when needed, i.e. for first time...
C
C- ******************************************************************
integer,parameter :: ntmax=200,nzmax=200,nvarmax=100
real time(ntmax),time2(ntmax)
REAL,ALLOCATABLE, DIMENSION (:,:) :: sp,cl,tl,f,zb,t2m,td2m,vip,
> u10m,v10m,oro,gradpv
REAL,ALLOCATABLE, DIMENSION (:,:,:) :: var,th,pv,lpv,the,rh,dhr,
> tt,qq,uu,vv,ww,rho,alpha,zz,mm,zlay,ug,vg,fl,ipv
character*80 cdfnam,cstnam,outfnam
integer cdfid,cdfid1,cstid,ierr,ndim,vardim(4),stat
integer cdfid2,vardim2(4)
real dx,dy,mdv,varmin(4),varmax(4),stag(4)
real aklev(nzmax),bklev(nzmax),aklay(nzmax),bklay(nzmax),
> ak(nzmax),bk(nzmax)
integer nx,ny,nz,ntimes,ntimes2,i,j,k,n
integer stdate(5)
character*(80) qmode,arg,vnam(nvarmax)
integer mode,zdef
real rlat,rlon,lat
real pollon,pollat,yphys
real phstoph
logical prelev
real,parameter :: pi=3.141592654
integer PS_out,TH_out,TH_calc,RH_out,RH_calc
integer PV_out,PV_calc,THE_out,THE_calc,VIP_out,VIP_calc
integer GRADPV_out,GRADPV_calc
integer LPV_out,LPV_calc
integer CH_out,CH_calc,PVR_out,PVR_calc
integer THW_out,THW_calc,Z_outP,Z_out,Z_calc
integer DIVQU_out,DIVQU_calc
integer NSQ_out,NSQ_calc,RHO_out,RHO_calc,ALPHA_out,ALPHA_calc,VEL_out,VEL_calc
integer NSQM_out,NSQM_calc,W_out,W_calc,M_out,M_calc
integer VORT_out,VORT_calc,UG_out,UG_calc,VG_out,VG_calc
integer AVO_out,AVO_calc,CURVO_out,CURVO_calc
integer DTHDP_out,DTHDP_calc
integer COS_out
integer ZLAY_out,ZLAY_calc,UA_out,UA_calc,VA_out,VA_calc
integer P_out,P_calc,PLEV_out,PLEV_calc
integer QXF_out,QXF_calc,QYF_out,QYF_calc
integer QX_out,QX_calc,QY_out,QY_calc,PSRED_calc,PSRED_out
integer RI_calc,RI_out,BLH_calc,BLH_out
integer GRADTH_out,GRADTH_calc,B_out,B_calc !(++)
logical verbose
logical ZonP,TonP,PSonP,UonP,VonP,OMEGAonP,ZBonP,ZBneed
logical T2MonP,TD2MonP,U10MonP,V10MonP,PVonP,PV3onP
character*(80) zbfile
c set defaults:
verbose=.false.
ZonP=.false.
TonP=.false.
PSonP=.false.
ZBonP=.false.
UonP=.false.
VonP=.false.
OMEGAonP=.false.
ZBonP=.false.
T2MonP=.false.
TD2MonP=.false.
U10MonP=.false.
V10MonP=.false.
PVonP=.false.
PV3onP=.false. ! Lukas
ZBneed=.false.
zbfile=''
qmode='QNone'
PS_out=1
TH_out=0
TH_calc=0
RH_out=0
RH_calc=0
PV_out=0
PV_calc=0
LPV_out=0
LPV_calc=0
VIP_out=0
VIP_calc=0
THE_out=0
THE_calc=0
CH_out=0
CH_calc=0
PVR_out=0
PVR_calc=0
THW_out=0
THW_calc=0
DIVQU_out=0
DIVQU_calc=0
Z_calc=0
Z_out=0
Z_outP=0
NSQ_out=0
NSQ_calc=0
DTHDP_out=0
DTHDP_calc=0
NSQM_out=0
NSQM_calc=0
RHO_out=0
RHO_calc=0
ALPHA_out=0
ALPHA_calc=0
VEL_out=0
VEL_calc=0
M_out=0
M_calc=0
B_out=0
B_calc=0
W_out=0
W_calc=0
VORT_out=0
VORT_calc=0
AVO_out=0
AVO_calc=0
CURVO_out=0
CURVO_calc=0
COS_out=0
UG_out=0
UG_calc=0
VG_out=0
VG_calc=0
UA_out=0
UA_calc=0
VA_out=0
VA_calc=0
ZLAY_out=0
ZLAY_calc=0
P_out=0
P_calc=0
PLEV_out=0
PLEV_calc=0
FL_out=0
FL_calc=0
PSRED_out=0
PSRED_calc=0
RI_out=0
RI_calc=0
BLH_out=0
BLH_calc=0
QXF_out=0
QXF_calc=0
QYF_out=0
QYF_calc=0
QX_out=0
QX_calc=0
QY_out=0
QY_calc=0
GRADTH_out=0
GRADTH_calc=0
GRADPV_out=0
GRADPV_calc=0 !(++)
c get arguments:
c get parameters from command-line:
c COUNT THE ARGUMENTS:
if (iargc() .lt. 1) then
print*,'USAGE: p2s [-m] file variable-list [-s] ',
> '[-o] [-zb file]'
STOP
endif
c REQUESTD INPUT:
c ---------------
c GET WITH getarg DIRECTLY FROM SHELL:
call getarg(1,cdfnam)
if (trim(cdfnam).eq.'-m') then
print*,' '
print*,'computes derived variables from primary ones on'
print*,'the input-file'
print*,'if the output-file is already present, it will be'
print*,'updated'
print*,' '
print*,'check the source-code itself about details...'
print*,' '
print*,'file: netCDF file with basic variables on it'
print*,' requested are the variables needed to calculate'
print*,' the requested output (variable-list)'
print*,' If file is a P-file (starting with P), the output-'
print*,' file will be an S-file, otherwise the extension'
print*,' _out will be appended, unless -o is used'
print*,' if the S-file exists already, it is tried to '
print*,' append the new variable'
print*,'[P]date means that you can either give PYYMMDD_HH'
print*,' or YYMMDD_HH alone'
print*,'variable-list: a list of variables to be calculated'
print*,' and written to the S_file, available are:'
print*,' TH,PV,LPV,RH,THE,THW,CH,PVR,Z,ZonP,GRADTH,NSQ,NSQM'
print*,' M,B,W,RHO,VEL,VORT,AVO,CURVO,UG,VG,ZLAY,UA,VA,P'
print*,' PLEV,FL,QX,QY,QXF,QYF,PSRED,RI,BLH,GRADPV,DTHDP'
print*,' ALPHA'
print*,'-s: only small S-file, i.e. TH and PV'
print*,'-zb: file with ZB (for PSRED)'
print*,'-o output: filename of the output netCDF file'
STOP
endif
C check, if cdfnam is with or without P:
if (cdfnam(1:1).eq.'P') then
outfnam='S'//cdfnam(2:len_trim(cdfnam))
else
outfnam=trim(cdfnam)//'_out'
endif
i=2
do while (iargc().ge.i)
call getarg(i,arg)
i=i+1
if (arg.eq.'TH') TH_out=1
if (arg.eq.'THE') THE_out=1
if (arg.eq.'THW') THW_out=1
if (arg.eq.'DIVQU') DIVQU_out=1
if (arg.eq.'PV') PV_out=1
if (arg.eq.'LPV') LPV_out=1
if (arg.eq.'VIP') VIP_out=1
if (arg.eq.'RH') RH_out=1
if (arg.eq.'CH') CH_out=1
if (arg.eq.'PVR') PVR_out=1
if (arg.eq.'Z') Z_out=1
if (arg.eq.'ZonP') Z_outP=1
if (arg.eq.'GRADTH') GRADTH_out=1
if (arg.eq.'GRADPV') GRADPV_out=1
if (arg.eq.'VEL') VEL_out=1
if (arg.eq.'RHO') RHO_out=1
if (arg.eq.'ALPHA') ALPHA_out=1
if (arg.eq.'W') W_out=1
if (arg.eq.'M') M_out=1
if (arg.eq.'B') B_out=1
if (arg.eq.'VORT') VORT_out=1
if (arg.eq.'AVO') AVO_out=1
if (arg.eq.'CURVO') CURVO_out=1
if (arg.eq.'COS') COS_out=1
if (arg.eq.'UG') UG_out=1
if (arg.eq.'VG') VG_out=1
if (arg.eq.'UA') UA_out=1
if (arg.eq.'VA') VA_out=1
if (arg.eq.'QX') QX_out=1
if (arg.eq.'QY') QY_out=1
if (arg.eq.'QXF') QXF_out=1
if (arg.eq.'QYF') QYF_out=1
if (arg.eq.'ZLAY') ZLAY_out=1
if (arg.eq.'P') P_out=1
if (arg.eq.'PLEV') PLEV_out=1
if (arg.eq.'FL') FL_out=1
if (arg.eq.'PSRED') PSRED_out=1
if (arg.eq.'RI') RI_out=1
if (arg.eq.'BLH') BLH_out=1
if (arg.eq.'NSQ') NSQ_out=1
if (arg.eq.'DTHDP') DTHDP_out=1
if (arg.eq.'NSQM') NSQM_out=1 ! (++)
if (arg.eq.'-v') verbose=.true.
if (arg.eq.'-s') then
TH_out=1
PV_out=1
endif
if (arg.eq.'-o') then
if (iargc().ge.i) then
call getarg(i,outfnam)
i=i+1
else
print*,'option -o requires filename'
STOP
endif
endif
if (arg.eq.'-zb') then
if (iargc().ge.i) then
call getarg(i,zbfile)
ZBneed=.true.
i=i+1
else
print*,'option -zb requires filename'
STOP
endif
endif
if (arg.eq.'-nops') then
PS_out=0
endif
enddo
C force calculations of requested fields:
c ---------------------------------------
if (QX_out.eq.1) QX_calc=1
if (QY_out.eq.1) QY_calc=1
if (QXF_out.eq.1) QXF_calc=1
if (QYF_out.eq.1) QYF_calc=1
if (ZLAY_out.eq.1) ZLAY_calc=1
if (P_out.eq.1) P_calc=1
if (PLEV_out.eq.1) PLEV_calc=1
if (FL_out.eq.1) FL_calc=1
if (UG_out.eq.1) UG_calc=1
if (VG_out.eq.1) VG_calc=1
if (UA_out.eq.1) UA_calc=1
if (VA_out.eq.1) VA_calc=1
if (VORT_out.eq.1) VORT_calc=1
if (AVO_out.eq.1) AVO_calc=1
if (CURVO_out.eq.1) CURVO_calc=1
if (TH_out.eq.1) TH_calc=1
if (PV_out.eq.1) PV_calc=1
if (LPV_out.eq.1) LPV_calc=1
if (VIP_out.eq.1) VIP_calc=1
if (RH_out.eq.1) RH_calc=1
if (THE_out.eq.1) THE_calc=1
if (THW_out.eq.1) THW_calc=1
if (DIVQU_out.eq.1) DIVQU_calc=1
if (CH_out.eq.1) CH_calc=1
if (PVR_out.eq.1) PVR_calc=1
if (Z_out.eq.1) Z_calc=1
if (Z_outP.eq.1) Z_calc=1
if (GRADTH_out.eq.1) GRADTH_calc=1
if (GRADPV_out.eq.1) GRADPV_calc=1
if (RHO_out.eq.1) RHO_calc=1
if (ALPHA_out.eq.1) ALPHA_calc=1
if (RI_out.eq.1) RI_calc=1
if (BLH_out.eq.1) BLH_calc=1
if (VEL_out.eq.1) VEL_calc=1
if (M_out.eq.1) M_calc=1
if (B_out.eq.1) B_calc=1
if (NSQM_out.eq.1) NSQM_calc=1
if (W_out.eq.1) W_calc=1
if (DTHDP_out.eq.1) DTHDP_calc=1
if (NSQ_out.eq.1) NSQ_calc=1 !(++)
C make dependencies for variable calculations:
c --------------------------------------------
if (NSQ_calc.eq.1) TH_calc=1 !(++)
if (DTHDP_calc.eq.1) TH_calc=1
if (PSRED_out.eq.1) PSRED_calc=1
if (PSRED_calc.eq.1) ZBneed=.true.
if (QX_out.eq.1) UG_calc=1
if (QY_out.eq.1) VG_calc=1
if (UA_calc.eq.1) UG_calc=1
if (VA_calc.eq.1) VG_calc=1
if (UG_calc.eq.1) ZLAY_calc=1
if (VG_calc.eq.1) ZLAY_calc=1
if (ZLAY_calc.eq.1) Z_calc=1
if (B_calc.eq.1) M_calc=1
if (M_calc.eq.1) ZLAY_calc=1
if (NSQ_calc.eq.1) RHO_calc=1
if (NSQM_calc.eq.1) RHO_calc=1
if (NSQM_calc.eq.1) THE_calc=1
if (W_calc.eq.1) RHO_calc=1
if (GRADTH_calc.eq.1) TH_calc=1
if (THW_calc.eq.1) THE_calc=1
if (THE_calc.eq.1) TH_calc=1
if (VIP_calc.eq.1) PV_calc=1
if (PV_calc.eq.1) TH_calc=1
if (LPV_calc.eq.1) PV_calc=1
if (PVR_calc.eq.1) CH_calc=1
if (CH_calc.eq.1) TH_calc=1
if (CH_calc.eq.1) RH_calc=1
if (RI_calc.eq.1) TH_calc=1
if (ALPHA_calc.eq.1) RHO_calc=1
print*,'processing: ',trim(cdfnam)
C Open files and get infos about data domain
c ------------------------------------------
if (Z_outP.eq.1) then
call cdfwopn(trim(cdfnam),cdfid1,ierr)
else
call cdfopn(trim(cdfnam),cdfid1,ierr)
endif
if (ierr.ne.0) then
print*,'ERROR opening input file, stopped'
stop
endif
call getcfn(cdfid1,cstnam,ierr)
if (ierr /= 0) then
cstnam = cdfnam
cstid = cdfid1
else
call cdfopn(trim(cstnam),cstid,ierr)
endif
C Inquire the variables on the netCDF file:
c -----------------------------------------
C Inquire number of variables and variable names
call getvars(cdfid1,nvars,vnam,ierr)
C print*,nvars,vnam(1),vnam(2)
do i=1,nvars
if (trim(vnam(i)).eq.'Q') qmode='Q'
if (trim(vnam(i)).eq.'QD') qmode='QD'
if (trim(vnam(i)).eq.'Z') ZonP=.true.
if (trim(vnam(i)).eq.'T') TonP=.true.
if (trim(vnam(i)).eq.'PS') PSonP=.true.
if (trim(vnam(i)).eq.'U') UonP=.true.
if (trim(vnam(i)).eq.'V') VonP=.true.
if (trim(vnam(i)).eq.'ZB') ZBonP=.true.
if (trim(vnam(i)).eq.'T2M') T2MonP=.true.
if (trim(vnam(i)).eq.'TD2M') TD2MonP=.true.
if (trim(vnam(i)).eq.'U10M') U10MonP=.true.
if (trim(vnam(i)).eq.'V10M') V10MonP=.true.
if (trim(vnam(i)).eq.'OMEGA') OMEGAonP=.true.
if (trim(vnam(i)).eq.'PV') PVonP=.true.
if (trim(vnam(i)).eq.'PV3') PV3onP=.true.
enddo
if (TonP) then
call getdef(cdfid1,'T',ndim,mdv,vardim,varmin,varmax,stag,ierr)
else
call getdef(cdfid1,vnam(2),ndim,mdv,
> vardim,varmin,varmax,stag,ierr)
endif
if (ierr.ne.0) goto 920
mdv=-999.98999
C Get the levels, pole, etc.
c --------------------------
nx=vardim(1)
ny=vardim(2)
nz=vardim(3)
C print*,nx,ny,nz
call getgrid(cstid,dx,dy,ierr)
call getlevs(cstid,nz,aklev,bklev,aklay,bklay,ierr)
call getpole(cstid,pollon,pollat,ierr)
call getstart(cstid,stdate,ierr)
C Allocate all arrays:
C --------------------
allocate(sp(nx,ny),STAT=stat)
if (stat.ne.0) print*,'error allocating sp(nx,ny)'
allocate(oro(nx,ny),STAT=stat)
if (stat.ne.0) print*,'error allocating oro(nx,ny)'
allocate(cl(nx,ny),STAT=stat)
if (stat.ne.0) print*,'error allocating cl(nx,ny)'
allocate(tl(nx,ny),STAT=stat)
if (stat.ne.0) print*,'error allocating tl(nx,ny)'
allocate(f(nx,ny),STAT=stat)
if (stat.ne.0) print*,'error allocating f(nx,ny)'
c allocate memory for results
allocate(var(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating var(nx,ny,nz)'
c allocate memory for variables on P-file (allocate all)
allocate(tt(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating tt(nx,ny,nz)'
allocate(qq(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating qq(nx,ny,nz)'
allocate(uu(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating uu(nx,ny,nz)'
allocate(vv(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating vv(nx,ny,nz)'
allocate(ww(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating ww(nx,ny,nz)'
allocate(t2m(nx,ny),STAT=stat)
if (stat.ne.0) print*,'error allocating t2m(nx,ny)'
allocate(td2m(nx,ny),STAT=stat)
if (stat.ne.0) print*,'error allocating td2m(nx,ny)'
allocate(u10m(nx,ny),STAT=stat)
if (stat.ne.0) print*,'error allocating u10m(nx,ny)'
allocate(v10m(nx,ny),STAT=stat)
if (stat.ne.0) print*,'error allocating v10m(nx,ny)'
allocate(ipv(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating ipv(nx,ny,nz)'
C Determine if data is on pressure or model levels
prelev=.true.
do k=1,nz
if (bklev(k).ne.0.) prelev=.false.
if (bklay(k).ne.0.) prelev=.false.
enddo
C print*,'prelev ',prelev
C Calculate cos(latitude) array and the coriolis parameter
if ((abs(pollon).gt.0.001).or.(abs(pollat-90.).gt.0.001)) then
do j=1,ny
rlat=varmin(2)+(j-1)*dy
do i=1,nx
rlon=varmin(1)+(i-1)*dx
yphys=phstoph(rlat,rlon,pollat,pollon)
C if I use sind(lat in deg): troubles at the N-pole
lat=2.*pi*yphys/360.
cl(i,j)=cosd(rlat)
tl(i,j)=tan(lat)
f(i,j)=0.000145444*sin(lat)
enddo
enddo
else
do j=1,ny
lat=varmin(2)+(j-1)*dy
lat=2.*pi*lat/360.
do i=1,nx
cl(i,j)=cos(lat)
f(i,j)=0.000145444*sin(lat)
enddo
enddo
endif
C Determine if data is on levels or layers
if (stag(3).eq.-0.5) then
ak=aklay
bk=bklay
else
ak=aklev
bk=bklev
endif
C Get all the fields
C ------------------
call gettimes(cdfid1,time,ntimes,ierr)
C Loop over all times
C -------------------
C print*,'loop over all times'
C print*,ntimes,vardim,nx,ny,nz
do n=1,ntimes
if (verbose) print*,'time=',time(n)
if (.not.prelev) then
if (PSonP) then
call getdat(cdfid1,'PS',time(n),0,sp,ierr)
if (ierr.ne.0) goto 921
else
if (verbose) print*,'PS not on P-file'
endif
endif
if (ZBonP) then
call getdat(cdfid1,'ZB',time(n),0,oro,ierr)
if (ierr.ne.0) goto 930
else
if (verbose) print*,'ZB not on P-file'
endif
if (TonP) then
call getdat(cdfid1,'T',time(n),0,tt,ierr)
if (ierr.ne.0) goto 920
else
if (verbose) print*,'T not on P-file'
endif
if (qmode.eq.'Q') then
call getdat(cdfid1,'Q',time(n),0,qq,ierr)
if (ierr.ne.0) goto 922
elseif (qmode.eq.'QD') then
call getdat(cdfid1,'QD',time(n),0,qq,ierr)
if (ierr.ne.0) goto 922
else
if (verbose) print*,'neither Q nor QD on P-file'
endif
if (ZonP) then
allocate(zz(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating zz'
call getdat(cdfid1,'Z',time(n),0,zz,ierr)
if (ierr.ne.0) then
print*,'error reading Z'
STOP
else
Z_calc=0 !indicate Z read
endif
endif
if (ZBneed) then
ZBneed=.false.
allocate(zb(nx,ny),STAT=stat)
if (stat.ne.0) print*,'error allocating zb'
if (ZBfile.ne.'') then
call cdfopn(trim(ZBfile),cdfid2,ierr)
if (ierr.ne.0) then
print*,'error opening ',trim(ZBfile)
ZBneed=.true.
endif
call gettimes(cdfid2,time2,ntimes2,ierr)
call getdat(cdfid2,'ZB',time2(1),0,zb,ierr)
else if (ZBonP) then
call getdat(cdfid1,'ZB',time(1),0,zb,ierr)
else
print*,'ZB needed (use option -zb filename)'
ZBneed=.true.
endif
if (ierr.ne.0) then
print*,'error reading ZB'
ZBneed=.true.
endif
endif
if (UonP) then
call getdat(cdfid1,'U',time(n),0,uu,ierr)
if (ierr.ne.0) goto 923
else
if (verbose) print*,'U not on P-file'
endif
if (VonP) then
call getdat(cdfid1,'V',time(n),0,vv,ierr)
if (ierr.ne.0) goto 924
else
if (verbose) print*,'V not on P-file'
endif
if (OMEGAonP) then
call getdat(cdfid1,'OMEGA',time(n),0,ww,ierr)
if (ierr.ne.0) goto 925
else
if (verbose) print*,'OMEGA not on P-file'
endif
if (T2MonP) then
call getdat(cdfid1,'T2M',time(n),0,t2m,ierr)
if (ierr.ne.0) goto 926
else
if (verbose) print*,'T2M not on P-file'
endif
if (TD2MonP) then
call getdat(cdfid1,'TD2M',time(n),0,td2m,ierr)
if (ierr.ne.0) goto 926
else
if (verbose) print*,'TD2M not on P-file'
endif
if (U10MonP) then
call getdat(cdfid1,'U10M',time(n),0,u10m,ierr)
if (ierr.ne.0) goto 926
else
if (verbose) print*,'U10M not on P-file'
endif
if (V10MonP) then
call getdat(cdfid1,'V10M',time(n),0,v10m,ierr)
if (ierr.ne.0) goto 926
else
if (verbose) print*,'V10M not on P-file'
endif
if (PVonP) then
call getdat(cdfid1,'PV',time(n),0,ipv,ierr)
if (ierr.ne.0) goto 926
else
if (verbose) print*,'PV not on P-file'
endif
if (PV3onP) then
call getdat(cdfid1,'PV3',time(n),0,ipv,ierr)
if (ierr.ne.0) goto 926
else
if (verbose) print*,'PV3 not on P-file'
endif
C Calculation of the geopotential
if (Z_calc.eq.1) then
allocate(zz(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating zz'
call zlev(zz,tt,qq,oro,sp,nx,ny,nz,aklev,bklev)
endif
if (Z_outP.eq.1) then
if (n.eq.1) then
stag(3)=0.0
call putdef(cdfid1,'Z',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable Z created on P-file'
stag(3)=-0.5
endif
call putdat(cdfid1,'Z',time(n),0,zz,ierr)
endif
C Create the secondary data file
if (n.eq.1) then
call cdfwopn(trim(outfnam),cdfid,ierr)
if (ierr.ne.0) then
call crecdf(trim(outfnam),cdfid,varmin,varmax,
> 3,trim(cstnam),ierr)
write(*,*)'*** NetCDF file ',trim(outfnam),' created'
else
write(*,*)'*** NetCDF file ',trim(outfnam),
> ' used for appending'
PS_out=0
endif
endif
C Put surface pressure on S-file
if ((.not.prelev).and.(PS_out.eq.1)) then
vardim(3)=1
if (n.eq.1) then
call putdef(cdfid,'PS',4,mdv,vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable PS created on ',trim(outfnam)
endif
call putdat(cdfid,'PS',time(n),0,sp,ierr)
vardim(3)=nz
endif
C Put geopotential on S-file
if (Z_out.eq.1) then
if (n.eq.1) then
stag(3)=0.0
call putdef(cdfid,'Z',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable Z created on ',trim(outfnam)
stag(3)=-0.5
endif
call putdat(cdfid,'Z',time(n),0,zz,ierr)
endif
C Calculate the secondary data variables
C --------------------------------------
C Calculation of potential temperature
if (TH_calc.eq.1) then
allocate(th(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating th'
call pottemp(th,tt,sp,nx,ny,nz,ak,bk)
if (TH_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'TH',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable TH created on ',trim(outfnam)
endif
call putdat(cdfid,'TH',time(n),0,th,ierr)
endif
endif
C Calculation of relative humidity
if (RH_calc.eq.1) then
allocate(rh(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating rh'
call relhum(rh,qq,tt,sp,nx,ny,nz,ak,bk)
if (RH_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'RH',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable RH created on ',trim(outfnam)
endif
call putdat(cdfid,'RH',time(n),0,rh,ierr)
endif
endif
C Calculation of potential vorticity (equals PV3 in IVE)
if (PV_calc.eq.1) then
allocate(pv(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating pv'
call potvort(pv,uu,vv,th,sp,cl,f,nx,ny,nz,ak,bk,
> varmin,varmax)
if (PV_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'PV',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable PV created on ',trim(outfnam)
endif
call putdat(cdfid,'PV',time(n),0,pv,ierr)
endif
endif
C Calculation of LAIT potential vorticity
if (LPV_calc.eq.1) then
allocate(lpv(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating lpv'
call laitpv(lpv,pv,th,nx,ny,nz)
if (LPV_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'LPV',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable LPV created on ',trim(outfnam)
endif
call putdat(cdfid,'LPV',time(n),0,lpv,ierr)
endif
endif
C Calculation of equivalent potential temperature
if (THE_calc.eq.1) then
allocate(the(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating the'
call equpot(the,tt,qq,sp,nx,ny,nz,ak,bk)
if (THE_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'THE',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable THE created on ',trim(outfnam)
endif
call putdat(cdfid,'THE',time(n),0,the,ierr)
endif
endif
C Calculation of wet-bulb potential temperature
if (THW_calc.eq.1) then
call wetbpt(var,the,sp,nx,ny,nz,ak,bk)
if (THW_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'THW',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable THW created on ',trim(outfnam)
endif
call putdat(cdfid,'THW',time(n),0,var,ierr)
endif
endif
C Calculation of water flux divergence
if (DIVQU_calc.eq.1) then
call divqu(var,uu,vv,qq,cl,nx,ny,nz,varmin,varmax,mdv)
if (DIVQU_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'DIVQU',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable DIVQU created on ',
> trim(outfnam)
endif
call putdat(cdfid,'DIVQU',time(n),0,var,ierr)
endif
endif
C Calculation of diabatic heating rate (also DHR in IVE)
if (CH_calc.eq.1) then
allocate(dhr(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating dhr'
call diabheat(dhr,th,ww,rh,sp,nx,ny,nz,ak,bk)
if (CH_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'CH',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable CH created on ',trim(outfnam)
endif
call putdat(cdfid,'CH',time(n),0,dhr,ierr)
endif
endif
C Calculation of diabatic PV rate (also DPVR in IVE)
if (PVR_calc.eq.1) then
call diabpvr(var,uu,vv,dhr,sp,cl,f,nx,ny,nz,ak,bk,
> varmin,varmax)
if (PVR_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'PVR',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable PVR created on ',trim(outfnam)
endif
call putdat(cdfid,'PVR',time(n),0,var,ierr)
endif
endif
C Calculation of the theta gradient
if (GRADTH_calc.eq.1) then
call gradth(var,th,sp,prelev,cl,nx,ny,nz,ak,bk,varmin,varmax)
if (GRADTH_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'GRADTH',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable GRADTH created on ',trim(outfnam)
endif
call putdat(cdfid,'GRADTH',time(n),0,var,ierr)
endif
endif
C Calculation of density RHO
if (RHO_calc.eq.1) then
allocate(rho(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating rho'
call calc_rho(rho,tt,sp,nx,ny,nz,ak,bk)
if (RHO_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'RHO',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable RHO created on ',trim(outfnam)
endif
call putdat(cdfid,'RHO',time(n),0,rho,ierr)
endif
endif
C Calculation of specific volume ALPHA
if (ALPHA_calc.eq.1) then
print*,'calculate alpha',n
allocate(alpha(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating rho'
alpha = 1. / rho
if (ALPHA_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'ALPHA',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable ALPHA created on ',
> trim(outfnam)
endif
call putdat(cdfid,'ALPHA',time(n),0,alpha,ierr)
endif
endif
C Calculation of Brunt-Vaisala frequ. N^2
if (NSQ_calc.eq.1) then
call nsq(var,rho,th,sp,nx,ny,nz,ak,bk)
if (NSQ_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'NSQ',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable NSQ created on ',trim(outfnam)
endif
call putdat(cdfid,'NSQ',time(n),0,var,ierr)
endif
endif
C Calculation of Brunt-Vaisala frequ. N^2 with ThetaE
if (NSQM_calc.eq.1) then
call nsq(var,rho,the,sp,nx,ny,nz,ak,bk)
if (NSQM_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'NSQM',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable NSQM created on ',trim(outfnam)
endif
call putdat(cdfid,'NSQM',time(n),0,var,ierr)
endif
endif
C Calculation of vertical gradient of potential temp. (-g d(th)/dp)
if (DTHDP_calc.eq.1) then
call dthetadp(var,th,sp,nx,ny,nz,ak,bk)
if (DTHDP_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'DTHDP',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable DTHDP created on ',trim(outfnam)
endif
call putdat(cdfid,'DTHDP',time(n),0,var,ierr)
endif
endif
C Calculation of vertical velocity W
c get the vertical wind velocity in Cart. coordinates.
c Omega is given in hPa/s.
if (W_calc.eq.1) then
where (rho.ne.0.) var=-100.*ww/(9.80616*rho)
if (W_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'W',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable W created on ',trim(outfnam)
endif
call putdat(cdfid,'W',time(n),0,var,ierr)
endif
endif
C Calculation of velocity VEL
if (VEL_calc.eq.1) then
var=sqrt(uu**2+vv**2)
if (VEL_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'VEL',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable VEL created on ',trim(outfnam)
endif
call putdat(cdfid,'VEL',time(n),0,var,ierr)
endif
endif
C Calculation of ZLAY
if (ZLAY_calc.eq.1) then
allocate(zlay(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating zlay'
call zlayer(zlay,tt,zz,sp,nx,ny,nz,aklev,bklev,aklay,bklay)
if (ZLAY_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'ZLAY',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable ZLAY created on ',trim(outfnam)
endif
call putdat(cdfid,'ZLAY',time(n),0,zlay,ierr)
endif
endif
C Calculation of Montgomery-Potential M
if (M_calc.eq.1) then
allocate(mm(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating mm'
mm=1004.*(tt+273.15)+9.80616*1000.*zlay
if (M_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'M',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable M created on ',trim(outfnam)
endif
call putdat(cdfid,'M',time(n),0,mm,ierr)
endif
endif
C Calculation of Bernoulli-Function B
if (B_calc.eq.1) then
var=mm+0.5*(uu**2+vv**2)
if (B_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'B',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable B created on ',trim(outfnam)
endif
call putdat(cdfid,'B',time(n),0,var,ierr)
endif
endif
C Calculation of relative vertical vorticity VORT
if (VORT_calc.eq.1) then
call vort(var,uu,vv,sp,cl,nx,ny,nz,ak,bk,varmin,varmax)
if (VORT_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'VORT',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable VORT created on ',trim(outfnam)
endif
call putdat(cdfid,'VORT',time(n),0,var,ierr)
endif
endif
C Calculation of absolute vertical vorticity AVO
if (AVO_calc.eq.1) then
call avort(var,uu,vv,sp,cl,f,nx,ny,nz,ak,bk,varmin,varmax)
if (AVO_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'AVO',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable AVO created on ',trim(outfnam)
endif
call putdat(cdfid,'AVO',time(n),0,var,ierr)
endif
endif
C Calculation of vertical curvature vorticity CURVO
if (CURVO_calc.eq.1) then
call curvo(var,uu,vv,sp,cl,nx,ny,nz,ak,bk,varmin,varmax)
if (CURVO_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'CURVO',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable CURVO created on ',trim(outfnam)
endif
call putdat(cdfid,'CURVO',time(n),0,var,ierr)
endif
endif
C Output of cos(latitude) array
if (COS_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'COS',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable COS created on ',trim(outfnam)
endif
call putdat(cdfid,'COS',time(n),0,cl,ierr)
endif
C Output of vertically integrated PV (VIP)
if (VIP_out.eq.1) then
allocate(vip(nx,ny),STAT=stat)
if (stat.ne.0) print*,'error allocating vip'
call vint(vip,pv,sp,150.,500.,nx,ny,nz,ak,bk)
if (n.eq.1) then
vardim(3)=1
call putdef(cdfid,'VIP',4,mdv,
> vardim,varmin,varmax,stag,ierr)
vardim(3)=nz
write(*,*)'*** variable VIP created on ',trim(outfnam)
endif
call putdat(cdfid,'VIP',time(n),0,vip,ierr)
endif
C Calculation of PV gradient (GRADPV)
if (GRADPV_out.eq.1) then
C write(*,*)'*** calling gradpv ***'
allocate(gradpv(nx,ny),STAT=stat)
if (stat.ne.0) print*,'error allocating gradpv'
call calc_gradpv(gradpv,ipv,cl,nx,ny,nz,akd,bkd,
> varmin,varmax)
if (n.eq.1) then
vardim(3)=1
call putdef(cdfid,'GRADPV',4,mdv,
> vardim,varmin,varmax,stag,ierr)
vardim(3)=nz
write(*,*)'*** variable GRADPV created on ',trim(outfnam)
endif
call putdat(cdfid,'GRADPV',time(n),0,gradpv,ierr)
endif
C Calculation of P
if (P_calc.eq.1) then
call pressure(var,sp,-0.5,nx,ny,nz,aklev,bklev,aklay,bklay)
if (P_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'P',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable P created on ',trim(outfnam)
endif
call putdat(cdfid,'P',time(n),0,var,ierr)
endif
endif
C Calculation of PLEV
if (PLEV_calc.eq.1) then
call pressure(var,sp,0.,nx,ny,nz,aklev,bklev,aklay,bklay)
if (PLEV_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'PLEV',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable PLEV created on ',trim(outfnam)
endif
call putdat(cdfid,'PLEV',time(n),0,var,ierr)
endif
endif
C Calculation of FL
if (FL_calc.eq.1) then
allocate(fl(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating fl'
call pres(var,sp,nx,ny,nz,aklay,bklay)
call flightlev(fl,var,nx,ny,nz)
if (FL_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'FL',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable FL created on ',trim(outfnam)
endif
call putdat(cdfid,'FL',time(n),0,fl,ierr)
endif
endif
C Calculation of geostrophic wind UG
if (UG_calc.eq.1) then
allocate(ug(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating ug'
call calc_ug(ug,zlay,sp,cl,f,nx,ny,nz,ak,bk,varmin,varmax)
if (UG_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'UG',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable UG created on ',trim(outfnam)
endif
call putdat(cdfid,'UG',time(n),0,ug,ierr)
endif
endif
C Calculation of geostrophic wind VG
if (VG_calc.eq.1) then
allocate(vg(nx,ny,nz),STAT=stat)
if (stat.ne.0) print*,'error allocating vg'
call calc_vg(vg,zlay,sp,cl,f,nx,ny,nz,ak,bk,varmin,varmax)
if (VG_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'VG',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable VG created on ',trim(outfnam)
endif
call putdat(cdfid,'VG',time(n),0,vg,ierr)
endif
endif
C Calculation of ageostrophic geostrophic wind UA
if (UA_calc.eq.1) then
var=uu-ug
if (UA_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'UA',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable UA created on ',trim(outfnam)
endif
call putdat(cdfid,'UA',time(n),0,var,ierr)
endif
endif
C Calculation of ageostrophic geostrophic wind VA
if (VA_calc.eq.1) then
var=vv-vg
if (VA_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'VA',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable VA created on ',trim(outfnam)
endif
call putdat(cdfid,'VA',time(n),0,var,ierr)
endif
endif
C Calculation of x-component of the Q-vector (calc. with U)
if (QXF_calc.eq.1) then
call calc_qx(var,uu,vv,tt,sp,cl,nx,ny,nz,ak,bk,varmin,varmax)
if (QXF_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'QXF',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable QXF created on ',trim(outfnam)
endif
call putdat(cdfid,'QXF',time(n),0,var,ierr)
endif
endif
C Calculation of y-component of the Q-vector (calc. with V)
if (QYF_calc.eq.1) then
call calc_qy(var,uu,vv,tt,sp,cl,tl,nx,ny,nz,ak,bk,varmin,varmax)
if (QYF_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'QYF',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable QYF created on ',trim(outfnam)
endif
call putdat(cdfid,'QYF',time(n),0,var,ierr)
endif
endif
C Calculation of x-component of the Q-vector (calc. with UG)
if (QX_calc.eq.1) then
call calc_qx(var,ug,vg,tt,sp,cl,nx,ny,nz,ak,bk,varmin,varmax)
if (QX_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'QX',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable QX created on ',trim(outfnam)
endif
call putdat(cdfid,'QX',time(n),0,var,ierr)
endif
endif
C Calculation of y-component of the Q-vector (calc. with VG)
if (QY_calc.eq.1) then
call calc_qy(var,ug,vg,tt,sp,cl,tl,nx,ny,nz,ak,bk,varmin,varmax)
if (QY_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'QY',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable QY created on ',trim(outfnam)
endif
call putdat(cdfid,'QY',time(n),0,var,ierr)
endif
endif
C Calculation of reduced surface pressure PSRED
if (PSRED_calc.eq.1) then
if (.not.ZBneed) then
call calc_psred(var,sp,tt,zb,nx,ny,nz,aklay,bklay)
if (PSRED_out.eq.1) then
if (n.eq.1) then
vardim2=vardim
vardim2(3)=1 ! force one vertical-level
call putdef(cdfid,'PSRED',4,mdv,
> vardim2,varmin,varmax,stag,ierr)
write(*,*)'*** variable PSRED created on ',trim(outfnam)
endif
call putdat(cdfid,'PSRED',time(n),0,var,ierr)
endif
else
print*,'ZB needed to calculate PSRED'
endif
endif
C Calculation of Richardson number
if (RI_calc.eq.1) then
call rich(var,sp,uu,vv,th,nx,ny,nz,ak,bk)
if (RI_out.eq.1) then
if (n.eq.1) then
call putdef(cdfid,'RI',4,mdv,
> vardim,varmin,varmax,stag,ierr)
write(*,*)'*** variable RI created on ',trim(outfnam)
endif
call putdat(cdfid,'RI',time(n),0,var,ierr)
endif
endif
C Calculation of boundary layer height BLH
if (BLH_calc.eq.1) then
call calc_blh(var,sp,tt,qq,uu,vv,t2m,td2m,u10m,v10m,
> nx,ny,nz,aklay,bklay)
if (BLH_out.eq.1) then
if (n.eq.1) then
vardim2=vardim
vardim2(3)=1 ! force one vertical-level
call putdef(cdfid,'BLH',4,mdv,
> vardim2,varmin,varmax,stag,ierr)
write(*,*)'*** variable BLH created on ',trim(outfnam)
endif
call putdat(cdfid,'BLH',time(n),0,var,ierr)
endif
endif
c add calculations of your own variables here: (++)
enddo
C Close the NetCDF files
call clscdf(cdfid,ierr)
900 continue
call clscdf(cdfid1,ierr)
call clscdf(cstid,ierr)
goto 999
920 stop '*** error: variable T not found on P-file ***'
921 stop '*** error: variable PS not found on P-file ***'
922 stop '*** error: variable Q not found on P-file ***'
923 stop '*** error: variable U not found on P-file ***'
924 stop '*** error: variable V not found on P-file ***'
925 stop '*** error: variable OMEGA not found on P-file ***'
926 stop '*** error: variable T2M not found on P-file ***'
927 stop '*** error: variable TD2M not found on P-file ***'
928 stop '*** error: variable U10M not found on P-file ***'
929 stop '*** error: variable V10M not found on P-file ***'
930 stop '*** error: variable ZB not found on P-file ***'
996 stop '*** error: could not create S-file ***'
999 continue
end
c-----------------------------------------------------------------------
c following subroutines
c-----------------------------------------------------------------------
subroutine calc_rho(var,tt,sp,ie,je,ke,ak,bk)
c ============================================
c computation of density
c
c argument declaration
integer ie,je,ke
real,intent(OUT) :: var(ie,je,ke)
real,intent(IN) :: tt(ie,je,ke),sp(ie,je)
real,intent(IN) :: ak(ke),bk(ke)
integer i,j,k
real,parameter :: tzero=273.15
c statement-functions for the computation of pressure
real pp,psrf
integer is
pp(is)=ak(is)+bk(is)*psrf
c computation of potential temperature
do i=1,ie
do j=1,je
psrf=sp(i,j)
do k=1,ke
c distinction of temperature in K and deg C
if (tt(i,j,k).lt.100.) then
var(i,j,k)=pp(k)/(2.87*(tt(i,j,k)+tzero))
else
var(i,j,k)=pp(k)/(2.87*tt(i,j,k))
endif
enddo
enddo
enddo
end
subroutine nsq(var,rho,th,sp,ie,je,ke,ak,bk)
C ======================================================
c argument declaration
integer,intent(IN) :: ie,je,ke
real,intent(OUT) :: var(ie,je,ke)
real,intent(IN) :: rho(ie,je,ke),th(ie,je,ke),sp(ie,je)
real,intent(IN) :: ak(ke),bk(ke)
c variable declaration
integer stat
REAL,ALLOCATABLE, DIMENSION (:,:,:) :: dthdp !3D array
allocate(dthdp(ie,je,ke),STAT=stat)
IF (stat.ne.0) PRINT*,'nsq: error allocating dthdp(ie,je,ke)'
call ddp(th,dthdp,sp,ie,je,ke,ak,bk)
where(th.ne.0.) var=-96.24*rho/th*dthdp
IF (ALLOCATED(dthdp)) DEALLOCATE(dthdp)
end
subroutine dthetadp(var,th,sp,ie,je,ke,ak,bk)
C ======================================================
c argument declaration
integer,intent(IN) :: ie,je,ke
real,intent(OUT) :: var(ie,je,ke)
real,intent(IN) :: th(ie,je,ke),sp(ie,je)
real,intent(IN) :: ak(ke),bk(ke)
c variable declaration
integer stat
REAL,ALLOCATABLE, DIMENSION (:,:,:) :: dthdp !3D array
allocate(dthdp(ie,je,ke),STAT=stat)
IF (stat.ne.0) PRINT*,'nsq: error allocating dthdp(ie,je,ke)'
call ddp(th,dthdp,sp,ie,je,ke,ak,bk)
c factor 100 is because VORT is in units of f and so VORT*DTHDP
c is in pvu
var=-9.80616*100.*dthdp
IF (ALLOCATED(dthdp)) DEALLOCATE(dthdp)
end
subroutine geopot(psi,q,t,oro,sp,ie,je,ke,ak,bk)
c ================================================
c argument declaration
integer ie,je,ke
real psi(ie,je,ke),t(ie,je,ke),q(ie,je,ke),oro(ie,je),
> sp(ie,je),ak(ke),bk(ke)
c variable declaration
integer i,j,k
real r,c,g
data r,c,g /287.,0.608,9.80616/
c statement-functions for the computation of pressure
real pp,psrf
integer is
pp(is)=ak(is)+bk(is)*psrf
c integration of geopotential height(special for first layer)
do i=1,ie
do j=1,je
psrf=sp(i,j)
psi(i,j,1)=1./g*(oro(i,j)
> +r*(t(i,j,1)+273.15)*(1.+c*q(i,j,1))*
> (psrf-pp(1))/(0.5*(psrf+pp(1))))
enddo
enddo
do j=1,je
do i=1,ie
psrf=sp(i,j)
do k=2,ke
psi(i,j,k)=psi(i,j,k-1)+r/g*
> ((t(i,j,k-1)+273.15)*(1.+c*q(i,j,k-1))+
> (t(i,j,k)+273.15)*(1.+c*q(i,j,k)))*
> (pp(k-1)-pp(k))/(pp(k-1)+pp(k))
enddo
enddo
enddo
end
subroutine getoro(or,dx,dy,starty,lonmin,latmin,ie,je,ierr)
c ===========================================================
c reads the orography for the actual data domain from the file
c "/home/henry/ecmwf/cdf/orogr", which contains the orography
c for the whole northern hemisphere.
c argument declaration
integer ie,je
real or(ie,je)
c variable declaration
integer i,j,cdfid,ierr,i0,j0,err,starty,nx
real gloro(480*240)
real dx,dy,dd,time,lonmin,latmin
character*(80)filnam
integer vardim(3),ndim
real varmin(3),varmax(3),stag(3),mdv
time=0.
c open file with orography values and get them
call ncpopt(NCVERBOS)
c q&d bug fix (dx, dy were changed below when calculating i0)
dd=dx
if ((dx.eq.0.75).and.(dy.eq.0.75)) then
if (starty.lt.96) then
if (starty.le.92) then
filnam="/home/henry/cdf/oro/9209orogr0_75"
else if (starty.le.93) then
filnam="/home/henry/cdf/oro/9309orogr0_75"
else if (starty.le.94) then
filnam="/home/henry/cdf/oro/9411orogr0_75"
else if (starty.le.95) then
filnam="/home/henry/cdf/oro/9509orogr0_75"
else
filnam="/home/henry/cdf/oro/orogr0_75"
endif
else
filnam="/home/henry/cdf/oro/95orogr0_75"
endif
else if ((dx.eq.1.0).and.(dy.eq.1.0)) then
if (starty.lt.95) then
filnam="/home/henry/cdf/oro/orogr1_00"
else
filnam="/home/henry/cdf/oro/gloro1_00"
endif
else if ((dx.eq.0.5).and.(dy.eq.0.5)) then
filnam="/home/henry/cdf/oro/95orogr0_50"
else
print*,'unappropriate data for the orography file'
print*,'grid interval should be 0.5, 0.75 or 1.00
> and data only on the NH'
ierr=2
return
endif
print*,filnam
call cdfopn(trim(filnam),cdfid,err)
call getdat(cdfid,'ORO',time,0,gloro,err)
call getdef(cdfid,'ORO',ndim,mdv,vardim,varmin,varmax,stag,err)
* call clscdf(cdfid,err)
i0=nint((lonmin-varmin(1))/dd)
j0=nint((latmin-varmin(2))/dd)
if (j0.lt.0) j0=-j0
nx=nint(360./dd)
do i=1,ie
do j=1,je
if (i0+i.le.nx) then
or(i,j)=gloro(i0+i+(j0+j-1)*nx)
else
or(i,j)=gloro(i0+i-nx+(j0+j-1)*nx)
endif
if (or(i,j).gt.1.e20) print*,i,j,i0+i+(j0+j-1)*nx
enddo
enddo
end
subroutine calc_qx(var,uu,vv,tt,sp,cl,ie,je,ke,ak,bk,vmin,vmax)
C ===============================================================
c calculate x-comp Q-vector: -9.8/273.*(D[U:X]*D[T:X]+D[V:X]*D[T:Y])
c argument declaration
integer ie,je,ke
real,intent(OUT) :: var(ie,je,ke)
real,intent(IN) :: uu(ie,je,ke),vv(ie,je,ke),tt(ie,je,ke)
real,intent(IN) :: sp(ie,je),cl(ie,je)
real,intent(IN) :: ak(ke),bk(ke),vmin(4),vmax(4)
c variable declaration
REAL,ALLOCATABLE, DIMENSION (:,:) :: dspdx,dspdy
REAL,ALLOCATABLE, DIMENSION (:,:,:) :: dudx,dtdx,dvdx,dtdy
integer stat
integer k
real mdv
logical prelev
c test if pressure or model levels
prelev=.true.
do k=1,ke
if (bk(k).ne.0.) prelev=.false.
enddo
mdv=-999.98999
if (.not.prelev) then
allocate(dspdx(ie,je),STAT=stat)
if (stat.ne.0) print*,'calc_qx: error allocating dspdx'
allocate(dspdy(ie,je),STAT=stat)
if (stat.ne.0) print*,'calc_qx: error allocating dspdy'
endif
allocate(dudx(ie,je,ke),STAT=stat)
if (stat.ne.0) print*,'calc_qx: error allocating dudx'
allocate(dtdx(ie,je,ke),STAT=stat)
if (stat.ne.0) print*,'calc_qx: error allocating dtdx'
allocate(dvdx(ie,je,ke),STAT=stat)
if (stat.ne.0) print*,'calc_qx: error allocating dvdx'
allocate(dtdy(ie,je,ke),STAT=stat)
if (stat.ne.0) print*,'calc_qx: error allocating dtdy'
if (prelev) then
do k=1,ke
call ddh2m(uu(1,1,k),dudx(1,1,k),cl,'X',ie,je,1,vmin,vmax,mdv)
call ddh2m(tt(1,1,k),dtdx(1,1,k),cl,'X',ie,je,1,vmin,vmax,mdv)
call ddh2m(vv(1,1,k),dvdx(1,1,k),cl,'X',ie,je,1,vmin,vmax,mdv)
call ddh2m(tt(1,1,k),dtdy(1,1,k),cl,'Y',ie,je,1,vmin,vmax,mdv)
enddo
else
call ddh2(sp,dspdx,cl,'X',ie,je,1,vmin,vmax)
call ddh2(sp,dspdy,cl,'Y',ie,je,1,vmin,vmax)
call ddh3(uu,dudx,sp,dspdx,cl,'X',ie,je,ke,vmin,vmax,ak,bk)
call ddh3(tt,dtdx,sp,dspdx,cl,'X',ie,je,ke,vmin,vmax,ak,bk)
call ddh3(vv,dvdx,sp,dspdx,cl,'X',ie,je,ke,vmin,vmax,ak,bk)
call ddh3(tt,dtdy,sp,dspdx,cl,'Y',ie,je,ke,vmin,vmax,ak,bk)
endif
var=-1.e9*9.80616/273.*(dudx*dtdx+dvdx*dtdy)
if (prelev) then
do i=1,ie
do j=1,je
do k=1,ke
if ((dudx(i,j,k).eq.mdv).or.
> (dtdx(i,j,k).eq.mdv).or.
> (dvdx(i,j,k).eq.mdv).or.
> (dtdy(i,j,k).eq.mdv)) then
var(i,j,k)=mdv
endif
enddo
enddo
enddo
endif
IF (ALLOCATED(dspdx)) DEALLOCATE(dspdx)
IF (ALLOCATED(dspdy)) DEALLOCATE(dspdy)
IF (ALLOCATED(dudx)) DEALLOCATE(dudx)
IF (ALLOCATED(dtdx)) DEALLOCATE(dtdx)
IF (ALLOCATED(dvdx)) DEALLOCATE(dvdx)
IF (ALLOCATED(dtdy)) DEALLOCATE(dtdy)
end
subroutine calc_qy(var,uu,vv,tt,sp,cl,tl,ie,je,ke,ak,bk,vmin,vmax)
C ===============================================================
c calculate y-comp Q-vector: -9.8/273.*(D[U:Y]*D[T:X]+D[V:Y]*D[T:Y]
c -U/6.37E6*TAN*D[T:X]-V/6.37E6*TAN*D[T:Y])
c argument declaration
integer ie,je,ke
real,intent(OUT) :: var(ie,je,ke)
real,intent(IN) :: uu(ie,je,ke),vv(ie,je,ke),tt(ie,je,ke)
real,intent(IN) :: sp(ie,je),cl(ie,je),tl(ie,je)
real,intent(IN) :: ak(ke),bk(ke),vmin(4),vmax(4)
c variable declaration
REAL,ALLOCATABLE, DIMENSION (:,:) :: dspdx,dspdy
REAL,ALLOCATABLE, DIMENSION (:,:,:) :: dudy,dtdx,dvdy,dtdy,tl3d
integer k,stat
real mdv
logical prelev
c test if pressure or model levels
prelev=.true.
do k=1,ke
if (bk(k).ne.0.) prelev=.false.
enddo
mdv=-999.98999
if (.not.prelev) then
allocate(dspdx(ie,je),STAT=stat)
if (stat.ne.0) print*,'calc_qy: error allocating dspdx'
allocate(dspdy(ie,je),STAT=stat)
if (stat.ne.0) print*,'calc_qy: error allocating dspdy'
endif
allocate(dudy(ie,je,ke),STAT=stat)
if (stat.ne.0) print*,'calc_qy: error allocating dudy'
allocate(dtdx(ie,je,ke),STAT=stat)
if (stat.ne.0) print*,'calc_qy: error allocating dtdx'
allocate(dvdy(ie,je,ke),STAT=stat)
if (stat.ne.0) print*,'calc_qy: error allocating dvdy'
allocate(dtdy(ie,je,ke),STAT=stat)
if (stat.ne.0) print*,'calc_qy: error allocating dtdy'
allocate(tl3d(ie,je,ke),STAT=stat)
if (stat.ne.0) print*,'calc_qy: error allocating tl3d'
if (prelev) then
do k=1,ke
call ddh2m(uu(1,1,k),dudy(1,1,k),cl,'Y',ie,je,1,vmin,vmax,mdv)
call ddh2m(tt(1,1,k),dtdx(1,1,k),cl,'X',ie,je,1,vmin,vmax,mdv)
call ddh2m(vv(1,1,k),dvdy(1,1,k),cl,'Y',ie,je,1,vmin,vmax,mdv)
call ddh2m(tt(1,1,k),dtdy(1,1,k),cl,'Y',ie,je,1,vmin,vmax,mdv)
enddo
else
call ddh2(sp,dspdx,cl,'X',ie,je,1,vmin,vmax)
call ddh2(sp,dspdy,cl,'Y',ie,je,1,vmin,vmax)
call ddh3(uu,dudy,sp,dspdx,cl,'Y',ie,je,ke,vmin,vmax,ak,bk)
call ddh3(tt,dtdx,sp,dspdx,cl,'X',ie,je,ke,vmin,vmax,ak,bk)
call ddh3(vv,dvdy,sp,dspdx,cl,'Y',ie,je,ke,vmin,vmax,ak,bk)
call ddh3(tt,dtdy,sp,dspdx,cl,'Y',ie,je,ke,vmin,vmax,ak,bk)
endif
do k=1,ke
tl3d(1:ie,1:je,k)=tl(1:ie,1:je)
enddo
var=-1.e9*9.80616/273.*(dudy*dtdx+dvdy*dtdy
> -uu/6.37E6*tl3d*dtdx-vv/6.37E6*tl3d*dtdy)
if (prelev) then
do i=1,ie
do j=1,je
do k=1,ke
if ((dudy(i,j,k).eq.mdv).or.
> (dtdx(i,j,k).eq.mdv).or.
> (dvdy(i,j,k).eq.mdv).or.
> (dtdy(i,j,k).eq.mdv)) then
var(i,j,k)=mdv
endif
enddo
enddo
enddo
endif
IF (ALLOCATED(dspdx)) DEALLOCATE(dspdx)
IF (ALLOCATED(dspdy)) DEALLOCATE(dspdy)
IF (ALLOCATED(dudy)) DEALLOCATE(dudy)
IF (ALLOCATED(dtdx)) DEALLOCATE(dtdx)
IF (ALLOCATED(dvdy)) DEALLOCATE(dvdy)
IF (ALLOCATED(dtdy)) DEALLOCATE(dtdy)
IF (ALLOCATED(tl3d)) DEALLOCATE(tl3d)
end
subroutine calc_ug(var,zz,sp,cl,f,ie,je,ke,ak,bk,vmin,vmax)
C ===========================================================
C calculate geostrophic wind
c argument declaration
integer ie,je,ke
real,intent(OUT) :: var(ie,je,ke)
real,intent(IN) :: zz(ie,je,ke),
> sp(ie,je),cl(ie,je),f(ie,je)
real ak(ke),bk(ke),vmin(4),vmax(4)
c variable declaration
REAL,ALLOCATABLE, DIMENSION (:,:) :: dspdy
REAL,ALLOCATABLE, DIMENSION (:,:,:) :: dzzdy
integer k,stat
allocate(dspdy(ie,je),STAT=stat)
if (stat.ne.0) print*,'calc_ug: error allocating dspdy'
allocate(dzzdy(ie,je,ke),STAT=stat)
if (stat.ne.0) print*,'calc_ug: error allocating dzzdy'
call ddh2(sp,dspdy,cl,'Y',ie,je,1,vmin,vmax)
call ddh3(zz,dzzdy,sp,dspdy,cl,'Y',ie,je,ke,vmin,vmax,ak,bk)
do k=1,ke
var(1:ie,1:je,k)=-dzzdy(1:ie,1:je,k)
> *9810.*(f(1:ie,1:je)/((ABS(f(1:ie,1:je))+1.e-12)**2))
enddo
IF (ALLOCATED(dspdy)) DEALLOCATE(dspdy)
IF (ALLOCATED(dzzdy)) DEALLOCATE(dzzdy)
end
subroutine calc_vg(var,zz,sp,cl,f,ie,je,ke,ak,bk,vmin,vmax)
C ===========================================================
C calculate geostrophic wind
c argument declaration
integer ie,je,ke
real,intent(OUT) :: var(ie,je,ke)
real,intent(IN) :: zz(ie,je,ke),
> sp(ie,je),cl(ie,je),f(ie,je)
real ak(ke),bk(ke),vmin(4),vmax(4)
c variable declaration
REAL,ALLOCATABLE, DIMENSION (:,:) :: dspdx
REAL,ALLOCATABLE, DIMENSION (:,:,:) :: dzzdx
integer k,stat
allocate(dspdx(ie,je),STAT=stat)
if (stat.ne.0) print*,'calc_vg: error allocating dspdx'
allocate(dzzdx(ie,je,ke),STAT=stat)
if (stat.ne.0) print*,'calc_vg: error allocating dzzdx'
call ddh2(sp,dspdx,cl,'X',ie,je,1,vmin,vmax)
call ddh3(zz,dzzdx,sp,dspdx,cl,'X',ie,je,ke,vmin,vmax,ak,bk)
do k=1,ke
var(1:ie,1:je,k)=dzzdx(1:ie,1:je,k)
> *9810.*(f(1:ie,1:je)/((ABS(f(1:ie,1:je))+1.e-12)**2))
enddo
IF (ALLOCATED(dspdx)) DEALLOCATE(dspdx)
IF (ALLOCATED(dzzdx)) DEALLOCATE(dzzdx)
end
subroutine zlayer(ap,t,z,sp,ie,je,ke,aklev,bklev,aklay,bklay)
c =============================================================
c argument declaration
integer ie,je,ke
real,intent(OUT) :: ap(ie,je,ke)
real,intent(IN) :: t(ie,je,ke),z(ie,je,ke),sp(ie,je)
real,intent(IN) :: aklev(ke),bklev(ke),aklay(ke),bklay(ke)
c variable declaration
integer i,j,k
real psrf
real,parameter :: rdg=29.271,tzero=273.15
c statement-functions for the computation of pressure
real prlev,prlay
integer is
prlev(is)=aklev(is)+bklev(is)*psrf
prlay(is)=aklay(is)+bklay(is)*psrf
c computation of height of main levels
do i=1,ie
do j=1,je
psrf=sp(i,j)
do k=1,ke-1
ap(i,j,k) = (z(i,j,k) - rdg*(t(i,j,k)+tzero)*
+ alog(prlay(k)/prlev(k)))/1000.
enddo
ap(i,j,ke) = (z(i,j,ke-1) + rdg*(t(i,j,ke)+tzero)*
+ alog(prlev(ke-1)/prlay(ke)))/1000.
enddo
enddo
end
subroutine calc_psred(psr,ps,t,zb,ie,je,ke,aklay,bklay)
c =======================================================
c calculate PSRED given T, ZB and ak,bk
c argument declaration
integer ie,je,ke
real,intent(OUT) :: psr(ie,je)
real,intent(IN) :: ps(ie,je),t(ie,je,ke),zb(ie,je)
real,intent(IN) :: aklay(ke),bklay(ke)
c variable declaration
integer i,j
real psrf
real ztstar,zalpha,zt0
real,parameter :: rdcp=0.286,tzero=273.15,r=287.05,g=9.80665
c statement-functions for the computation of pressure
real prlay
integer is
prlay(is)=aklay(is)+bklay(is)*psrf
do i=1,ie
do j=1,je
psrf=ps(i,j)
if (zb(i,j).lt.1.) then
psr(i,j)=psrf
else
ztstar = (t(i,j,1)+tzero)*(1. + 0.0065*r/g*
& (ps(i,j)/prlay(1) - 1.0))
zalpha = 0.0065*r
zt0 = ztstar + 0.0065*zb(i,j)
if (zt0.gt.290.5) then
if (ztstar.gt.290.5) then
zalpha = 0.0
ztstar = 0.5*(ztstar+290.5)
else
zalpha = r*(290.5-ztstar)/zb(i,j)
endif
else if (ztstar.lt.255.) then
ztstar = 0.5*(255.0+ztstar)
endif
psr(i,j) = ps(i,j)* exp(g*zb(i,j)/(r*ztstar)*
& (1.0 - 0.5*(zalpha*zb(i,j)/(r*ztstar)) +
& 0.333*(zalpha*zb(i,j)/(r*ztstar))**2))
endif
enddo
enddo
end
subroutine calc_blh(blh,ps,t,q,u,v,t2m,td2m,u10m,v10m,
> ie,je,ke,aklay,bklay)
c ======================================================
c calculate BLH with routines from Andi Stohl
c argument declaration
integer ie,je,ke
real,intent(OUT) :: blh(ie,je)
real,intent(IN) :: ps(ie,je),t2m(ie,je),td2m(ie,je),
> u10m(ie,je),v10m(ie,je)
real,intent(IN) :: t(ie,je,ke),q(ie,je,ke),u(ie,je,ke),
> v(ie,je,ke)
real,intent(IN) :: aklay(ke),bklay(ke)
c variable declaration
integer i,j
real psrf
real ztstar,zalpha,zt0
real,parameter :: rdcp=0.286,tzero=273.15,r=287.05,g=9.80665
c statement-functions for the computation of pressure
real prlay
integer is
prlay(is)=aklay(is)+bklay(is)*psrf
do i=1,ie
do j=1,je
call richardson(ps,ust,t(i,j,1),q(i,j,1),u(i,j,1),v(i,j,1),
> ke,aklay,bklay,hf,t2m,td2m,blh(i,j),wst)
enddo
enddo
end
subroutine richardson(psurf,ust,ttlev,qvlev,ulev,vlev,nuvz,
+akz,bkz,hf,tt2,td2,h,wst)
*****************************************************************************
* *
* Calculation of mixing height based on the critical Richardson number. *
* Calculation of convective time scale. *
* For unstable conditions, one iteration is performed. An excess *
* temperature (dependent on hf and wst) is calculated, added to the *
* temperature at the lowest model level. Then the procedure is repeated.*
* *
* Author: A. Stohl *
* *
* 22 August 1996 *
* *
* Literature: *
* Vogelezang DHP and Holtslag AAM (1996): Evaluation and model impacts *
* of alternative boundary-layer height formulations. Boundary-Layer *
* Meteor. 81, 245-269. *
* *
* Update: 1999-02-01 by G. Wotawa *
* *
* Two meter level (temperature, humidity) is taken as reference level *
* instead of first model level. *
* New input variables tt2, td2 introduced. *
* *
*****************************************************************************
* *
* Variables: *
* h mixing height [m] *
* hf sensible heat flux *
* psurf surface pressure at point (xt,yt) [Pa] *
* tv virtual temperature *
* wst convective velocity scale *
* *
* Constants: *
* ric critical Richardson number *
* *
*****************************************************************************
* include 'includepar'
integer i,k,nuvz,itmax,iter
real tv,tvold,zref,z,zold,pint,pold,theta,thetaref,wm,ri,riold
real akz(nuvz),bkz(nuvz),ulev(nuvz),vlev(nuvz),hf,wst,tt2,td2,ew
real psurf,ust,ttlev(nuvz),qvlev(nuvz),h,const,ric,b,excess,bs
real thetaold,zl,ul,vl,thetal,ril
parameter(r_air=287.05,ga=9.81)
parameter(const=r_air/ga,ric=0.25,b=100.,bs=8.5,itmax=3)
excess=0.0
iter=0
C Compute virtual temperature and virtual potential temperature at
C reference level (2 m)
******************************************************************
30 iter=iter+1
pold=psurf
tvold=tt2*(1.+0.378*esat(td2)/psurf)
zold=2.0
zref=zold
thetaref=tvold*(100000./pold)**(r_air/cpa)+excess
riold=0.
C Integrate z up to one level above zt
**************************************
do 10 k=3,nuvz
pint=akz(k)+bkz(k)*psurf ! pressure on model layers
wm=qvlev(k)/(1.-qvlev(k))
tv=ttlev(k)*(1.+0.378*wm/(wm+.622))
if (abs(tv-tvold).gt.0.2) then
z=zold+const*log(pold/pint)*(tv-tvold)/log(tv/tvold)
else
z=zold+const*log(pold/pint)*tv
endif
theta=tv*(100000./pint)**(r_air/cpa)
Calculate Richardson number at each level
*****************************************
ri=ga/thetaref*(theta-thetaref)*(z-zref)/
+ max(((ulev(k)-ulev(2))**2+(vlev(k)-vlev(2))**2+b*ust**2),0.1)
if (ri.gt.ric) goto 20
riold=ri
tvold=tv
pold=pint
thetaold=theta
10 zold=z
20 continue
C Determine Richardson number between the critical levels
*********************************************************
do 15 i=1,20
zl=zold+float(i)/20.*(z-zold)
ul=ulev(k-1)+float(i)/20.*(ulev(k)-ulev(k-1))
vl=vlev(k-1)+float(i)/20.*(vlev(k)-vlev(k-1))
vl=vlev(k-1)+float(i)/20.*(vlev(k)-vlev(k-1))
thetal=thetaold+float(i)/20.*(theta-thetaold)
ril=ga/thetaref*(thetal-thetaref)*(zl-zref)/
+ max(((ul-ulev(2))**2+(vl-vlev(2))**2+b*ust**2),0.1)
if (ril.gt.ric) goto 25
15 continue
25 continue
h=zl
C Calculate convective velocity scale
*************************************
if (hf.lt.0.) then
wst=(-h*ga/thetaref*hf/cpa)**0.333
excess=-bs*hf/cpa/wst
if (iter.lt.itmax) goto 30
else
wst=0.
endif
return
end