!
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE CELTRK ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE celtrk(nx,ny,nz,ibeg,iend,jbeg,jend,kbeg,kend, & 1,5
w, qr, rhobar, x,y,zp, ntrcell, xcw, ycw, &
ireturn, &
ihead,itail,jseg,kcell,icmin,icmax, &
xs,ys,tem1,tem2)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Driver for cell tracking subroutines.
! Part of the ARPS cell tracking subsystem.
!
! AUTHOR: Keith Brewster
! 22 April 1993
!
!-----------------------------------------------------------------------
!
! INPUT VARIABLES
!
! x x coordinate of grid points in physical/comp. space (m)
! y y coordinate of grid points in physical/comp. space (m)
! zp z coordinate of grid points in physical space (m)
!
! w vertical component of velocity in Cartesian
! coordinates (m/s).
!
! qr Rain water mixing ratio (kg/kg)
!
! rhobar Mean density (kg/m^3)
!
! OUTPUT:
!
! Writes tracking information to a file, and returns the following
! variables:
!
! ntrcell Number of cells found at this time
! xcw Weighted central x position of all cells at this time
! ycw Weighted central y position of all cells at this time
!
! ireturn return status
! =0 center of "mass" successfully determined
! =-1 no cells found so center of "mass" only estimated based
! on previous location
!
! WORK ARRAYS:
!
! tem1 Temporary work array.
! tem2 Temporary work array.
!
! (These arrays are defined and used locally (i.e. inside this
! subroutine), they may also be passed into routines called by
! this one. Exiting the call to this subroutine, these temporary
! work arrays may be used for other purposes, and therefore their
! contents may be overwritten. Please examine the usage of work
! arrays before you make any change to the code.)
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
!-----------------------------------------------------------------------
!
! Include files:
!
!-----------------------------------------------------------------------
!
INCLUDE 'globcst.inc'
INCLUDE 'grid.inc' ! Grid parameters
!
!-----------------------------------------------------------------------
!
! Arguments
!
!-----------------------------------------------------------------------
!
INTEGER :: nx,ny,nz
INTEGER :: ibeg,iend,jbeg,jend,kbeg,kend
!
REAL :: x(nx)
REAL :: y(ny)
REAL :: zp(nx,ny,nz)
REAL :: w (nx,ny,nz)
REAL :: qr (nx,ny,nz)
REAL :: rhobar(nx,ny,nz)
!
INTEGER :: ntrcell
REAL :: xcw,ycw
INTEGER :: ireturn
!
!-----------------------------------------------------------------------
!
! Work Arrays
!
!-----------------------------------------------------------------------
!
REAL :: tem1(nx,ny,nz)
REAL :: tem2(nx,ny,nz)
REAL :: xs(nx),ys(ny)
!
!-----------------------------------------------------------------------
!
! Array size parameters.
!
! maxcell: maximum number of cells
! not all may be present at one time
!
! maxtime: number of cell locations over time to save
!
!-----------------------------------------------------------------------
!
INTEGER :: maxcell,maxtime
PARAMETER (maxcell=26, maxtime=15)
!
!-----------------------------------------------------------------------
!
! Important adjustable parameters.
!
! maxhgt: maximum height to look for cells.
! thresh: minimum value of vertical velocity used to define a cell
! eps: small margin of error to allow to pass as meeting threshold
! if thresh is not exactly met
! maxblw: maximum number of points meeting thresh-eps threshold but
! not thresh threshold in a segment
! minlen: minimum length of a segment (meters)
! minarea: minimum area of a horizontal cell (m*m)
! minvol: minimum volume of a 3-d cell (m*m*m)
! minqr: minimum rainwater maximum within a 3-d cell (kg/kg)
! disthr: maximum distance from an extrapolated cell location
! to match with a current cell location (m)
!
!
!-----------------------------------------------------------------------
!
INTEGER :: maxblw
REAL :: thresh,eps,maxhgt,minlen,minqr,minarea,minvol,disthr
PARAMETER (maxhgt=12000., & ! m
thresh=5.0, & ! m/s
eps=0.5, & ! m/s
maxblw=2, & ! grid points
minlen=2000., & ! m
minarea=9.0E06, & ! m*m
minvol=50.0E09, & ! m*m*m
minqr=0.001, & ! kg/kg maximum in cell
disthr=4000.) ! m
!
!
!-----------------------------------------------------------------------
!
! Variables to determine cell location at a given time.
!
!-----------------------------------------------------------------------
!
INTEGER :: ihead(nx*ny),itail(nx*ny),jseg(nx*ny), &
kcell(nx*ny)
REAL :: xcent(maxcell,2)
REAL :: ycent(maxcell,2)
REAL :: zcent(maxcell,2)
REAL :: qrmax(maxcell,2)
REAL :: wgt(maxcell,2)
REAL :: area(maxcell,2)
INTEGER :: icmin(maxcell,ny,2)
INTEGER :: icmax(maxcell,ny,2)
INTEGER :: ncell
!
!-----------------------------------------------------------------------
!
! Location-to-motion variables
!
!-----------------------------------------------------------------------
!
CHARACTER (LEN=1) :: cname(maxcell)
INTEGER :: ktime,ncalls
INTEGER :: nctim(maxtime)
REAL :: alltime(maxtime)
REAL :: xpos(maxtime,maxcell)
REAL :: ypos(maxtime,maxcell)
REAL :: zpos(maxtime,maxcell)
REAL :: xnot(maxcell)
REAL :: ynot(maxcell)
REAL :: allvol(maxtime,maxcell)
REAL :: allwgt(maxtime,maxcell)
REAL :: umotion(maxtime,maxcell)
REAL :: vmotion(maxtime,maxcell)
REAL :: wmotion(maxtime,maxcell)
REAL :: growth(maxtime,maxcell)
!
!-----------------------------------------------------------------------
!
! Save cname and all variables that are a function of time.
!
!-----------------------------------------------------------------------
!
SAVE cname
SAVE ktime,ncalls
SAVE nctim
SAVE alltime,xpos,ypos,zpos,xnot,ynot
SAVE allvol,allwgt,umotion,vmotion,wmotion,growth
!
DATA cname /'A','B','C','D','E','F','G','H','I','J', &
'K','L','M','N','O','P','Q','R','S','T', &
'U','V','W','X','Y','Z'/
DATA ktime,ncalls /0,0/
!
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
REAL :: prtmis
PARAMETER (prtmis= 999.)
CHARACTER (LEN=1) :: comma
PARAMETER (comma=',')
REAL :: wgtsum,xsum,ysum
INTEGER :: maxseg
INTEGER :: istr,ifin,jstr,jfin,kstr,kfin
INTEGER :: i,j,kc,mtime,mpast
!
CHARACTER (LEN=80 ) :: trkfn ! Name of max./min. file
INTEGER :: ltrkfn
INTEGER :: istat, nchtrk
SAVE nchtrk
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
maxseg = nx*ny
IF( ((nx*nz)/2) < maxcell) THEN
WRITE(6,'(1x,a,/1x,a,I4,a,/1x,a)') &
'The size of temporary arrays passed to CELTRK not big enough& !', &
'(nx*nz)/2 must be greater than ',maxcell, &
' for CELTRK to work properly.', &
' No cell tracking was done.'
RETURN
END IF
IF(ncalls == 0) THEN
ncalls=1
trkfn = runname(1:lfnkey)//'.track'
ltrkfn = lfnkey + 6
CALL getunit
(nchtrk)
WRITE(6,'(1x,a,a,a/,1x,a)') &
'Check to see if file ',trkfn(1:ltrkfn),' already exists.', &
'If so, append a version number to the filename.'
CALL fnversn
( trkfn, ltrkfn )
OPEN(nchtrk,FORM='formatted',STATUS='new', &
FILE=trkfn(1:ltrkfn),IOSTAT=istat)
IF( istat /= 0) THEN
WRITE(6,'(/a,i2,/a/)') &
' Error occured when opening file '//trkfn(1:ltrkfn)// &
' using FORTRAN unit ',nchtrk,' Program stopped in trkdriv.'
CALL arpsstop ("arpstop called from celtrk",1)
END IF
WRITE(nchtrk,'(a)') ''''//runname//''''
WRITE(nchtrk,'(/a,a)') &
' time name xloc yloc zloc', &
' u v w vol wgt '
END IF
!
!-----------------------------------------------------------------------
!
! Check the limits that were passed in.
! For bookkeeping reasons (avoid array out of bounds and some
! storage tricks), as well as physical sense, the range of i,j,k
! should not involve the artificial boundary points.
!
! Use istr,ifin,jstr,jfin,kstr,kfin in place of ibeg,iend, etc.
! for the call to loccell.
!
!-----------------------------------------------------------------------
!
istr=MAX(ibeg,2)
ifin=MIN(iend,nx-1)
jstr=MAX(jbeg,2)
jfin=MIN(jend,ny-1)
kstr=MAX(kbeg,2)
kfin=MIN(kend,nz-1)
!
!-----------------------------------------------------------------------
!
! Locate cells in grid.
!
!-----------------------------------------------------------------------
!
DO i=1,nx-1
xs(i)=(x(i)+x(i+1))*0.5
END DO
xs(nx)=2.*xs(nx-1)-xs(nx-2)
DO j=1,ny-1
ys(j)=(y(j)+y(j+1))*0.5
END DO
ys(ny)=2.*ys(ny-1)-ys(ny-2)
CALL loccell
(nx,ny,nz, maxseg,maxcell,ncell, &
istr,ifin,jstr,jfin,kstr,kfin, &
w,qr, rhobar, xs,ys,zp, &
ihead,itail,kcell,jseg, &
xcent,ycent,zcent,icmin,icmax, &
qrmax,area,wgt,maxhgt, &
thresh,eps,maxblw,minlen,minqr,minarea,minvol, &
ireturn, tem1,tem2)
!
!-----------------------------------------------------------------------
!
! Add movement of grid to the cell locations.
! Compute a weighted mean location of all cells at this time.
!
!-----------------------------------------------------------------------
!
xsum=0.
ysum=0.
wgtsum=0.
DO kc=1,ncell
xcent(kc,1)=xcent(kc,1)+xgrdorg
ycent(kc,1)=ycent(kc,1)+ygrdorg
wgtsum=wgtsum+wgt(kc,1)
xsum=xsum+xcent(kc,1)*wgt(kc,1)
ysum=ysum+ycent(kc,1)*wgt(kc,1)
END DO
!
ntrcell=ncell
!
IF(wgtsum > 0.) THEN
ireturn=0
xcw=xsum/wgtsum
ycw=ysum/wgtsum
ELSE
ireturn=-1
IF( ktime > 1) THEN
xcw=xcw+umove*tceltrk
ycw=ycw+vmove*tceltrk
ELSE
xcw=(xs(1)+xs(nx))*0.5
ycw=(ys(1)+ys(ny))*0.5
END IF
END IF
!
!-----------------------------------------------------------------------
!
! Spit out some diagnostics to the list file.
!
!-----------------------------------------------------------------------
!
WRITE(6,'(//a,i4,/a,a)') &
' Cell positions for whole vol Total cells: ',ncell, &
' kc xcabs ycabs xcrel ycrel ', &
' zcent vol wgt qrmax'
DO kc=1,ncell
WRITE(6,'(1x,i4,2(F9.2,F9.2),F9.2,F9.0,F12.0)') &
kc,(xcent(kc,1)*0.001),(ycent(kc,1)*0.001) &
,((xcent(kc,1)-xgrdorg)*0.001) &
,((ycent(kc,1)-ygrdorg)*0.001) &
,(zcent(kc,1)*0.001) &
,( area(kc,1)*1.0E-09),wgt(kc,1) &
,(qrmax(kc,1)*1000.)
END DO
!
!-----------------------------------------------------------------------
!
! Match current cell volumes with previous.
!
!-----------------------------------------------------------------------
!
! print *, ' Calling matctim'
CALL matctim
(maxcell,maxtime,ktime,mtime,mpast, &
disthr,curtim,umove,vmove, &
ncell,xcent(1,1),ycent(1,1),zcent(1,1), &
area(1,1),wgt(1,1), &
cname,nctim,alltime, &
xpos,ypos,zpos,xnot,ynot, &
allvol,allwgt, &
umotion,vmotion,wmotion)
WRITE(6,'(//a,i4,/a)') &
' Cells combined in time arrays: ',nctim(mtime), &
' jc xpos ypos zpos volume wgt'
DO kc=1,nctim(mtime)
IF(xpos(mtime,kc) > -1.e30) THEN
WRITE(6,'(3x,a1,F9.2,F9.2,F9.2,F9.0,F12.0)') &
cname(kc),(xpos(mtime,kc)*0.001), &
(ypos(mtime,kc)*0.001), &
(zpos(mtime,kc)*0.001), &
(allvol(mtime,kc)*1.0E-09), &
allwgt(mtime,kc)
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Calculate cell motion vector and growth rate.
!
!-----------------------------------------------------------------------
!
CALL getvec
(maxcell,maxtime,ktime,mtime, &
cname,nctim,alltime, &
xpos,ypos,zpos,xnot,ynot, &
allvol,allwgt, &
umotion,vmotion,wmotion,growth)
!
!-----------------------------------------------------------------------
!
! Spit out motion vector results.
!
!-----------------------------------------------------------------------
!
IF(nctim(mtime) > 0) THEN
DO kc=1,nctim(mtime)
IF(xpos(mtime,kc) > -1.0E30) THEN
IF(umotion(mtime,kc) > -1.0E30) THEN
WRITE(nchtrk,'(1x,F7.0,2x,a1,1x,f7.2, &
& f7.2,f7.2,f7.2,f7.2,f7.2,f7.0,f10.0)') &
alltime(mtime),cname(kc), &
(xpos(mtime,kc)*0.001), &
(ypos(mtime,kc)*0.001), &
(zpos(mtime,kc)*0.001), &
umotion(mtime,kc), &
vmotion(mtime,kc), &
wmotion(mtime,kc), &
(allvol(mtime,kc)*1.0E-09), &
allwgt(mtime,kc)
ELSE
WRITE(nchtrk,'(1x,F7.0,2x,a1,1x, &
& f7.2,f7.2,f7.2,f7.2,f7.2,f7.2,f7.0,f10.0)') &
alltime(mtime),cname(kc), &
(xpos(mtime,kc)*0.001), &
(ypos(mtime,kc)*0.001), &
(zpos(mtime,kc)*0.001), &
prtmis, &
prtmis, &
prtmis, &
(allvol(mtime,kc)*1.0E-09), &
allwgt(mtime,kc)
END IF
END IF
END DO
END IF
WRITE(6,'(/a,i8,f9.0,f9.0//)') ' End of tracking for time:', &
mtime,alltime(mtime),curtim
RETURN
END SUBROUTINE celtrk
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE LOCCELL ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE loccell(nx,ny,nz, maxseg,maxcell,ncell, & 1,11
ibeg,iend,jbeg,jend,kbeg,kend, &
tvar,qr,rhobar,x,y,zp, &
ihead,itail,kcell,jseg, &
xcent,ycent,zcent,icmin,icmax, &
qrmax,area,wgt,maxhgt, &
thresh,eps,maxblw,minlen,minqr,minarea,minvol, &
ireturn, tem1,tem2)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Builds cells from tracking variable (tvar, i.e. w) field and
! establishes a central postion for each which is used for
! storm tracking.
!
! A module of the ARPS cell tracking subsystem.
!
! AUTHOR: Keith Brewster
! 21 Mar 1993
!
!-----------------------------------------------------------------------
!
! DATA ARRAYS:
!
! x x coordinate of grid points in physical/comp. space (m)
! y y coordinate of grid points in physical/comp. space (m)
! zp z coordinate of grid points in physical space (m)
!
! w z component of velocity (m/s)
!
! qr Rainwater mixing ratio (kg/kg)
!
! rhobar Mean density (kg/m^3)
!
! WORK ARRAYS:
!
! tem1 Temporary work array.
! tem2 Temporary work array.
!
! (These arrays are defined and used locally (i.e. inside this
! subroutine), they may also be passed into routines called by
! this one. Exiting the call to this subroutine, these temporary
! work arrays may be used for other purposes, and therefore their
! contents may be overwritten. Please examine the usage of work
! arrays before you make any change to the code.)
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: nx,ny,nz
INTEGER :: maxseg
INTEGER :: maxcell
INTEGER :: ncell
INTEGER :: ibeg,iend,jbeg,jend,kbeg,kend
REAL :: x(nx)
REAL :: y(ny)
REAL :: zp(nx,ny,nz)
REAL :: tvar(nx,ny,nz)
REAL :: qr(nx,ny,nz)
REAL :: rhobar(nx,ny,nz)
REAL :: thresh
INTEGER :: ihead(maxseg)
INTEGER :: itail(maxseg)
INTEGER :: jseg(maxseg)
INTEGER :: kcell(maxseg)
REAL :: xcent(maxcell,2)
REAL :: ycent(maxcell,2)
REAL :: zcent(maxcell,2)
REAL :: wgt(maxcell,2)
REAL :: qrmax(maxcell,2)
REAL :: area(maxcell,2)
INTEGER :: icmin(maxcell,ny,2)
INTEGER :: icmax(maxcell,ny,2)
INTEGER :: maxblw
REAL :: eps,maxhgt,minlen,minqr,minarea,minvol
REAL :: tem1(nx,ny,nz)
REAL :: tem2(nx,ny,nz)
INTEGER :: ireturn
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: nseg,onvf
INTEGER :: i,j,k,kc,ncellk
REAL :: tmin,tmax
INTEGER :: ilmax,jlmax,klmax,ilmin,jlmin,klmin
INTEGER :: icengd,jcengd,iseg,ihd,itl,kntblw
REAL :: xlen,thmin,zsfc
LOGICAL :: onseg
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
! Average qr in the vertical to get qr at w points.
! This is stored in tem1.
!
!-----------------------------------------------------------------------
!
onvf=1
CALL avgz
(qr, onvf, nx,ny,nz, &
1,nx-1,1,ny-1,2,nz-1, tem1)
!
!-----------------------------------------------------------------------
!
! Average rhobar in the vertical to get rhobar at w points.
! This is stored in tem2.
!
!-----------------------------------------------------------------------
!
onvf=1
CALL avgz
(rhobar, onvf, nx,ny,nz, &
1,nx-1,1,ny-1,2,nz-1, tem2)
!
!-----------------------------------------------------------------------
!
! Find the w max and report it.
! For now this information is only used for diagnostics,
! but in the future the cell matching could begin at the level
! of max w and work up and down from there.
! For now, it begins at the top and works down.
!
!-----------------------------------------------------------------------
!
CALL a3dmax
(tvar, 1,nx,ibeg,iend, 1,ny,jbeg,jend, &
1,nz,kbeg,kend, tmax,tmin, &
ilmax,jlmax,klmax,ilmin,jlmin,klmin)
PRINT *, ' w max = ',tmax
! print *, ' imax,jmax,kmax = ',ilmax,jlmax,klmax
! print *, ' thresh= ',thresh
! print *, ' minlen= ',minlen
!
!-----------------------------------------------------------------------
!
! Search for segments, strings of points meeting the threshold.
! The variable onseg is a flag indicating whether we are on a
! segment looking for its end (onseg=true) or looking for the
! beginning of the next segment (onseg=false).
!
! When the end of a segment is reached matchsg is called which
! matches the current segment to any previously found segments
! on this level.
!
! Variables ihead and itail describe the beginning and end of
! the each segment.
!
! At the end of each level, matchsg is called in reverse
! order to see if any further matching of cells can be made
! (since the matching process can be directional dependent).
! In the following example segments A and B would not be matched
! to each other going from 1-to-3 but on the reverse matching
! (3-to-1) B would be matched to C which had originally been
! matched to A.
!
! 3 DDDD EEEE
! 2 CCCCCCCCCCCCC
! 1 AAA BBBB
!
!-----------------------------------------------------------------------
!
icengd=((nx-3)/2) + 1
jcengd=((ny-3)/2) + 1
zsfc=0.5*(zp(icengd,jcengd,1)+zp(icengd,jcengd,2))
thmin=thresh-eps
ncell=0
DO k=kend,kbeg,-1
! print *, ' k = ',k
IF((zp(icengd,jcengd,k)-zsfc) <= maxhgt) THEN
nseg=0
ncellk=0
IF(tmax > thresh) THEN
DO j=jbeg,jend
onseg=.false.
DO i=ibeg,iend
IF(onseg) THEN
IF(tvar(i,j,k) < thresh) THEN
kntblw=kntblw+1
IF(tvar(i,j,k) >= thmin) THEN
IF(kntblw > maxblw) THEN
itl=(i-kntblw)
xlen=ABS( IF(xlen >= minlen) THEN
IF(nseg < maxseg) THEN
nseg=nseg+1
ihead(nseg)=ihd
itail(nseg)=itl
jseg(nseg)=j
kcell(nseg)=-99
CALL matchsg
(maxseg,maxcell, &
nseg, 1,(nseg-1),1,ihd,itl,j, &
ihead,itail,jseg,kcell,ncellk)
END IF
END IF
onseg=.false.
END IF
ELSE ! LT.thresh and LT.thmin
itl=(i-kntblw)
xlen=ABS( IF(xlen >= minlen) THEN
IF(nseg < maxseg) THEN
nseg=nseg+1
ihead(nseg)=ihd
itail(nseg)=itl
jseg(nseg)=j
kcell(nseg)=-99
CALL matchsg
(maxseg,maxcell, &
nseg, 1,(nseg-1),1,ihd,itl,j, &
ihead,itail,jseg,kcell,ncellk)
END IF
END IF
onseg=.false.
END IF
!
!-----------------------------------------------------------------------
!
! Onseg and tvar is greater than thresh
! Reset kntblw to zero,
! then resume search for the end of the segment.
!
!-----------------------------------------------------------------------
!
ELSE
kntblw=0
END IF
!
!-----------------------------------------------------------------------
!
! Not "onseg"
! See if the threshold is exceeded, if so, initialize
! segment pointers, ihd and kntblw, and set onseg to true.
!
!-----------------------------------------------------------------------
!
ELSE
IF(tvar(i,j,k) >= thresh) THEN
ihd=i
kntblw=0
onseg=.true.
END IF
END IF
END DO
!
!-----------------------------------------------------------------------
!
! If you've reached the end of the i indices and your are
! still "onseg", then close this segment.
!
!-----------------------------------------------------------------------
!
IF(onseg) THEN
itl=iend-kntblw
xlen=ABS( IF(xlen >= minlen) THEN
IF(nseg < maxseg) THEN
nseg=nseg+1
ihead(nseg)=ihd
itail(nseg)=itl
jseg(nseg)=j
kcell(nseg)=-99
CALL matchsg
(maxseg,maxcell, &
nseg, 1,(nseg-1),1,ihd,itl,j, &
ihead,itail,jseg,kcell,ncellk)
END IF
END IF
onseg=.false.
END IF
END DO
END IF ! tmax .gt. thresh
!
!-----------------------------------------------------------------------
!
! Do backwards matching of segments
!
!-----------------------------------------------------------------------
!
! print *, ' before backward matching ncellk = ',ncellk
DO iseg=(nseg-1),1,-1
CALL matchsg
(maxseg,maxcell,iseg, nseg,(iseg+1),-1, &
ihead(iseg),itail(iseg),jseg(iseg), &
ihead,itail,jseg,kcell,ncellk)
END DO
! print *, ' after backward matching ncell = ',ncellk
!
!-----------------------------------------------------------------------
!
! Calculate cell areas and centroids.
!
!-----------------------------------------------------------------------
!
IF(ncellk > 0) THEN
CALL ctrwgt
(nx,ny,maxseg,maxcell,nseg,ncellk, &
tvar(1,1,k),tem1(1,1,k),tem2(1,1,k), &
x,y,zp(1,1,k), &
ihead,itail,jseg,kcell, &
xcent(1,2),ycent(1,2),zcent(1,2), &
qrmax(1,2),area(1,2),wgt(1,2))
!
!-----------------------------------------------------------------------
!
! Create array describing min and max of i for each j column
! in each cell.
!
! This is required for efficient vertical matching of horizontal
! cells to create 3d cells.
!
!-----------------------------------------------------------------------
!
DO j=1,ny
DO kc=1,maxcell
icmin(kc,j,2)=nx+1
icmax(kc,j,2)=-99
END DO
END DO
DO iseg=1,nseg
kc=kcell(iseg)
icmin(kc,jseg(iseg),2)= &
MIN(icmin(kc,jseg(iseg),2),ihead(iseg))
icmax(kc,jseg(iseg),2)= &
MAX(icmax(kc,jseg(iseg),2),itail(iseg))
END DO
!
!-----------------------------------------------------------------------
!
! Clean up cell list, eliminate those with small area.
! Or those not meeting the minimum rainwater (qr) requirement.
!
!-----------------------------------------------------------------------
!
! print *, ' inside loccell minqr,minarea= ',minqr,minarea
! print *, ' Before sieve2d, ncell= ',ncellk
CALL sieve2d
(maxcell,ny,ncellk, &
xcent(1,2),ycent(1,2),zcent(1,2), &
qrmax(1,2),area(1,2),wgt(1,2), &
icmin(1,1,2),icmax(1,1,2), &
minarea)
! print *, ' After sieving, ncell= ',ncellk
!
! tell us about icmin and icmax
! do 256 kc=1,ncellk
! print *, ' k, kc = ',k,kc
! do 255 j=1,ny
! print *,' j= ',j,' imin= ',icmin(kc,j,2),
! : ' imax= ',icmax(kc,j,2)
!255 continue
!256 continue
END IF
!
! IF( ncellk.gt.0 ) THEN
! write(6,'(//a,i4,a,i4,/a)')
! : ' Cells on level: ',k,' Total cells: ',ncellk,
! : ' kc xcent ycent zcent area wgt'
! DO 300 kc=1,ncellk
! write(6,'(1x,i4,F9.2,F9.2,F9.2,F9.0,F12.0)')
! : kc,xcent(kc,2),ycent(kc,2),zcent(kc,2),area(kc,2),wgt(kc,2)
!00 CONTINUE
! END IF
!
!-----------------------------------------------------------------------
!
! Combine cells with cells found at previous levels.
! The combined cell info is put in the level one index.
!
!-----------------------------------------------------------------------
!
CALL linkcell
(maxcell,nx,ny,nz,k,ncell,ncellk, &
x,y,zp,xcent,ycent,zcent,icmin,icmax, &
qrmax,area,wgt)
END IF ! below maxhgt?
END DO
!
!-----------------------------------------------------------------------
!
! Compute the central x,y,z
! for each cell volume from the info collected on plane 1.
!
!-----------------------------------------------------------------------
!
DO kc=1,ncell
IF(wgt(kc,1) /= 0.0) THEN
xcent(kc,1)=xcent(kc,1)/wgt(kc,1)
ycent(kc,1)=ycent(kc,1)/wgt(kc,1)
zcent(kc,1)=zcent(kc,1)/wgt(kc,1)
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Eliminate cells which are too small.
!
!-----------------------------------------------------------------------
PRINT *, ' before sieve3d, ncell= ',ncell
CALL sieve3d
(maxcell,ncell, &
xcent(1,1),ycent(1,1),zcent(1,1), &
qrmax(1,1),area(1,1),wgt(1,1), &
minqr,minvol)
PRINT *, ' after sieve3d, ncell= ',ncell
!
RETURN
END SUBROUTINE loccell
!
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE MATCHSG ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE matchsg(maxseg,maxcell, & 4
kseg, mbeg,mend,mdir,ihd,itl,j, &
ihead,itail,jseg,kcell,ncell)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Matches line segments to form horizontal cells.
! A module of the ARPS cell tracking subsystem.
!
! AUTHOR: Keith Brewster
! 21 Mar 1993
!
!-----------------------------------------------------------------------
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: maxseg,maxcell,kseg
INTEGER :: ihd,itl,j
INTEGER :: mbeg,mend,mdir
INTEGER :: ihead(maxseg),itail(maxseg),jseg(maxseg), &
kcell(maxseg)
INTEGER :: ncell
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: mseg
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
! Form cells from line segments
!
!-----------------------------------------------------------------------
!
DO mseg=mbeg,mend,mdir
IF(ABS(jseg(mseg)-j) == 1) THEN
IF(ihd >= ihead(mseg) .AND. ihd <= itail(mseg)) GO TO 120
IF(itl >= ihead(mseg) .AND. itl <= itail(mseg)) GO TO 120
IF(itl >= itail(mseg) .AND. ihd <= ihead(mseg)) GO TO 120
END IF
END DO
!
!-----------------------------------------------------------------------
!
! No cell found so this may be a new one.
!
!-----------------------------------------------------------------------
!
IF(kcell(kseg) < 0) THEN
IF(ncell < maxcell) THEN
ncell=ncell+1
kcell(kseg)=ncell
! print *, ' kseg j,ihd,itl: ',kseg,j,ihd,itl
! print *, ' new cell: ',ncell,kcell(kseg)
ELSE
PRINT *, ' WARNING: ran out of space for cells.'
END IF
END IF
RETURN
!
!-----------------------------------------------------------------------
!
! Cell found, it belongs with kcell(mseg)
!
!-----------------------------------------------------------------------
!
120 CONTINUE
IF(kcell(mseg) > 0) THEN
kcell(kseg)=kcell(mseg)
ELSE
IF(ncell < maxcell) THEN
ncell=ncell+1
kcell(kseg)=ncell
kcell(mseg)=ncell
END IF
END IF
! print *, ' kseg j,ihd,itl: ',kseg,j,ihd,itl
! print *, ' matched with cell: ',kcell(mseg),j,
! : ihead(kcell(mseg)),itail(kcell(mseg))
RETURN
END SUBROUTINE matchsg
!
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE CTRWGT ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE ctrwgt(nx,ny,maxseg,maxcell,nseg,ncell, & 1
tvar,qratw,rhoatw,x,y,zp, &
ihead,itail,jseg,kcell, &
xcent,ycent,zcent,qrmax,area,wgt)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Compute a central location for all cells formed by matchsg.
! A module of the ARPS cell tracking subsystem.
!
! AUTHOR: Keith Brewster
! 21 Mar 1993
!
!-----------------------------------------------------------------------
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: nx,ny
INTEGER :: maxseg
INTEGER :: maxcell
REAL :: tvar(nx,ny)
REAL :: qratw(nx,ny)
REAL :: rhoatw(nx,ny)
REAL :: x(nx)
REAL :: y(ny)
REAL :: zp(nx,ny)
INTEGER :: ihead(maxseg)
INTEGER :: itail(maxseg)
INTEGER :: jseg(maxseg)
INTEGER :: kcell(maxseg)
REAL :: xcent(maxcell)
REAL :: ycent(maxcell)
REAL :: zcent(maxcell)
REAL :: qrmax(maxcell)
REAL :: area(maxcell)
REAL :: wgt(maxcell)
INTEGER :: nseg
INTEGER :: ncell
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
REAL :: ddx,ddy,ddxy,wayt
INTEGER :: i,j,m,kc
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
ddx=x(2)-x(1)
ddy=y(2)-y(1)
ddxy=ABS(ddx*ddy)
!
!-----------------------------------------------------------------------
!
! Initializations.
!
!-----------------------------------------------------------------------
!
DO kc=1,ncell
wgt(kc)=0.
qrmax(kc)=-999.
area(kc)=0.
xcent(kc)=0.
ycent(kc)=0.
zcent(kc)=0.
END DO
!
!-----------------------------------------------------------------------
!
! Go through all segments. Build sums for each cell.
!
!-----------------------------------------------------------------------
!
DO m=1,nseg
IF(kcell(m) > 0) THEN
j=jseg(m)
kc=kcell(m)
DO i=ihead(m),itail(m)
wayt=rhoatw(i,j)*tvar(i,j)*tvar(i,j)
! wayt=tvar(i,j)*tvar(i,j)
wgt(kc)=wgt(kc)+wayt
xcent(kc)=xcent(kc)+wayt*x(i)
ycent(kc)=ycent(kc)+wayt*y(j)
zcent(kc)=zcent(kc)+wayt*zp(i,j)
qrmax(kc)=AMAX1(qrmax(kc),qratw(i,j))
area(kc)=area(kc)+ddxy
END DO
ELSE
PRINT *, ' Warning: segment ',m,' not assigned to a cell'
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Calculated cell centroid, a weight average of the locations
! of all the grid points in the cell.
!
!-----------------------------------------------------------------------
!
DO kc=1,ncell
IF(wgt(kc) > 0.) THEN
xcent(kc)=xcent(kc)/wgt(kc)
ycent(kc)=ycent(kc)/wgt(kc)
zcent(kc)=zcent(kc)/wgt(kc)
END IF
END DO
!
RETURN
END SUBROUTINE ctrwgt
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE SIEVE2D ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE sieve2d(maxcell,ny,ncell, & 1
xcent,ycent,zcent,qrmax,area,wgt, &
icmin,icmax, &
minarea)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Discard cells less than a given areal size.
! A module of the ARPS cell tracking subsystem.
!
! AUTHOR: Keith Brewster
! 21 Mar 1993
!
!-----------------------------------------------------------------------
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: maxcell,ny,ncell
REAL :: xcent(maxcell)
REAL :: ycent(maxcell)
REAL :: zcent(maxcell)
REAL :: qrmax(maxcell)
REAL :: area(maxcell)
REAL :: wgt(maxcell)
INTEGER :: icmin(maxcell,ny)
INTEGER :: icmax(maxcell,ny)
REAL :: minarea
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: ic,j,kc,nn
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
nn=ncell
DO ic=1,ncell
20 CONTINUE
IF(ic > nn) EXIT
! print *, ' ic area, qrmax= ',ic,area(ic),qrmax(ic)
IF(area(ic) < minarea) THEN
nn=nn-1
DO kc=ic,nn
wgt(kc)=wgt(kc+1)
area(kc)=area(kc+1)
qrmax(kc)=qrmax(kc+1)
xcent(kc)=xcent(kc+1)
ycent(kc)=ycent(kc+1)
zcent(kc)=zcent(kc+1)
END DO
DO j=1,ny
DO kc=ic,nn
icmin(kc,j)=icmin(kc+1,j)
icmax(kc,j)=icmax(kc+1,j)
END DO
END DO
GO TO 20
END IF
END DO
ncell=nn
RETURN
END SUBROUTINE sieve2d
!
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE SIEVE3D ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE sieve3d(maxcell,ncell, & 1
xcent,ycent,zcent,qrmax,area,wgt, &
minqr,minvol)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Discard 3-dimensional cells less than a given volume size.
! A module of the ARPS cell tracking subsystem.
!
! AUTHOR: Keith Brewster
! 21 Mar 1993
!
!-----------------------------------------------------------------------
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: maxcell
INTEGER :: ncell
REAL :: xcent(maxcell)
REAL :: ycent(maxcell)
REAL :: zcent(maxcell)
REAL :: qrmax(maxcell)
REAL :: area(maxcell)
REAL :: wgt(maxcell)
REAL :: minqr,minvol
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: ic,kc,nn
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
nn=ncell
DO ic=1,ncell
20 CONTINUE
IF(ic > nn) EXIT
IF(area(ic) < minvol .OR. qrmax(ic) < minqr) THEN
nn=nn-1
DO kc=ic,nn
wgt(kc)=wgt(kc+1)
area(kc)=area(kc+1)
qrmax(kc)=qrmax(kc+1)
xcent(kc)=xcent(kc+1)
ycent(kc)=ycent(kc+1)
zcent(kc)=zcent(kc+1)
END DO
GO TO 20
END IF
END DO
ncell=nn
RETURN
END SUBROUTINE sieve3d
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE LINKCELL ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE linkcell(maxcell,nx,ny,nz,k,ncell,ncellk, & 1
x,y,zp,xcent,ycent,zcent,icmin,icmax, &
qrmax,area,wgt)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Link cells on adjacent horizontal surfaces to form 3-d cell.
! Combine location info to get 3D location info.
! A module of the ARPS cell tracking subsystem.
!
! AUTHOR: Keith Brewster
! 21 Mar 1993
!
!-----------------------------------------------------------------------
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: maxcell,nx,ny,nz
INTEGER :: k,ncell,ncellk
REAL :: x(nx)
REAL :: y(ny)
REAL :: zp(nx,ny,nz)
REAL :: xcent(maxcell,2)
REAL :: ycent(maxcell,2)
REAL :: zcent(maxcell,2)
REAL :: wgt(maxcell,2)
REAL :: qrmax(maxcell,2)
REAL :: area(maxcell,2)
INTEGER :: icmin(maxcell,ny,2)
INTEGER :: icmax(maxcell,ny,2)
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: ic,jc,j,iloc,jloc
REAL :: dx,dy
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! NOTE:
! 3-d info is in 3rd index=1,
! 2-d info for a single level is in 3rd index=2.
!
! Find a cell that has an overlap with this cell.
! For this nested loop, 2 is the plane being checked
! 1 is the plane being searched for possible matches
! ic is the cell being checked
! jc is the cell being compared on plane 1 (3-d info)
!
!-----------------------------------------------------------------------
!
dx=x(2)-x(1)
dy=y(2)-y(1)
DO ic=1,ncellk
DO jc=1,ncell
!
!-----------------------------------------------------------------------
!
! Check for overlap between these two cells
!
!-----------------------------------------------------------------------
!
DO j=1,ny
IF(icmax(ic,j,2) > 0 .AND. icmax(jc,j,1) > 0) THEN
IF((icmax(ic,j,2) >= icmin(jc,j,1)) .AND. &
(icmin(ic,j,2) <= icmax(jc,j,1))) &
GO TO 250
END IF
END DO
END DO
!
!-----------------------------------------------------------------------
!
! No match found, must be a new cell
!
!-----------------------------------------------------------------------
!
ncell=ncell+1
jc=ncell
!
wgt(jc,1)=wgt(ic,2)
xcent(jc,1)=wgt(ic,2)*xcent(ic,2)
ycent(jc,1)=wgt(ic,2)*ycent(ic,2)
zcent(jc,1)=wgt(ic,2)*zcent(ic,2)
qrmax(jc,1)=qrmax(ic,2)
iloc=nint((xcent(ic,2)/dx) + 1.5)
jloc=nint((ycent(ic,2)/dy) + 1.5)
area(jc,1)=area(ic,2)* &
0.5*(zp(iloc,jloc,k+1)-zp(iloc,jloc,k-1))
!
!-----------------------------------------------------------------------
!
! Set icmin, icmax
!
! 1 index is added to the max and 1 index is subtracted from
! the min so that the comparisons in do loop 180 accept cells
! that touch rather than just overlap. Adding now saves time
! of adding inside the IF statement.
!
!-----------------------------------------------------------------------
!
DO j=1,ny
icmin(jc,j,1)=icmin(ic,j,2)-1
icmax(jc,j,1)=icmax(ic,j,2)+1
END DO
!
CYCLE
!
!-----------------------------------------------------------------------
!
! Match found.
! Update weighted sums
!
!-----------------------------------------------------------------------
!
250 CONTINUE
wgt(jc,1)=wgt(jc,1)+wgt(ic,2)
xcent(jc,1)=xcent(jc,1)+wgt(ic,2)*xcent(ic,2)
ycent(jc,1)=ycent(jc,1)+wgt(ic,2)*ycent(ic,2)
zcent(jc,1)=zcent(jc,1)+wgt(ic,2)*zcent(ic,2)
qrmax(jc,1)=AMAX1(qrmax(jc,1),qrmax(ic,2))
iloc=nint((xcent(ic,2)/dx) + 1.5)
jloc=nint((ycent(ic,2)/dy) + 1.5)
area(jc,1)=area(jc,1)+area(ic,2)* &
0.5*(zp(iloc,jloc,k+1)-zp(iloc,jloc,k-1))
!
!-----------------------------------------------------------------------
!
! Match found.
! Update icmin,icmax
!
!-----------------------------------------------------------------------
!
DO j=1,ny
icmin(jc,j,1)=MIN(icmin(jc,j,1),(icmin(ic,j,2)-1))
icmax(jc,j,1)=MAX(icmax(jc,j,1),(icmax(ic,j,2)+1))
END DO
END DO
!
RETURN
END SUBROUTINE linkcell
!
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE MATCTIM ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE matctim(maxcell,maxtime,ktime,mtime,mpast, & 1
disthr,time,umove,vmove, &
ncell,xcent,ycent,zcent, &
area,wgt, &
cname,nctim,alltime, &
xpos,ypos,zpos,xnot,ynot, &
allvol,allwgt, &
umotion,vmotion,wmotion)
!
IMPLICIT NONE
INTEGER :: maxcell,maxtime,ktime,mtime
REAL :: time,disthr,umove,vmove
INTEGER :: ncell
REAL :: xcent(maxcell),ycent(maxcell),zcent(maxcell), &
wgt(maxcell),area(maxcell)
CHARACTER (LEN=2) :: cname(maxcell)
INTEGER :: nctim(maxtime)
REAL :: alltime(maxtime)
REAL :: xpos(maxtime,maxcell),ypos(maxtime,maxcell), &
zpos(maxtime,maxcell)
REAL :: xnot(maxcell),ynot(maxcell)
REAL :: allvol(maxtime,maxcell),allwgt(maxtime,maxcell)
REAL :: umotion(maxtime,maxcell),vmotion(maxtime,maxcell), &
wmotion(maxtime,maxcell)
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: icell,jcell,inear,mpast
REAL :: xxtrap,yxtrap
REAL :: d2thr,deltat,ddx,ddy,dist2,distmin,d2rat,drmin
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!-----------------------------------------------------------------------
!
! Index control: ktime is count of times processed here
! mtime is current index in arrays saving locations
! mpast is past index in arrays saving locations
!
!-----------------------------------------------------------------------
!
ktime=ktime+1
mtime=MOD(ktime,maxtime)
IF(mtime == 0) mtime=maxtime
mpast=MOD((ktime-1),maxtime)
IF(mpast == 0) mpast=maxtime
PRINT *, ' inside matctim '
PRINT *, ' ncell,ktime,mtime = ',ncell,ktime,mtime
PRINT *, ' mpast,nctim(mpast)= ',mpast,nctim(mpast)
!
d2thr=disthr*disthr
alltime(mtime)=time
!
DO icell=1,maxcell
nctim(mtime)=0
xpos(mtime,icell)=-1.0E30
ypos(mtime,icell)=-1.0E30
zpos(mtime,icell)=-1.0E30
allvol(mtime,icell)=-1.0E30
allwgt(mtime,icell)=-1.0E30
umotion(mtime,icell)=-1.0E30
vmotion(mtime,icell)=-1.0E30
wmotion(mtime,icell)=-1.0E30
END DO
!
IF(ktime == 1) THEN
nctim(mtime)=ncell
DO icell=1,ncell
xpos(mtime,icell)=xcent(icell)
ypos(mtime,icell)=ycent(icell)
zpos(mtime,icell)=zcent(icell)
allvol(mtime,icell)=area(icell)
allwgt(mtime,icell)=wgt(icell)
END DO
ELSE ! not first time, need to match up with past cells
!
!-----------------------------------------------------------------------
!
! Try to match location of "current" cells with extrapolated
! positions of past cells. It is assumed throughout that we are
! dealing with absolute (not grid relative locations). This
! is necessary for the linear fit to work right under the condition
! that the grid motion (umove,vmove) are changing with time.
!
!
! For extrapolation use, (in the following order of priority,
! according to the available data for each cell):
!
! 1) Least-squares line from previous u,v fitting
! (umotion,vmotion and xnot,ynot)
!
! 2) Last umotion and vmotion and last location
!
! 3) Guess motion (zero relative to grid, e.g.)
! and last location
!
!-----------------------------------------------------------------------
!
nctim(mtime)=nctim(mpast)
deltat=time-alltime(mpast)
DO jcell=1,nctim(mpast)
IF(umotion(mpast,jcell) /= -1.0E30 .AND. &
vmotion(mpast,jcell) /= -1.0E30 ) THEN
PRINT *, ' Past abs umotion,vmotion (m/s):', &
umotion(mpast,jcell), &
vmotion(mpast,jcell)
IF(xnot(jcell) /= -1.0E30 .AND. ynot(jcell) /= -1.0E30 ) THEN
xxtrap=xnot(jcell)+time*umotion(mpast,jcell)
yxtrap=ynot(jcell)+time*vmotion(mpast,jcell)
ELSE
xxtrap=xpos(mpast,jcell)+deltat*umotion(mpast,jcell)
yxtrap=ypos(mpast,jcell)+deltat*vmotion(mpast,jcell)
END IF
ELSE
xxtrap=xpos(mpast,jcell)+deltat*umove
yxtrap=ypos(mpast,jcell)+deltat*vmove
END IF
PRINT *, ' past x,xxtrap = ',xpos(mpast,jcell),xxtrap
PRINT *, ' past y,yxtrap = ',ypos(mpast,jcell),yxtrap
!
!-----------------------------------------------------------------------
!
! Find the location among the current cells (icell) that is the
! closest to this past cell (jcell). When a cell has been used
! already, its wgt is set to -1.
!
!-----------------------------------------------------------------------
!
inear=0
drmin=1.0E30
DO icell=1,ncell
IF(wgt(icell) > 0.) THEN
ddx=xcent(icell)-xxtrap
ddy=ycent(icell)-yxtrap
dist2=ddx*ddx + ddy*ddy
IF(dist2 < d2thr) THEN
d2rat=dist2/area(icell)
! d2rat=dist2/wgt(icell)
IF(d2rat < drmin) THEN
inear=icell
drmin=d2rat
END IF
END IF
END IF
END DO
IF(inear > 0) THEN
PRINT *, ' time match jcell,inear= ',jcell,inear
distmin=SQRT(drmin*area(inear))
PRINT *, ' min distance (m) = ',distmin
xpos(mtime,jcell)=xcent(inear)
ypos(mtime,jcell)=ycent(inear)
zpos(mtime,jcell)=zcent(inear)
allvol(mtime,jcell)=area(inear)
allwgt(mtime,jcell)=wgt(inear)
wgt(inear)=-1.
END IF
END DO
!
!-----------------------------------------------------------------------
!
! Now make new locations for any cells not matched in the
! above process.
!
!-----------------------------------------------------------------------
!
DO icell=1,ncell
IF(wgt(icell) > 0.) THEN
PRINT *, ' New cell in time/motion matching: ', icell
IF(nctim(mtime) < maxcell) THEN
nctim(mtime)=nctim(mtime)+1
PRINT *, ' New count is ',nctim(mtime)
jcell=nctim(mtime)
xpos(mtime,jcell)=xcent(icell)
ypos(mtime,jcell)=ycent(icell)
zpos(mtime,jcell)=zcent(icell)
allvol(mtime,jcell)=area(icell)
allwgt(mtime,jcell)=wgt(icell)
ELSE
PRINT *, ' WARNING ran out space for cells'
PRINT *, ' in subroutine matctim. '
END IF
END IF
END DO
END IF
!
PRINT *, ' Leaving matctim, nctim = ',nctim(mtime)
RETURN
END SUBROUTINE matctim
!
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE GETVEC ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE getvec(maxcell,maxtime,ktime,mtime, & 1,4
cname,nctim,alltime, &
xpos,ypos,zpos,xnot,ynot, &
allvol,allwgt, &
umotion,vmotion,wmotion,growth)
!
IMPLICIT NONE
INTEGER :: maxcell,maxtime,ktime,mtime
CHARACTER (LEN=2) :: cname(maxcell)
INTEGER :: nctim(maxtime)
REAL :: alltime(maxtime)
REAL :: xpos(maxtime,maxcell),ypos(maxtime,maxcell), &
zpos(maxtime,maxcell)
REAL :: xnot(maxcell),ynot(maxcell)
REAL :: allvol(maxtime,maxcell),allwgt(maxtime,maxcell)
REAL :: umotion(maxtime,maxcell),vmotion(maxtime,maxcell), &
wmotion(maxtime,maxcell),growth(maxtime,maxcell)
!
!-----------------------------------------------------------------------
!
! Parameters and variables for least squares fitting.
!
!-----------------------------------------------------------------------
!
REAL :: twparm
PARAMETER (twparm=900.*900.) ! secs*secs
REAL :: tvalid,ufit,vfit
INTEGER :: ireturn
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: icell,mpast,itime
REAL :: deltat,znot,dummy
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
itime=MIN(ktime,maxtime)
mpast=MOD((ktime-1),maxtime)
IF(mpast == 0) mpast=maxtime
PRINT *, ' Inside getvec: ktime= ',ktime
PRINT *, ' mtime ',mtime,' nctim(mtime) = ',nctim(mtime)
PRINT *, ' mpast ',mpast,' nctim(mpast) = ',nctim(mpast)
!
!-----------------------------------------------------------------------
!
! Initialize all motions to a wacky missing value.
!
!-----------------------------------------------------------------------
!
DO icell=1,maxcell
xnot(icell)=-1.0E30
ynot(icell)=-1.0E30
umotion(mtime,icell)=-1.0E30
vmotion(mtime,icell)=-1.0E30
wmotion(mtime,icell)=-1.0E30
growth(mtime,icell)=-1.0E30
END DO
!
!-----------------------------------------------------------------------
!
! Use the least squares fit of a line to "itime" number of
! points to get the velocity.
!
! In the event a solution could not be found, ireturn.ne.0,
! use the current position less the past position to get the
! velocity.
!
!-----------------------------------------------------------------------
!
IF(ktime > 1) THEN
deltat=alltime(mtime)-alltime(mpast)
tvalid=0.5*(alltime(mtime)+alltime(mpast))
DO icell=1,nctim(mtime)
IF(xpos(mtime,icell) /= -1.0E30) THEN
CALL leastsq
(xpos(1,icell),alltime, &
tvalid,twparm,itime,xnot(icell),ufit,ireturn)
IF(ireturn == 0) THEN
umotion(mtime,icell)=ufit
ELSE IF(xpos(mpast,icell) /= -1.0E30) THEN
umotion(mtime,icell)= &
(xpos(mtime,icell)-xpos(mpast,icell))/deltat
END IF
CALL leastsq
(ypos(1,icell),alltime, &
tvalid,twparm,itime,ynot(icell),vfit,ireturn)
IF(ireturn == 0) THEN
vmotion(mtime,icell)=vfit
ELSE IF(ypos(mpast,icell) /= -1.0E30) THEN
vmotion(mtime,icell)= &
(ypos(mtime,icell)-ypos(mpast,icell))/deltat
END IF
CALL leastsq
(zpos(1,icell),alltime, &
tvalid,twparm,itime, &
znot,wmotion(mtime,icell),ireturn)
IF(ireturn /= 0 .AND. zpos(mpast,icell) /= -1.0E30) THEN
wmotion(mtime,icell)= &
(zpos(mtime,icell)-zpos(mpast,icell))/deltat
END IF
CALL leastsq
(allvol(1,icell),alltime, &
tvalid,twparm,itime, &
dummy,growth(mtime,icell),ireturn)
IF(ireturn /= 0 .AND. allvol(mpast,icell) /= -1.0E30) THEN
growth(mtime,icell)= &
(allvol(mtime,icell)-allvol(mpast,icell))/deltat
END IF
END IF
END DO
END IF
RETURN
END SUBROUTINE getvec
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE LEASTSQ ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE leastsq(xo,TO,tvalid,twparm,npts,xnot,uo,ireturn) 4
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Modified least-squares estimate for the following equations:
!
! X = xnot + Uo*t
!
! Modification is that what is minimized is not the X deviation
! squared, rather X deviation squared times a weight specified
! in the time weighting function tweight. The idea is to
! make the line fit the observations near the time specified as
! the "valid time", tvalid.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Steven Lazarus
! 4/12/93
!
! MODIFICATIONS:
! 4/13/93 Keith Brewster
! Added weighting based on time.
! Changed to do one variables at a time.
! 4/19/93 Keith Brewster
! Added ireturn variable.
!
!-----------------------------------------------------------------------
!
! INPUT:
!
! npts Number of points in the Sample
! xo Observed storm position (predictand) for X = xnot + Uo*t
! to Observed time for xo(to),yo(to) (t=to)
! tvalid "Valid" time of estimation, used for time weighting
! Closer fit to data near vaild time.
! twparm Time weighting parameter used as denominator in exponential
! time weighting function (secs*secs)
!
! OUTPUT:
!
! xnot Origin of regression line X =Xnot + Uo*t, (f(xo,to))
! uo Slope of the regression line X =Xnot + Uo*t, (f(xo,to))
! ireturn Return status indicator.
!
!-----------------------------------------------------------------------
!
! Variable Declarations
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: npts ! Number of points in the sample
REAL :: xo (npts) ! Observed independent variable
REAL :: TO (npts) ! Observed time for xo,yo
REAL :: tvalid ! valid time
REAL :: twparm ! time weighting parameter (secs*secs)
REAL :: xnot ! Least-Squares fit for x=xnot+uo*t
REAL :: uo ! Least-Squares fit for x=xnot+uo*t
INTEGER :: ireturn ! Return status indicator
! =0 succesful completion
! =1 not enough data
! =2 divide by zero avoided, nothing computed
!
!-----------------------------------------------------------------------
!
! Misc. Local Variables
!
!-----------------------------------------------------------------------
!
REAL :: sumx,sumt,sumw,sumt2
REAL :: sumxt
REAL :: dt,twgt
REAL :: denomx,denomu
INTEGER :: i,knt
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
knt = 0
sumw = 0.0
sumx = 0.0
sumt = 0.0
sumxt = 0.0
sumt2 = 0.0
DO i=1,npts
IF(xo(i) /= -1.0E30) THEN
knt=knt+1
dt=tvalid-TO(i)
twgt=EXP(-dt*dt/twparm)
sumw = sumw + twgt
sumx = sumx + xo(i)*twgt
sumt = sumt + TO(i)*twgt
sumt2 = sumt2 + TO(i)*TO(i)*twgt
sumxt = sumxt + xo(i)*TO(i)*twgt
END IF
END DO
IF( knt > 2) THEN
denomx = sumt*sumt - sumt2*sumw
denomu = sumw*sumt2 - sumt*sumt
IF( denomx /= 0. .AND. denomu /= 0.) THEN
ireturn=0
xnot = (sumt*sumxt - sumt2*sumx) / denomx
uo = (sumw*sumxt - sumx*sumt) / denomu
ELSE
ireturn=2
xnot = -1.e30
uo = -1.e30
END IF
ELSE
ireturn=1
xnot = -1.e30
uo = -1.e30
END IF
RETURN
END SUBROUTINE leastsq