!
!--------------------------------------------------------------------------
!
SUBROUTINE updgrd(mptr) 1,8
!
! To update a coarse grid by interpolating from finer grid(s).
!
INCLUDE 'nodal.inc'
INCLUDE 'agrigrid.inc'
INCLUDE 'agrialloc.inc'
INCLUDE 'grddsc.inc'
INCLUDE 'agricst.inc'
DIMENSION msrcs(30),iupvar(nxy2d+nxyz3d),iupsta(nxy2d+nxyz3d)
LOGICAL :: smstg2
IF( intrpodr == 2 ) THEN
nwhts=9
ELSE
nwhts=4
END IF
level = node(4,mptr)
IF(level >= lfine) RETURN
!
! Get all the possible source grids on the next level for mptr.
!
numscs=0
mgrid=lstart(level+1)
15 IF(mgrid == 0) GO TO 20
numscs=numscs+1
msrcs(numscs)=mgrid
mgrid=node(10,mgrid)
GO TO 15
20 CONTINUE
nx=node(5,mptr)
ny=node(6,mptr)
!
! --------------------------------------------------------------------
! update 2-d scalars
! --------------------------------------------------------------------
!
IF (verbose6) WRITE(6,'('' UPDATING 2-D SCALAR(S):''//)')
ndim=2
!
! initialize the updating status flag with value 1
!
DO i=1,nxy2d
iupsta(i)=1
END DO
100 CONTINUE
!
! search for unupdated 2-d scalars and group them according to staggering
!
nupvar=0
DO iup=1,nxy2d
!
! look for 1st 2-d scalar that needs updating
!
IF(iupxy(1,iup) == 1.AND.iupsta(iup) == 1.AND. iupxy(2,iup) == 0)THEN
nupvar=nupvar+1
iupvar(nupvar)=iup
iupsta(iup)=0
DO ivar=iup+1,nxy2d
!
! list additonal scalars with matching staggering to that of iup.
!
IF(iupxy(1,ivar) == 1.AND.iupsta(ivar) == 1.AND. &
iupxy(2,ivar) == 0.AND. smstg2(ivar,iup,2)) THEN
nupvar=nupvar+1
iupvar(nupvar)=ivar
iupsta(ivar)=0
END IF
END DO
END IF
END DO
!
! if no 2-d scalar needs updating goto next step
!
IF(nupvar == 0)GO TO 200
!
! perform interpolations for 3-d scalars listed in iupvar(nupvar).
!
IF( verbose6) THEN
WRITE(6,'(/'' UPDATING '',I3,'' 2-D SCALAR(S)''/)')nupvar
WRITE(6,9992) (iupvar(ii),ii=1,nupvar)
9992 FORMAT(1X, 10I5)
END IF
!
mxpts=nx*ny
iptr1=igetsp(2*mxpts)
iptr2=igetsp(2*mxpts)
iptr3=igetsp(2*mxpts)
iptr4=igetsp( mxpts)
iptr5=igetsp(nwhts*mxpts)
iptr6=igetsp(2*mxpts)
iptr7=igetsp(2*mxpts)
!
CALL itpscl
(mptr,msrcs,numscs,a(iptr1),a(iptr2),a(iptr3), &
a(iptr4),a(iptr5),a(iptr6),a(iptr7), &
mxpts,nwhts,iupvar,nupvar,ndim)
!
! restore tem space
!
CALL resett
!
! go back to check if any more var's need updating
!
GO TO 100
200 CONTINUE
!
! --------------------------------------------------------------------
! update 3-d scalars
! --------------------------------------------------------------------
!
IF(verbose6) WRITE(6,'('' UPDATING 3-D SCALAR(S):''//)')
ndim=3
!
! initialize the updating status flag with value 1
!
DO i=1,nxyz3d
iupsta(i)=1
END DO
!
! search for unupdated 3-d scalars and group them according to staggering
!
300 CONTINUE
nupvar=0
DO iup=1,nxyz3d
!
! look for 1st 3-d scalar that needs updating
!
IF(iupxyz(1,iup) == 1.AND.iupsta(iup) == 1.AND. iupxyz(2,iup) == 0)THEN
nupvar=nupvar+1
iupvar(nupvar)=iup
iupsta(iup)=0
DO ivar=iup+1,nxyz3d
!
! list additonal 3-d scalars with matching staggering to that of iup.
!
IF(iupxyz(1,ivar) == 1.AND.iupsta(ivar) == 1.AND. &
iupxyz(2,ivar) == 0.AND. smstg2(ivar,iup,3))THEN
nupvar=nupvar+1
iupvar(nupvar)=ivar
iupsta(ivar)=0
END IF
END DO
END IF
END DO
!
! if no more 3-d scalar needs updating goto next step
!
IF(nupvar == 0) GO TO 400
!
! perform interpolations for 3-d scalars listed in iupvar(nupvar).
!
IF(verbose6) THEN
WRITE(6,'(/'' UPDATING '',I3,'' 3-D SCALAR(S)''/)')nupvar
WRITE(6,9992) (iupvar(ii),ii=1,nupvar)
END IF
!
mxpts=nx*ny
iptr1=igetsp(2*mxpts)
iptr2=igetsp(2*mxpts)
iptr3=igetsp(2*mxpts)
iptr4=igetsp( mxpts)
iptr5=igetsp(nwhts*mxpts)
iptr6=igetsp(2*mxpts)
iptr7=igetsp(2*mxpts)
!
CALL itpscl
(mptr,msrcs,numscs,a(iptr1),a(iptr2),a(iptr3), &
a(iptr4),a(iptr5),a(iptr6),a(iptr7), &
mxpts,nwhts,iupvar,nupvar,ndim)
!
! restore tem space
!
CALL resett
!
! go back to check if any more var's need updating
!
GO TO 300
400 CONTINUE
!
!-------------------------------------------------------------------
! update 2-d vectors
! --------------------------------------------------------------------
!
! write(6,'('' updating 2-d vector(s):''//)')
ndim=2
!
! initialize the updating status flag with value 1
!
DO i=1,nxy2d
iupsta(i)=1
END DO
500 CONTINUE
!
! search for a vector that needs updating and store the compnt No. in
! array iupvar.
!
nupvar=0
DO iup=1,nxy2d
!
! look for 1st 2-d vector that needs updating
!
IF(iupxy(1,iup) == 1.AND.iupxy(2,iup) > 0.AND. iupsta(iup) == 1) THEN
iup2=iupxy(2,iup)
iupvar(nupvar+1)=iup
iupvar(nupvar+2)=iup2
nupvar=nupvar+2
iupsta(iup )=0
iupsta(iup2)=0
EXIT
END IF
END DO
67 CONTINUE
!
! if no more 2-d vector needs updating goto next step
!
IF(nupvar == 0)GO TO 600
!
! perform interpolations for 2-d vectors listed in iupvar(nupvar).
!
IF(verbose6) THEN
WRITE(6,'(//'' UPDATING 2-D VECTOR '',I5,I5//)') &
iupvar(1),iupvar(2)
END IF
!
mxpts=nx*ny
iptr1=igetsp(4*mxpts)
iptr2=igetsp(4*mxpts)
iptr3=igetsp(4*mxpts)
iptr4=igetsp(2*mxpts)
iptr5=igetsp(2*nwhts*mxpts)
iptr6=igetsp(4*mxpts)
iptr7=igetsp(4*mxpts)
!
CALL itpvtr
(mptr,msrcs,numscs,a(iptr1),a(iptr2),a(iptr3), &
a(iptr4),a(iptr5),a(iptr6),a(iptr7), &
mxpts,nwhts,iupvar,nupvar,ndim)
!
! restore tem space
!
CALL resett
!
! go back to check if any more var's need updating
!
GO TO 500
600 CONTINUE
!
!------------------------------------------------------------------
! update 3-d vectors
!------------------------------------------------------------------
!
IF(verbose6) WRITE(6,'('' UPDATING 3-D VECTOR(S):''//)')
ndim=3
!
! initialize the updating status flag with value 1
!
DO i=1,nxyz3d
iupsta(i)=1
END DO
!
700 CONTINUE
!
! search for a vector that needs updating and store the compnt No. in
! array iupvar.
!
nupvar=0
DO iup=1,nxyz3d
!
! pick out the 1st 3-d vector that needs updating
!
IF(iupxyz(1,iup) == 1.AND.iupxyz(2,iup) > 0.AND. iupsta(iup) == 1) THEN
iup2=iupxyz(2,iup)
iupvar(nupvar+1)=iup
iupvar(nupvar+2)=iup2
nupvar=nupvar+2
iupsta(iup )=0
iupsta(iup2)=0
EXIT
END IF
END DO
92 CONTINUE
!
! if no more 3-d vector needs updating goto next step
!
IF(nupvar == 0)GO TO 800
!
! perform interpolations for 3-d vectors listed in iupvar(nupvar).
!
IF(verbose6) THEN
WRITE(6,'(//'' UPDATING 3-D VECTOR '',I5,I5//)') &
iupvar(1),iupvar(2)
END IF
!
mxpts=nx*ny
iptr1=igetsp(4*mxpts)
iptr2=igetsp(4*mxpts)
iptr3=igetsp(4*mxpts)
iptr4=igetsp(2*mxpts)
iptr5=igetsp(2*nwhts*mxpts)
iptr6=igetsp(4*mxpts)
iptr7=igetsp(4*mxpts)
!
CALL itpvtr
(mptr,msrcs,numscs,a(iptr1),a(iptr2),a(iptr3), &
a(iptr4),a(iptr5),a(iptr6),a(iptr7), &
mxpts,nwhts,iupvar,nupvar,ndim)
!
! restore tem space
!
CALL resett
!
! go back to check if any more var's need updating
!
GO TO 700
800 CONTINUE
RETURN
END SUBROUTINE updgrd
!
!--------------------------------------------------------------------------
!
SUBROUTINE itpscl(mrec,msrcs,numscs,ptsrec, & 2,9
irec,isrc,igsrc,whts,pts,irecp,mxpts,nwhts, &
iupvar,nupvar,ndim)
!
DIMENSION msrcs(numscs),ptsrec(2,mxpts),irec(2,mxpts), &
isrc(2,mxpts),igsrc(mxpts),whts(nwhts,mxpts), &
pts(2,mxpts),irecp(2,mxpts), &
iupvar(nupvar)
INCLUDE 'nodal.inc'
INCLUDE 'agrigrid.inc'
INCLUDE 'agrialloc.inc'
INCLUDE 'grddsc.inc'
nw1=nint( SQRT(FLOAT(nwhts)) )
nw2=nw1
!
! Calculate and store the coor's of p-points of the receive
! grid in array ptsrec with their indecies stored in irec.
!
IF(nupvar == 0) RETURN
nx=node(5,mrec)
ny=node(6,mrec)
cosr=rnode(21,mrec)
sinr=rnode(22,mrec)
dxr=rnode(9 ,mrec)
dyr=rnode(10,mrec)
xor=rnode(1,mrec)
yor=rnode(2,mrec)
ivar=iupvar(1)
IF(ndim == 2) THEN
xshift=stgxy(1,ivar)
yshift=stgxy(2,ivar)
nx1=nx-idmxy(1,ivar)
ny1=ny-idmxy(2,ivar)
ELSE IF(ndim == 3)THEN
xshift=stgxyz(1,ivar)
yshift=stgxyz(2,ivar)
nx1=nx-idmxyz(1,ivar)
ny1=ny-idmxyz(2,ivar)
ELSE
PRINT*,'Error in ITPSCL: Variable dimension ndim set wrong!'
PRINT*,'ndim should be 2 or 3, input was',ndim
END IF
xc=xshift*dxr*cosr
ys=yshift*dyr*sinr
xs=xshift*dxr*sinr
yc=yshift*dyr*cosr
xorp=xor+xc-ys
yorp=yor+xs+yc
!
! To calculate the absolute coordinates of the model interior
! points that may need updating.
!
! Attention:
!
! here we assume that in x direction the interior points start
! at i=2 and finish at i=nx1-1. The boundaries are at i=1 and nx1.
! Similarly in y direction, the boundaries are at j=1 and ny1.
! If in a particular solver (model), the boundaries for certain
! variables are defined at points other the above, the use needs to
! change the following loop accordingly (i.e. change ist, jst, iend
! and jend). As a result, the part in routine ITPBSL that calculates
! the points for boundary value interpolations also need change.
!
ist=2
jst=2
iend=nx1-1
jend=ny1-1
DO j=jst,jend
jj=(j-jst)*(iend-ist+1)
DO i=ist,iend
ii = jj+i-ist+1
x = (i-1)*dxr
y = (j-1)*dyr
ptsrec(1,ii) = xorp+x*cosr-y*sinr
ptsrec(2,ii) = yorp+x*sinr+y*cosr
irec (1,ii) = i
irec (2,ii) = j
END DO
END DO
numpts=(iend-ist+1)*(jend-jst+1)
!
! Find the source points for receive grid points ptsrec
!
ierfl=0
iptcmp=1
CALL getsrc
(mrec,msrcs,numscs,xshift,yshift,ptsrec,numpts, &
irec,igsrc,ierfl,iptcmp)
!
! if no point can be updated from listed source grids, skip through
! this loop
!
IF(numpts == 0) THEN
WRITE(6,'(''NO SRC. POINT FOUND FOR'',I2,''-d variable(s)'')')ndim
WRITE(6,'(20i4)') iupvar
RETURN
END IF
!
! Loop through all source grids
!
DO ks=1,numscs
msrc=msrcs(ks)
!
! sort rec. grid points according to their source grid
!
npts=0
DO np=1,numpts
IF(igsrc(np) == msrc) THEN
npts=npts+1
pts(1,npts)=ptsrec(1,np)
pts(2,npts)=ptsrec(2,np)
irecp(1,npts)=irec(1,np)
irecp(2,npts)=irec(2,np)
END IF
END DO
IF(npts == 0) CYCLE
nxr=node(5,mrec)
nyr=node(6,mrec)
nzr=node(14,mrec)
nxs=node(5,msrc)
nys=node(6,msrc)
nzs=node(14,msrc)
!
! Calculate weights of interpolation for points pts.
!
CALL calwht
(mrec,msrc,pts,isrc,whts,npts,nwhts,ivar,ndim)
! print*,'after calling calwht'
! do 1111 ii=1,npts
! write(6,'(5i5,10f10.5)') ii,irecp(1,ii),irecp(2,ii),
! : isrc(1,ii),isrc(2,ii),(whts(jj,ii),jj=1,nw1*nw2)
!1111 continue
!
! update variables in list iupvar
!
DO i=1,nupvar
ivar=iupvar(i)
IF(ndim == 2) THEN
n3rd=1
irptr=igtnxy(mrec,ivar,1)
isptr=igtnxy(msrc,ivar,1)
ELSE
n3rd=nzs
irptr=igtxyz(mrec,ivar,1)
isptr=igtxyz(msrc,ivar,1)
END IF
needsp =nxs*nys*n3rd
iavrg=igetsp(needsp)
CALL hrzavg
(
CALL intrps
( irecp,isrc,whts,npts,nw1,nw2)
IF(ndim == 2) THEN
CALL retnxy
(mrec,ivar,1,irptr,.true.)
CALL retnxy
(msrc,ivar,1,isptr,.false.)
ELSE
CALL retxyz
(mrec,ivar,1,irptr,.true.)
CALL retxyz
(msrc,ivar,1,isptr,.false.)
END IF
CALL reclam
(iavrg,nxs*nys*n3rd)
END DO
!
END DO
500 CONTINUE
RETURN
END SUBROUTINE itpscl
!
!--------------------------------------------------------------------------
!
SUBROUTINE intrps(varrec,varsrc,nxr,nyr,nxs,nys,nz, & 5
irec,isrc,whts,numpts,nw1,nw2)
DIMENSION varrec(nxr,nyr,nz),varsrc(nxs,nys,nz), &
irec(2,numpts),isrc(2,numpts),whts(nw1,nw2,numpts)
!
itest = 0
IF(itest == 1) THEN
WRITE(6,'('' DATA DUMP IN INTRPS '',8I6)') &
nxr,nyr,nxs,nys,nz,numpts,nw1,nw2
DO ip=1,20
WRITE(7,1114) irec(1,ip),irec(2,ip),isrc(1,ip),isrc(2,ip), &
whts(1,1,ip),whts(2,1,ip),whts(1,2,ip),whts(2,2,ip)
END DO
1114 FORMAT(1X,4I7,4E10.3)
END IF
IF(nw1 == 2.AND.nw2 == 2) THEN
!
! The interpolation calculations are all independent of each other,
! they can be vecotrized in inner loop and parellelized in outer loop.
!
nzswap=2
!
! if nz if small, swap the loop order
!
IF(nz <= nzswap)THEN
!fpp$ nodepchk
DO ks=1,nz
!DIR$ IVDEP
DO np=1,numpts
ir = irec(1,np)
jr = irec(2,np)
is = isrc(1,np)
js = isrc(2,np)
varrec(ir,jr,ks)=varsrc(is,js,ks)*whts(1,1,np) &
+varsrc(is+1,js,ks)*whts(2,1,np) &
+varsrc(is,js+1,ks)*whts(1,2,np) &
+varsrc(is+1,js+1,ks)*whts(2,2,np)
END DO
END DO
ELSE
!fpp$ nodepchk
DO np=1,numpts
ir = irec(1,np)
jr = irec(2,np)
is = isrc(1,np)
js = isrc(2,np)
!DIR$ IVDEP
DO ks=1,nz
varrec(ir,jr,ks)=varsrc(is,js,ks)*whts(1,1,np) &
+varsrc(is+1,js,ks)*whts(2,1,np) &
+varsrc(is,js+1,ks)*whts(1,2,np) &
+varsrc(is+1,js+1,ks)*whts(2,2,np)
END DO
END DO
END IF
ELSE
IF(nz <= nzswap)THEN
!fpp$ nodepchk
DO ks=1,nz
!DIR$ IVDEP
DO np=1,numpts
ir = irec(1,np)
jr = irec(2,np)
is = isrc(1,np)
js = isrc(2,np)
varrec(ir,jr,ks)= &
varsrc(is-1,js-1,ks)*whts(1,1,np) &
+varsrc(is ,js-1,ks)*whts(2,1,np) &
+varsrc(is+1,js-1,ks)*whts(3,1,np) &
+varsrc(is-1,js ,ks)*whts(1,2,np) &
+varsrc(is ,js ,ks)*whts(2,2,np) &
+varsrc(is+1,js ,ks)*whts(3,2,np) &
+varsrc(is-1,js+1,ks)*whts(1,3,np) &
+varsrc(is ,js+1,ks)*whts(2,3,np) &
+varsrc(is+1,js+1,ks)*whts(3,3,np)
END DO
END DO
ELSE
!fpp$ nodepchk
DO np=1,numpts
ir = irec(1,np)
jr = irec(2,np)
is = isrc(1,np)
js = isrc(2,np)
!DIR$ IVDEP
DO ks=1,nz
varrec(ir,jr,ks)= &
varsrc(is-1,js-1,ks)*whts(1,1,np) &
+varsrc(is ,js-1,ks)*whts(2,1,np) &
+varsrc(is+1,js-1,ks)*whts(3,1,np) &
+varsrc(is-1,js ,ks)*whts(1,2,np) &
+varsrc(is ,js ,ks)*whts(2,2,np) &
+varsrc(is+1,js ,ks)*whts(3,2,np) &
+varsrc(is-1,js+1,ks)*whts(1,3,np) &
+varsrc(is ,js+1,ks)*whts(2,3,np) &
+varsrc(is+1,js+1,ks)*whts(3,3,np)
END DO
END DO
END IF
END IF
RETURN
END SUBROUTINE intrps
!
!--------------------------------------------------------------------------
!
SUBROUTINE itpvtr(mrec,msrcs,numscs,ptsrec, & 2,13
irec,isrc,igsrc,whts,pts,irecp,mxpts,nwhts, &
iupvar,nupvar,ndim)
!
DIMENSION msrcs(numscs),ptsrec(2,mxpts,2),irec(2,mxpts,2), &
isrc(2,mxpts,2),igsrc(mxpts,2),whts(nwhts,mxpts,2), &
pts(2,mxpts,2),irecp(2,mxpts,2),iupvar(nupvar), &
numpts(2),npts(2)
INCLUDE 'nodal.inc'
INCLUDE 'agrigrid.inc'
INCLUDE 'agrialloc.inc'
INCLUDE 'grddsc.inc'
LOGICAL :: samstg,smstg2
nw1=nint( SQRT(FLOAT(nwhts)) )
nw2=nw1
!
IF(nupvar == 0) RETURN
nxr=node(5,mrec)
nyr=node(6,mrec)
nzr=node(14,mrec)
cosr=rnode(21,mrec)
sinr=rnode(22,mrec)
dxr=rnode(9 ,mrec)
dyr=rnode(10,mrec)
xor=rnode(1,mrec)
yor=rnode(2,mrec)
!
CALL chkdim
(ndim,'ITPVTR')
!
! To loop through all vectors, which has two components stored consecutively
! in nupvar. The 1st compt. has to be the one in x direction.
!
DO ivtr=1,nupvar,2
ivar1=iupvar(ivtr)
ivar2=iupvar(ivtr+1)
samstg=smstg2(ivar1,ivar2,ndim)
IF(ndim == 2) THEN
xshft = MAX( stgxy(1,ivar1),stgxy(1,ivar2) )
yshft = MAX( stgxy(2,ivar1),stgxy(2,ivar2) )
ELSE IF(ndim == 3)THEN
xshft = MAX( stgxyz(1,ivar1),stgxyz(1,ivar2) )
yshft = MAX( stgxyz(2,ivar1),stgxyz(2,ivar2) )
END IF
!
! Find the points on rec. grid for both compnts. and the source grid for
! them.If the two compnts have the samew staggering, they have the
! same coordinate points and the source grid, therefore those for the
! 2nd compnt. do not need to be recalculated.
!
DO icmpr=1,2
!
! icmpr=1 for the 1st component of vectors
! =2 for the 2nd component of vectors
!
IF(icmpr == 2.AND.samstg)THEN
numpts(2)=numpts(1)
DO ip=1,numpts(2)
ptsrec(1,ip,2)=ptsrec(1,ip,1)
ptsrec(2,ip,2)=ptsrec(2,ip,1)
irec(1,ip,2)=irec(1,ip,1)
irec(2,ip,2)=irec(2,ip,1)
igsrc(ip,2)=igsrc(ip,1)
END DO
CYCLE
END IF
ivar=iupvar(ivtr+icmpr-1)
IF(ndim == 2) THEN
xshift=stgxy(1,ivar)
yshift=stgxy(2,ivar)
nx1=nxr-idmxy(1,ivar)
ny1=nyr-idmxy(2,ivar)
ELSE IF(ndim == 3)THEN
xshift=stgxyz(1,ivar)
yshift=stgxyz(2,ivar)
nx1=nxr-idmxyz(1,ivar)
ny1=nyr-idmxyz(2,ivar)
END IF
xc=xshift*dxr*cosr
ys=yshift*dyr*sinr
xs=xshift*dxr*sinr
yc=yshift*dyr*cosr
xorp=xor+xc-ys
yorp=yor+xs+yc
!
! The following loop calculates the absolute coordinates of the model
! interior points that may need updating.
!
! Attention:
!
! here we assume that in x direction the interior points start
! at i=2 and finish at i=nx1-1. The boundaries are at i=1 and nx1.
! Similarly in y direction, the boundaries are at j=1 and ny1.
! If in a particular solver (model), the boundaries for certain
! variables are defined at points other the above, the use needs to
! change the following loop accordingly (i.e. change ist, jst, iend
! and jend). As a result, the part in routine ITPBVT that calculates
! the points for boundary value interpolations also need change.
!
ist=2
jst=2
iend=nx1-1
jend=ny1-1
DO j=jst,jend
jj=(j-jst)*(iend-ist+1)
DO i=ist,iend
ii=jj+i-ist+1
x=(i-1)*dxr
y=(j-1)*dyr
ptsrec(1,ii,icmpr) = xorp+x*cosr-y*sinr
ptsrec(2,ii,icmpr) = yorp+x*sinr+y*cosr
irec (1,ii,icmpr) = i
irec (2,ii,icmpr) = j
END DO
END DO
numpts(icmpr)=(iend-ist+1)*(jend-jst+1)
16 CONTINUE
!
! Find the source grid for receive grid points ptsrec
!
ierfl=0
iptcmp=1
CALL getsrc
(mrec,msrcs,numscs,xshft,yshft,ptsrec(1,1,icmpr), &
numpts(icmpr),irec(1,1,icmpr),igsrc(1,icmpr),ierfl,iptcmp)
END DO
!
! if no point can be updated from listed source grids, skip through
! this loop
!
IF(numpts(1) == 0.AND.numpts(2) == 0) THEN
WRITE(6,'(''NO SRC. POINT FOUND FOR'',I2, &
& ''-d vector no. '', 2I6)')ndim,iupvar(ivtr),iupvar(ivtr+1)
CYCLE
END IF
!
! find storage pointers for the receive grid variables (2 compnts of vector).
! uppack them if neccesary.
!
IF(ndim == 2) THEN
irptr1=igtnxy(mrec,ivar1,1)
irptr2=igtnxy(mrec,ivar2,1)
ELSE
irptr1=igtxyz(mrec,ivar1,1)
irptr2=igtxyz(mrec,ivar2,1)
END IF
!
! Loop through all source grids
!
DO ks=1,numscs
msrc=msrcs(ks)
nxs=node(5,msrc)
nys=node(6,msrc)
nzs=node(14,msrc)
coss=rnode(21,msrc)
sins=rnode(22,msrc)
cossr= coss*cosr+sins*sinr
sinsr= coss*sinr-sins*cosr
DO icmps=1,2
DO icmpr=1,2
IF(icmpr == 2.AND.samstg)THEN
npts(2)=npts(1)
DO ip=1,npts(2)
pts (1,ip,2)=pts (1,ip,1)
pts (2,ip,2)=pts (2,ip,1)
isrc (1,ip,2)=isrc (1,ip,1)
isrc (2,ip,2)=isrc (2,ip,1)
irecp(1,ip,2)=irecp(1,ip,1)
irecp(2,ip,2)=irecp(2,ip,1)
END DO
DO iw=1,nwhts
DO ip=1,npts(2)
whts(iw,ip,2)=whts(iw,ip,1)
END DO
END DO
PRINT*,'irecp, isrc, whts with icmps=:',icmps
CYCLE
END IF
!
! sort rec. grid points according to their source grid
!
npt=0
DO np=1,numpts(icmpr)
IF(igsrc(np,icmpr) == msrc) THEN
npt=npt+1
pts(1,npt,icmpr)=ptsrec(1,np,icmpr)
pts(2,npt,icmpr)=ptsrec(2,np,icmpr)
irecp(1,npt,icmpr)=irec(1,np,icmpr)
irecp(2,npt,icmpr)=irec(2,np,icmpr)
END IF
END DO
npts(icmpr)=npt
IF(npts(icmpr) == 0) CYCLE
!
! Calculate weights of interpolation for points pts.
!
ivsrc=iupvar(ivtr+icmps-1)
CALL calwht
(mrec,msrc,pts(1,1,icmpr),isrc(1,1,icmpr), &
whts(1,1,icmpr),npts(icmpr),nwhts,ivsrc,ndim)
END DO
IF(npts(1) == 0.AND.npts(2) == 0) CYCLE
!
! find pointer for one of the components (icmps) of the source grid
! vector. If it is packed, do uppacking for this variable.
!
ivsrc=iupvar(ivtr+icmps-1)
IF(ndim == 2) THEN
n3rd=1
isptr=igtnxy(msrc,ivsrc,1)
ELSE
n3rd=nzs
isptr=igtxyz(msrc,ivsrc,1)
END IF
needsp = nxs*nys*n3rd
iavrg=igetsp(needsp)
CALL hrzavg
(
IF(icmps == 1)THEN
proj1=cossr
proj2=-sinsr
ELSE
proj1=sinsr
proj2=cossr
END IF
icmpr=1
IF(npts(icmpr) /= 0) THEN
CALL intrpv
( irecp(1,1,icmpr),isrc(1,1,icmpr),whts(1,1,icmpr), &
npts(icmpr),nw1,nw2,icmps,proj1)
END IF
icmpr=2
IF(npts(icmpr) /= 0) THEN
CALL intrpv
( irecp(1,1,icmpr),isrc(1,1,icmpr),whts(1,1,icmpr), &
npts(icmpr),nw1,nw2,icmps,proj2)
END IF
CALL reclam
(iavrg,nxs*nys*n3rd)
IF(ndim == 2) THEN
CALL retnxy
(msrc,ivsrc,1,isptr,.false.)
ELSE
CALL retxyz
(msrc,ivsrc,1,isptr,.false.)
END IF
END DO
!
END DO
IF(ndim == 2) THEN
CALL retnxy
(mrec,ivar1,1,irptr1,.true.)
CALL retnxy
(mrec,ivar2,1,irptr2,.true.)
ELSE
CALL retxyz
(mrec,ivar1,1,irptr1,.true.)
CALL retxyz
(mrec,ivar2,1,irptr2,.true.)
END IF
END DO
RETURN
END SUBROUTINE itpvtr
!
!--------------------------------------------------------------------------
!
SUBROUTINE intrpv(varrec,varsrc,nxr,nyr,nxs,nys,nz, & 6
irec,isrc,whts,numpts,nw1,nw2,mode,proj)
DIMENSION varrec(nxr,nyr,nz),varsrc(nxs,nys,nz), &
irec(2,numpts),isrc(2,numpts),whts(nw1,nw2,numpts)
!
itest = 0
IF(itest == 1) THEN
WRITE(6,'('' DATA DUMP IN INTRPV '',8I6)') &
nxr,nyr,nxs,nys,nz,numpts,nw1,nw2
DO ip=1,20
WRITE(7,1114) irec(1,ip),irec(2,ip),isrc(1,ip),isrc(2,ip), &
whts(1,1,ip),whts(2,1,ip),whts(1,2,ip),whts(2,2,ip)
END DO
1114 FORMAT(1X,4I7,4E10.3)
END IF
iaccum=0
IF(mode == 2) iaccum=1
IF(nw1 == 2.AND.nw2 == 2) THEN
!
! The interpolation calculations are all independent of each other,
! they can be vecotrized in inner loop and parellelized in outer loop.
!
nzswap=2
!
! if nz if small, swap the loop order
!
IF(nz <= nzswap)THEN
!fpp$ nodepchk
DO ks=1,nz
!DIR$ IVDEP
DO np=1,numpts
ir = irec(1,np)
jr = irec(2,np)
is = isrc(1,np)
js = isrc(2,np)
varrec(ir,jr,ks)=varrec(ir,jr,ks)*iaccum &
+(varsrc(is,js,ks)*whts(1,1,np) &
+varsrc(is+1,js,ks)*whts(2,1,np) &
+varsrc(is,js+1,ks)*whts(1,2,np) &
+varsrc(is+1,js+1,ks)*whts(2,2,np))*proj
END DO
END DO
ELSE
!fpp$ nodepchk
DO np=1,numpts
ir = irec(1,np)
jr = irec(2,np)
is = isrc(1,np)
js = isrc(2,np)
!DIR$ IVDEP
DO ks=1,nz
varrec(ir,jr,ks)=varrec(ir,jr,ks)*iaccum &
+(varsrc(is,js,ks)*whts(1,1,np) &
+varsrc(is+1,js,ks)*whts(2,1,np) &
+varsrc(is,js+1,ks)*whts(1,2,np) &
+varsrc(is+1,js+1,ks)*whts(2,2,np))*proj
END DO
END DO
END IF
ELSE
IF(nz <= nzswap)THEN
!fpp$ nodepchk
DO ks=1,nz
!DIR$ IVDEP
DO np=1,numpts
ir = irec(1,np)
jr = irec(2,np)
is = isrc(1,np)
js = isrc(2,np)
varrec(ir,jr,ks)=varrec(ir,jr,ks)*iaccum &
+(varsrc(is-1,js-1,ks)*whts(1,1,np) &
+varsrc(is ,js-1,ks)*whts(2,1,np) &
+varsrc(is+1,js-1,ks)*whts(3,1,np) &
+varsrc(is-1,js ,ks)*whts(1,2,np) &
+varsrc(is ,js ,ks)*whts(2,2,np) &
+varsrc(is+1,js ,ks)*whts(3,2,np) &
+varsrc(is-1,js+1,ks)*whts(1,3,np) &
+varsrc(is ,js+1,ks)*whts(2,3,np) &
+varsrc(is+1,js+1,ks)*whts(3,3,np))*proj
END DO
END DO
ELSE
!fpp$ nodepchk
DO np=1,numpts
ir = irec(1,np)
jr = irec(2,np)
is = isrc(1,np)
js = isrc(2,np)
!DIR$ IVDEP
DO ks=1,nz
varrec(ir,jr,ks)=varrec(ir,jr,ks)*iaccum &
+(varsrc(is-1,js-1,ks)*whts(1,1,np) &
+varsrc(is ,js-1,ks)*whts(2,1,np) &
+varsrc(is+1,js-1,ks)*whts(3,1,np) &
+varsrc(is-1,js ,ks)*whts(1,2,np) &
+varsrc(is ,js ,ks)*whts(2,2,np) &
+varsrc(is+1,js ,ks)*whts(3,2,np) &
+varsrc(is-1,js+1,ks)*whts(1,3,np) &
+varsrc(is ,js+1,ks)*whts(2,3,np) &
+varsrc(is+1,js+1,ks)*whts(3,3,np))*proj
END DO
END DO
END IF
END IF
RETURN
END SUBROUTINE intrpv
!
!--------------------------------------------------------------------------
!
SUBROUTINE getsrc(mrec,msrcs,numscs,xshift,yshift,ptsrec,numpts, & 9
irec,igsrc,ierfl,iptcmp)
DIMENSION msrcs(numscs),ptsrec(2,numpts),irec(2,numpts), &
igsrc(numpts)
!
INCLUDE 'nodal.inc'
INCLUDE 'agrigrid.inc'
INCLUDE 'agrialloc.inc'
INCLUDE 'grddsc.inc'
levelr = node(4,mrec)
!
DO i=1,numpts
igsrc(i)=0
END DO
!
DO lvlchk=levelr-1,levelr+1
!
IF(lvlchk == 0) CYCLE
DO ig=1,numscs
msrc=msrcs(ig)
IF(node(4,msrc) /= lvlchk) CYCLE
!
! now find points with msrc as source
!
dx = rnode(9,msrc)
dy = rnode(10,msrc)
hx=2*hxposs(lvlchk)+xshift*dx
hy=2*hyposs(lvlchk)+yshift*dy
t1=rnode(16,msrc)-hx
t2=rnode(17,msrc)+hx
t3=rnode(18,msrc)-hy
t4=rnode(19,msrc)+hy
DO i=1,numpts
ex1=ptsrec(1,i)*rnode(12,msrc)+ptsrec(2,i)*rnode(13,msrc)
ex2=ptsrec(1,i)*rnode(14,msrc)+ptsrec(2,i)*rnode(15,msrc)
IF((t1-ex1 >= 0).AND.(ex1-t2 >= 0).AND. &
(t3-ex2 >= 0).AND.(ex2-t4 >= 0)) igsrc(i)=msrc
END DO
END DO
END DO
!
! next check if source has been found for all points
!
ierfl0=ierfl
IF(ierfl == 1) THEN
ierfl=0
DO i=1,numpts
IF(igsrc(i) == 0) ierfl=ierfl+1
END DO
IF(ierfl > 0) THEN
!
! some points do not have a source, problems here
!
WRITE(6,'('' IN SOURCE, POINTS LACKING SOURCE, GRID '',i4)') mrec
WRITE(6,'('' POSSIBLE SOURCE GRIDS '',10I4)')(msrcs(i),i=1,numscs)
DO i=1,numpts
IF(igsrc(i) == 0) WRITE(6,240) ptsrec(1,i),ptsrec(2,i)
END DO
240 FORMAT(' point ',2(1X,e12.5))
ierfl=1
END IF
END IF
!
! finally, return only those points that have source
!
IF(ierfl0 == 1.AND.ierfl == 0) RETURN
IF(iptcmp == 1) THEN
ist=0
DO i=1,numpts
IF(igsrc(i) /= 0)THEN
ist=ist+1
igsrc(ist)=igsrc(i)
ptsrec(1,ist)=ptsrec(1,i)
ptsrec(2,ist)=ptsrec(2,i)
irec(1,ist)=irec(1,i)
irec(2,ist)=irec(2,i)
END IF
END DO
numpts=ist
310 CONTINUE
END IF
RETURN
END SUBROUTINE getsrc
!
!--------------------------------------------------------------------------
!
SUBROUTINE calwht(mrec,msrc,points,isrc,whts,numpts,nwhts, & 8
ivar,ndim)
DIMENSION points(2,numpts),whts(nwhts,numpts),isrc(2,numpts)
!
! this routine calculates the weights for the interpolation
! of mass points or vertical velocity (stuff that doesn't need
! any rotation from grid msrc to grid mrec
!
! if nw = 4 bilinear interp., = 9 bi-quadratic
!
INCLUDE 'nodal.inc'
INCLUDE 'agrigrid.inc'
INCLUDE 'agrialloc.inc'
INCLUDE 'grddsc.inc'
fq(xp,x1,x2,x3,x4)=(xp-x2)*(xp-x3)/ &
((x1-x2)*(x1-x3))+x4
fl(xp,x1,x2)=(xp-x2)/(x1-x2)
!
cosc = rnode( 21,msrc)
sinc = rnode( 22,msrc)
dxc = rnode(9,msrc)
dyc = rnode(10,msrc)
odxc = 1./dxc
odyc = 1./dyc
xor = rnode(1,msrc)
yor = rnode(2,msrc)
!
IF(ndim == 2) THEN
xshift=stgxy(1,ivar)
yshift=stgxy(2,ivar)
ELSE
xshift=stgxyz(1,ivar)
yshift=stgxyz(2,ivar)
END IF
xc=xshift*dxc*cosc
ys=yshift*dyc*sinc
xs=xshift*dxc*sinc
yc=yshift*dyc*cosc
xorp=xor+xc-ys
yorp=yor+xs+yc
DO i=1,numpts
x=points(1,i)
y=points(2,i)
points(1,i)=1+( cosc*(x-xorp)+sinc*(y-yorp))*odxc
points(2,i)=1+(-sinc*(x-xorp)+cosc*(y-yorp))*odyc
END DO
!
! next, calculate weights for the interpolation
!
IF(nwhts == 9) THEN
alpha=0.
alpha2=0.
DO i=1,numpts
xp=points(1,i)-FLOAT( nint(points(1,i)) )
yp=points(2,i)-FLOAT( nint(points(2,i)) )
tempy1=fq(yp,-1.,0.,1.,alpha)
tempy2=fq(yp,0.,-1.,1.,alpha2)
tempy3=fq(yp,1.,-1.,0.,alpha)
tempx1=fq(xp,-1.,0.,1.,alpha)
tempx2=fq(xp,0.,-1.,1.,alpha2)
tempx3=fq(xp,1.,-1.,0.,alpha)
whts(1,i)=tempy1*tempx1
whts(2,i)=tempy1*tempx2
whts(3,i)=tempy1*tempx3
whts(4,i)=tempy2*tempx1
whts(5,i)=tempy2*tempx2
whts(6,i)=tempy2*tempx3
whts(7,i)=tempy3*tempx1
whts(8,i)=tempy3*tempx2
whts(9,i)=tempy3*tempx3
isrc(1,i)=nint(points(1,i))
isrc(2,i)=nint(points(2,i))
END DO
ELSE
DO i=1,numpts
xp=points(1,i)-FLOAT( INT(points(1,i)) )
yp=points(2,i)-FLOAT( INT(points(2,i)) )
tempy1=fl(yp,0.,1.)
tempy2=fl(yp,1.,0.)
tempx1=fl(xp,0.,1.)
tempx2=fl(xp,1.,0.)
whts(1,i)=tempy1*tempx1
whts(2,i)=tempy1*tempx2
whts(3,i)=tempy2*tempx1
whts(4,i)=tempy2*tempx2
isrc(1,i)=INT(points(1,i))
isrc(2,i)=INT(points(2,i))
END DO
END IF
RETURN
END SUBROUTINE calwht
!
!--------------------------------------------------------------------------
!
SUBROUTINE hrzavg(vout,vin,nx,ny,nz) 2
!
! Perform horizontal plane average over nine points.
!
DIMENSION vout(nx,ny,nz),vin(nx,ny,nz)
a19 = 1.0/9.0
DO k=1,nz
DO j=2,ny-1
DO i=2,nx-1
vout(i,j,k)=(vin(i,j,k)+vin(i-1,j,k)+vin(i+1,j,k) &
+vin(i,j-1,k)+vin(i,j+1,k)+vin(i+1,j+1,k) &
+vin(i+1,j-1,k)+vin(i-1,j+1,k)+vin(i-1,j-1,k))*a19
END DO
END DO
END DO
DO k=1,nz
DO j=1,ny
vout(1 ,j,k)=vin(1, j,k)
vout(nx,j,k)=vin(nx,j,k)
END DO
DO i=1,nx
vout(i,1 ,k)=vin(i,1 ,k)
vout(i,ny,k)=vin(i,ny,k)
END DO
END DO
RETURN
END SUBROUTINE hrzavg
FUNCTION smstg2(ivar1,ivar2, ndim),1
INCLUDE 'agrigrid.inc'
INCLUDE 'grddsc.inc'
LOGICAL :: smstg2
smstg2=.false.
eps=1.0E-6
CALL chkdim
(ndim,'SMSTG2')
IF(ndim == 2) THEN
IF(ABS(stgxy (1,ivar1)-stgxy (1,ivar2 )) < eps .AND. &
ABS(stgxy (2,ivar1)-stgxy (2,ivar2)) < eps) smstg2=.true.
ELSE
IF(ABS(stgxyz(1,ivar1)-stgxyz(1,ivar2 )) < eps .AND. &
ABS(stgxyz(2,ivar1)-stgxyz(2,ivar2)) < eps) smstg2=.true.
END IF
RETURN
END FUNCTION smstg2
FUNCTION smstg3(ivar1,ivar2, ndim),1
INCLUDE 'agrigrid.inc'
INCLUDE 'grddsc.inc'
LOGICAL :: smstg3
smstg3=.false.
eps=1.0E-6
CALL chkdim
(ndim,'SMSTG3')
IF(ndim == 2) THEN
IF(ABS(stgxy (1,ivar1)-stgxy (1,ivar2)) < eps.AND. &
ABS(stgxy (2,ivar1)-stgxy (2,ivar2)) < eps) smstg3=.true.
ELSE
IF(ABS(stgxyz(1,ivar1)-stgxyz(1,ivar2)) < eps.AND. &
ABS(stgxyz(2,ivar1)-stgxyz(2,ivar2)) < eps.AND. &
ABS(stgxyz(3,ivar1)-stgxyz(3,ivar2)) < eps) smstg3=.true.
END IF
RETURN
END FUNCTION smstg3
!
SUBROUTINE addcst(mptr,ndim,ivar,cst),3
!
! to add a constant CST to ndim-D variable IVAR for grid MPTR.
!
INCLUDE 'nodal.inc'
INCLUDE 'agrigrid.inc'
INCLUDE 'grddsc.inc'
INCLUDE 'agrialloc.inc'
nx=node(5,mptr)
ny=node(6,mptr)
CALL chkdim
(ndim,'GTRCRD')
IF(ndim == 2) THEN
nz=1
iptr=igtnxy(mptr,ivar,1)
ELSE
nz=node(14,mptr)
iptr=igtxyz(mptr,ivar,1)
END IF
DO ijk=1,nx*ny*nz
a(ijk-1+iptr)=a(ijk-1+iptr)+cst
END DO
IF(ndim == 2) THEN
CALL retnxy
(mptr,ivar,1,iptr,.true.)
ELSE
CALL retxyz
(mptr,ivar,1,iptr,.true.)
END IF
RETURN
END SUBROUTINE addcst