SUBROUTINE regrid(lbase,rdbpts) 1,8
!
LOGICAL :: rdbpts
INCLUDE 'nodal.inc'
INCLUDE 'agricpu.inc'
INCLUDE 'agricst.inc'
!
! ******************************************************************
! REGRID = FLAG POINTS ON EACH GRID WITH A LEVEL > = LBASE.
! CLUSTER THEM, AND FIT NEW SUBGRIDS AROUND THE CLUSTERS.
! THE LBASE GRIDS STAY FIXED DURING REGRIDDING OPERATION.
! WHEN A PARENT GRID HAS ITS ERROR ESTIMATED, ADD ITS KID GRID
! INFORMATION TO THE ERROR GRID BEFORE CLUSTERING. (PROJECT)
! ORDER OF GRID EXAMINATION - ALL GRIDS AT THE SAME LEVEL, THEN
! DO THE NEXT COARSER LEVEL.
!
! NOTE: THE ACTUAL GRIDFITTING IS DONE BY GRDFIT. IN THIS
! VERSION WE DO NOT HAVE POINT FLAGGING CAPABILITY IN
! 3-D (NOR GRIDFITTING CAPABILITY IN 3-D) HENCE THE
! NEW GRIDS ARE SPECIFIED BY THE USER. SEE GRDFIT.
!
! RDBPTS = true for reading badpoints from file
!
! LOCAL VARIABLES:
! LCHECK = THE LEVEL BEING EXAMINED.
! LFNEW = FINEST GRID TO BE. WILL REPLACE LFINE.
! GLOBAL
! MSTART = START OF VERY COARSEST GRIDS.
! *****************************************************************
!
cpu0 = f_cputime
()
!
!
PRINT*,'REGRID called with LBASE=', lbase,' mxnest=',mxnest
PRINT*,'LFINE =', lfine
!
! yuhe: LCHECK should go from lower to higher so that the grid numbers
! will be set from lower to higher.
!
! LCHECK = MIN0(LFINE,MXNEST-1)
lcheck = lbase
lfnew = lbase
DO i = 1, mxnest
newstl(i) = 0
END DO
time = rnode(20, lstart(lbase))
20 CONTINUE
PRINT*,' lcheck =',lcheck,' lbase= ',lbase
! IF (LCHECK .ge. LBASE) THEN
IF ( lcheck <= MIN0(lfine,mxnest-1) ) THEN
!
! yuhe: Since lstart(lcheck) has not been set, the following statement
! may run into a trouble.
!
! IF (ABS(TIME-RNODE(20, LSTART(LCHECK))).gt..0001) THEN
!
! WRITE(6,100) TIME
!100 FORMAT(41H GRIDS AT DIFFERENT TIMES DURING REGRID ,E12.7)
! STOP
!
! ENDIF
WRITE(6,'('' IN REGRID, CALLING GRDFIT '')')
CALL grdfit
(lbase,lcheck,lfnew,time,rdbpts)
PRINT*,' LBASE,LCHECK,LFNEW,TIME,RDBPTS =', &
lbase,lcheck,lfnew,time,rdbpts, newstl(lcheck+1)
IF (newstl(lcheck+1) /= 0) lfnew = MAX0(lcheck + 1,lfnew)
!
! note: this line is added for testing purpose
!
! LFNEW = MAX0(LCHECK + 1,LFNEW)
! LCHECK = LCHECK - 1
lcheck = lcheck + 1
GO TO 20
END IF
PRINT*,' LBASE,LCHECK,LFNEW,TIME,RDBPTS =', &
lbase,lcheck,lfnew,time,rdbpts
PRINT*,' END OF LEVEL LOOP '
!
! END OF LEVEL LOOP
!
! REMAINING TASKS LEFT IN REGRIDDING:
!
! INTERPOLATE STORAGE FOR THE NEW GRIDS. THE STARTING POINTERS
! FOR EACH LEVEL ARE IN NEWSTL.
!
! first we need to push the old data out temporarily
!
PRINT*,' lfnew ', lfnew
levd = lfnew
DO levn=lfnew,lbase+1,-1
PRINT*,' levn =', levn
IF(lstart(levn) /= 0) THEN
PRINT*,'calling dmplvl '
CALL dmplvl
(levn)
levd = levn
END IF
END DO
!
! now fill the new grids
!
DO levn=lbase+1,lfnew
IF( verbose6 ) WRITE(6,'('' CALLING FILL FOR LEVEL '',I5)') levn
PRINT*,' levd =', levd
CALL fillngrd
( levn, levd )
END DO
!
! clean get rid of disk files for the temp grid dump
! performed by dmplvl
!
PRINT*,' lfnew, lbase+1 ', lfnew, lbase+1
DO levn=lfnew,lbase+1,-1
PRINT*,' levn =',levn, lfnew, lbase+1
mptr = lstart(levn)
CALL cleanf
( mptr )
mptr = newstl(levn)
CALL cleanf
( mptr )
END DO
!
! MERGE DATA STRUCTURES (NEWSTL AND LSTART, LBACK)
! FINISH STORAGE ALLOCATION, RECLAIM SPACE,
! SET UP NEW SOURCE ARRAYS FOR INTERP AND UPDATE
!
PRINT*,'calling join with LBASE, LFNEW=',lbase, lfnew
CALL join
(lbase, lfnew)
!
cpu_regrid = cpu_regrid + f_cputime
() - cpu0
!
RETURN
END SUBROUTINE regrid
!
SUBROUTINE grdfit (lbase,lcheck,lfnew,time,rdbpts) 1,3
!
INCLUDE 'nodal.inc'
INCLUDE 'agricst.inc'
LOGICAL :: rdbpts
INTEGER :: lcheck,prvptr
REAL :: ugrids(11,10)
!
! GRDFIT CALLED BY SETGRD AND REGRID TO ACTUALLY FIT THE NEW GRIDS
! ON EACH LEVEL. LCHECK IS THE LEVEL BEING ERROR ESTIMATED
! SO THAT LCHECK+1 WILL BE THE LEVEL OF THE NEW GRIDS.
!
! IN THIS VERSION WE JUST CALL A USER WRITTEN ROUTINE WHICH RETURNS
! THE NEW GRID LOCATION IN UGRID. UGRID(1-8,*) ARE THE FOUR CORNERS
! OF THE NEW GRID, 9 AND 10 ARE THE BOTTOM AND TOP, 11 IS DZ.
!
lckp1 = lcheck+1
IF(ngrdnew(lcheck) == 0) GO TO 99
CALL rdgrds
(ugrids,lckp1)
!
! SET UP GRID STRUCTURE FOR EACH NEW GRID
!
levnew = lckp1
prvptr=0
DO ig=1,ngrdnew(lckp1-1)
mnew = nodget(dummy)
IF(prvptr /= 0) node(10,prvptr) = mnew
IF(prvptr == 0) newstl(levnew) = mnew
node(12,mnew) = prvptr
DO ip=1,8
rnode(ip,mnew) = ugrids(ip,ig)
END DO
! CALL MOMENT( RNODE(1,MNEW),UGRIDS(1,IG),4,
! * USAGE,0.,0.,HXPOSS(LEVNEW),HYPOSS(LEVNEW) )
rnode(20,mnew) = time
rnode(29,mnew) = ugrids(9,ig)
rnode(30,mnew) = ugrids(10,ig)
rnode(31,mnew) = ugrids(11,ig)
node(4,mnew) = levnew
node(9,mnew) = 1
prvptr = mnew
END DO
!
CALL sethk
(newstl(levnew))
CALL setrot
(newstl(levnew))
!
!
99 RETURN
END SUBROUTINE grdfit
!
SUBROUTINE rdgrds(ug,ln) 1
DIMENSION ug(11,10), tmpg(8)
INCLUDE 'nodal.inc'
INCLUDE 'agricst.inc'
!
! this routine returns the corners for the new grids
! ln is the level for the new grids. ngrdnew is the
! numer of new grids on ln passed through common block
! agri100. ug(1-8) contains the x-y coordinates of the
! corners, 9-10 the bottom and top height and 11 is dz.
!
!
! we will read in the new grid information at present
! xc and yc is the center point, xl and yl the
! axis lengths, angle is the rotation angle, zo and
! zt are the bottom and top of the grid boundaries
!
! these are in coarse-grid normalized coordinates.
!
!
WRITE(6,*) ' regridding'
DO ig=1,ngrdnew(ln-1)
pio2 = 1.570796
angle = -pio2*gangle(ig,ln-1)/90.
cosang = COS(angle)
sinang = -SIN(angle)
xld2 = 0.5*ixln(ig,ln-1)
yld2 = 0.5*jyln(ig,ln-1)
ug(1,ig) = (ixc(ig,ln-1) - xld2*cosang + yld2*sinang -1 ) * &
rnode( 9,mstart)
ug(2,ig) = (jyc(ig,ln-1) - xld2*sinang - yld2*cosang -1 ) * &
rnode( 9,mstart)
ug(3,ig) = (ixc(ig,ln-1) - xld2*cosang - yld2*sinang -1 ) * &
rnode( 9,mstart)
ug(4,ig) = (jyc(ig,ln-1) - xld2*sinang + yld2*cosang -1 ) * &
rnode( 9,mstart)
ug(5,ig) = (ixc(ig,ln-1) + xld2*cosang - yld2*sinang -1 ) * &
rnode( 9,mstart)
ug(6,ig) = (jyc(ig,ln-1) + xld2*sinang + yld2*cosang -1 ) * &
rnode( 9,mstart)
ug(7,ig) = (ixc(ig,ln-1) + xld2*cosang + yld2*sinang -1 ) * &
rnode( 9,mstart)
ug(8,ig) = (jyc(ig,ln-1) + xld2*sinang - yld2*cosang -1 ) * &
rnode( 9,mstart)
!
! here we redo the points such that the point with max x is
! always the first point. this means that the grids will
! always have an angle between 0 and -90 degrees in the interface.
! this does not change the actual grid placement in any way.
!
i1 = 1
IF(ug(3,ig) < ug(i1,ig)) i1 = 3
IF(ug(5,ig) < ug(i1,ig)) i1 = 5
IF(ug(7,ig) < ug(i1,ig)) i1 = 7
!
IF(i1 > 1) THEN
DO i=i1,i1+7
in = i
IF(i > 8) in = i-8
ii = i-i1+1
tmpg(ii) = ug(in,ig)
END DO
DO i=1,8
ug(i,ig) = tmpg(i)
END DO
END IF
!
ug(9,ig) = 0.
ug(10,ig)= rnode(30,mstart)
ug(11,ig)= rnode(31,mstart)
WRITE(6,11)ig,(ug(ii,ig),ii=1,11)
END DO
11 FORMAT(2X,' new grid ',i4,', location information ',3(/,2X,4E12.5) )
RETURN
END SUBROUTINE rdgrds
!
SUBROUTINE join(lbase, lfnew) 1
!
INCLUDE 'nodal.inc'
LOGICAL :: printl
INTEGER :: ptr
!
! JOIN = HOOK UP OLD AND NEW LEVEL DATA STRUCTURES.
! SET PREVLEVEL POINTERS.
! RESET GLOBAL VARIABLE LFINE.
! RETURN FILES FROM OLD GRIDS.
!
!
l = lbase + 1
10 IF (l > lfine) GO TO 40
mptr = lstart(l)
20 IF (mptr == 0) GO TO 30
mold = mptr
mptr = node(10, mptr)
! CALL PUTNOD(MOLD)
GO TO 20
30 CONTINUE
l = l + 1
GO TO 10
40 CONTINUE
!
! MERGE NEWSTL INTO LSTART FOR FINISHING TOUCHES OF GRID STRUCTURE
!
l = lbase + 1
50 IF (l > 10) GO TO 60
lstart(l) = newstl(l)
l = l + 1
GO TO 50
60 CONTINUE
lfine = lfnew
!
! GRID STRUCTURE NOW COMPLETE AGAIN. SAFE TO PRINT, ETC. ASSUMING
! THINGS INITIALIZED TO ZERO IN NODGET.
!
! here we'd set whatever else needs to be set
!
printl = .true.
l = lbase + 1
70 IF (l > lfine) GO TO 105
mptr = newstl(l)
80 IF (mptr == 0) GO TO 90
lm1=l-1
! CALL SRCLST( MPTR,MPTRSC,DXYSRC,NUMBS,LM1,L )
! CALL ZSOURCE( IZSRC(1,1,MPTR),MPTRSC,MPTR,NUMBS,
! * BOUNDI,PRINTL )
mptr = node(10, mptr)
GO TO 80
90 CONTINUE
l = l + 1
GO TO 70
105 CONTINUE
!
! SET THE LBACK POINTER
!
100 l = lbase+1
110 IF (l > lfine) GO TO 130
ptr = lstart(l)
120 CONTINUE
lback(l) = ptr
ptr = node(10,ptr)
IF (ptr /= 0) GO TO 120
l = l + 1
GO TO 110
130 CONTINUE
!
!
RETURN
END SUBROUTINE join
!
SUBROUTINE sethk(msave) 1
INCLUDE 'nodal.inc'
INTEGER :: mptr
INTEGER :: pptr,n,mlevel
REAL :: inner,norm1,norm2,cossqu,h1,h2
! LOGICAL OVRLAP
! ******************************************************************
! SETHK - SET THE H'S, K, AND MAXNUMROW, COL FOR THE GRIDS
! STARTING AT MSAVE.
! INPUT PARAMETER:
! MPTR - STARTING PTR TO GRID TO FIND HROW, HCOL, K, MAXI, MAXJ FOR
!
! NOTE ON ALGORITHM:
! SINCE THE STEP SIZES MAY BE DIFFERENT DIRECTIONS, A SMOOTH CHANGE
! FROM 0 TO PI/2 ORIENTATION ANGLE IS MADE BY COMPUTING THE ANGLE
! BETWEEN MPTR AND AN (OLD) PARENT. CALL THIS ANGLE ALPHA.
! WE THEN FIND WHICH OF THE H'S BY INSISTING THAT IF ALPHA = 0,
! THEN THE NEW H IS JUST H(X OR Y)POSS; IF ALPHA = PI/2, THEN THE
! NEW H IS JUST H(Y OR X)POSS; AND THAT THE CHANGE IS SMOOTH.
! THE CHOICE MADE WAS (NOTE THAT THIS HAS NOTHING TO DUE WITH
! ROTATIONS):
! NEW H1 = H1*COS**2(ALPHA) + H2*SIN**2(ALPHA)
! AND SIMILIARLY FOR H2.
! HERE THE H1 AND H2 ARE THE "APPROPRIATE" CHOICE OF H(X OR Y)POSS
! (BASED ON THE ORIENTATION OF MPTR)
! SPECIAL NOTE:
! IT IS USUALLY THE CASE THAT THE SIDES OF THE RECTANGLE ARE NOT
! AN INTEGRAL MULTIPLE OF THE STEP SIZES. SETHK INCREASES THE H'S
! TO THE SMALLEST H > ORIGINAL H. THIS IS TO KEEP THE METHOD STABLE,
! WHICH WOULD NOT BE TRUE IF WE USED AN H < ORIGINAL H.
! ******************************************************************
mlevel = node(4,msave)
mptr = msave
!
23000 IF(.NOT. (mptr /= 0))GO TO 23001
pptr = lstart(1)
!23002 IF(.NOT. (.NOT. OVRLAP(PPTR,MPTR)))GO TO 23003
! PPTR = NODE(10, PPTR)
! GO TO 23002
!23003 CONTINUE
!
! COMPUTE INNER PRODUCT AND LENGTHS OF SIDES
inner = ( rnode(7,pptr)-rnode(1,pptr) ) *( rnode(7,mptr)- &
rnode(1,mptr) ) +( rnode(8,pptr)-rnode(2,pptr) ) *( rnode(8,mptr) &
-rnode(2,mptr) )
norm1 = ( ( rnode(7,pptr)-rnode(1,pptr) ) ** 2 +( rnode(8, &
pptr)-rnode(2,pptr) ) ** 2 )
norm2 = ( ( rnode(7,mptr)-rnode(1,mptr) ) ** 2 +( rnode(8, &
mptr)-rnode(2,mptr) ) ** 2 )
!
cossqu = (inner/norm1) * (inner/norm2)
!
IF (cossqu < 0.5) GO TO 23004
h1 = hxposs(mlevel)
h2 = hyposs(mlevel)
GO TO 23005
23004 CONTINUE
h1 = hyposs(mlevel)
h2 = hxposs(mlevel)
23005 CONTINUE
!
hx = (h1-h2)*cossqu + h2
hy = (h2-h1)*cossqu + h1
rnode(11,mptr) = possk(mlevel)
!
! NOW, WE ADJUST THE H'S SO THAT N*H = LENGTH OF SIDE FOR SOME
! INTEGER N
!
norm2 = SQRT( (rnode(3,mptr)-rnode(1,mptr))**2 +(rnode(4,mptr &
)-rnode(2,mptr))**2 )
norm1 = SQRT( (rnode(7,mptr)-rnode(1,mptr))**2 +(rnode(8,mptr &
)-rnode(2,mptr))**2 )
!
n = IFIX(norm1/hx+.01 + 1)
!
! SET N,M ODD FOR ERREST (2DX GRID OVERLY)
!
! IF(MOD(N,2) .NE. 0) N=N-1
rnode(9,mptr) = norm1 / FLOAT(n-1)
node(5,mptr) = n
!
n = IFIX(norm2/hy+.01 + 1)
! IF(MOD(N,2) .NE. 0) N=N-1
rnode(10,mptr) = norm2 / FLOAT(n-1)
node(6,mptr) = n
!
! NOW SET NUMBER OF LAYERS FOR THIS GRID
!
node(14,mptr) = nint( (rnode(30,mptr)-rnode(29,mptr)) &
/rnode(31,mptr) ) + 1
!
mptr = node(10,mptr)
GO TO 23000
23001 CONTINUE
RETURN
END SUBROUTINE sethk
!