|
filpatch_geo.f.html |
|
|
Source file: filpatch_geo.f
|
|
Directory: /home/rjl/git/rjleveque/clawpack-4.x/geoclaw/2d/lib
|
|
Converted: Sun May 15 2011 at 19:15:40
using clawcode2html
|
|
This documentation file will
not reflect any later changes in the source file.
|
c
c ---------------------------------------------------------------
c
recursive subroutine filrecur(level,nvar,valbig,aux,naux,
1 time,mitot,mjtot,
2 nrowst,ncolst,ilo,ihi,jlo,jhi)
c :::::::::::::::::::::::::::: FILPATCH :::::::::::::::::::::::::;
c
c fill the portion of valbig from rows nrowst
c and cols ncolst
c the patch can also be described by the corners (xlp,ybp) by (xrp,ytp).
c vals are needed at time time, and level level,
c
c first fill with values obtainable from the level level
c grids. if any left unfilled, then enlarge remaining rectangle of
c unfilled values by 1 (for later linear interp), and recusively
c obtain the remaining values from coarser levels.
c
c :::::::::::::::::::::::::::::::::::::::;:::::::::::::::::::::::;
use geoclaw_module
implicit double precision (a-h,o-z)
include "call.i"
logical set, sticksout
dimension valbig(mitot,mjtot,nvar), aux(mitot,mjtot,naux)
c use stack-based scratch arrays instead of alloc, since dont really
c need to save beyond these routines, and to allow dynamic memory resizing
c
c use 1d scratch arrays that are potentially the same size as
c current grid, since may not coarsen.
c need to make it 1d instead of 2 and do own indexing, since
c when pass it in to subroutines they treat it as having different
c dimensions than the max size need to allocate here
c
dimension valcrse((ihi-ilo+2)*(jhi-jlo+2)*nvar) ! NB this is a 1D array
dimension auxcrse((ihi-ilo+2)*(jhi-jlo+2)*naux) ! the +2 is to expand on coarse grid to enclose fine
c
dimension flaguse(ihi-ilo+1,jhi-jlo+1)
logical reloop
logical fineflag((ihi-ilo+2)*(jhi-jlo+2)*nvar)
double precision finemass((ihi-ilo+2)*(jhi-jlo+2))
double precision etacrse((ihi-ilo+2)*(jhi-jlo+2))
double precision velmax((ihi-ilo+2)*(jhi-jlo+2))
double precision velmin((ihi-ilo+2)*(jhi-jlo+2))
double precision slopex((ihi-ilo+2)*(jhi-jlo+2))
double precision slopey((ihi-ilo+2)*(jhi-jlo+2))
integer icount((ihi-ilo+2)*(jhi-jlo+2))
ivalc(i,j,ivar) = i + nrowc*(j - 1)
& + nrowc*ncolc*(ivar-1)
icrse(i,j) = i + nrowc*(j-1)
c
c # index into first component of aux = topo:
iauxc(i,j) = i + nrowc*(j-1)
sticksout(iplo,iphi,jplo,jphi) =
& (iplo .lt. 0 .or. jplo .lt. 0 .or.
& iphi .ge. iregsz(levc) .or. jphi .ge. jregsz(levc))
!-- write(*,*)" entering filrecur with level ",level
!-- write(*,*)" and patch indices ilo,ihi,jlo,jhi ",
!-- & ilo,ihi,jlo,jhi
c write(*,*)" in filrecur for level ",level,mitot,mjtot
c
c We begin by filling values for grids at level level. If all values can be
c filled in this way, we return;
nrowp = ihi - ilo + 1
ncolp = jhi - jlo + 1
c locuse = igetsp(nrowp*ncolp)
hxf = hxposs(level)
hyf = hyposs(level)
xlp = xlower + ilo*hxf
xrp = xlower + (ihi+1)*hxf
ybp = ylower + jlo*hyf
ytp = ylower + (jhi+1)*hyf
call intfil
& (valbig,mitot,mjtot,time,flaguse,nrowst,ncolst,
& ilo,ihi,jlo,jhi,level,nvar,naux)
c & (valbig,mitot,mjtot,time,locuse,nrowst,ncolst,
c
c Trimbd returns set = true if all of the entries are filled (=1.).
c set = false, otherwise. If set = true, then no other levels are
c are required to interpolate, and we return.
c
c Note that the used array is filled entirely in intfil, i.e. the
c marking done there also takes into account the points filled by
c the boundary conditions. bc2amr will be called later, after all 4
c boundary pieces filled.
c call trimbd(alloc(locuse),nrowp,ncolp,set,il,ir,jb,jt)
call trimbd(flaguse,nrowp,ncolp,set,il,ir,jb,jt)
if (set) go to 90 ! all done except for bcs
c
c otherwise make recursive calls to coarser levels to fill remaining unset points
c
if (level .eq. 1) then
write(outunit,*)" error in filrecur - level 1 not set"
write(outunit,900) nrowst,ncolst
write(*,*)" error in filrecur - level 1 not set"
write(*,*)" should not need more recursion "
write(*,*)" to set patch boundaries"
write(*,900) nrowst,ncolst
900 format("start at row: ",i4," col ",i4)
stop
endif
c set = false. we will have to interpolate some values from coarser
c levels. We begin by initializing the level level arrays, so that we can use
c purely recursive formulation for interpolating.
levc = level - 1
hxc = hxposs(levc)
hyc = hyposs(levc)
isl = il + ilo - 1
isr = ir + ilo - 1
jsb = jb + jlo - 1
jst = jt + jlo - 1
c
c coarsen
lratiox = intratx(levc)
lratioy = intraty(levc)
iplo = (isl-lratiox +nghost*lratiox)/lratiox - nghost
jplo = (jsb-lratioy +nghost*lratioy)/lratioy - nghost
iphi = (isr+lratiox )/lratiox
jphi = (jst+lratioy )/lratioy
xlc = xlower + iplo*hxc
ybc = ylower + jplo*hyc
xrc = xlower + (iphi+1)*hxc
ytc = ylower + (jphi+1)*hyc
nrowc = iphi - iplo + 1
ncolc = jphi - jplo + 1
ntot = nrowc*ncolc*(nvar+naux)
c write(*,876) nrowc,ncolc, ihi-ilo+2,jhi-jlo+2
876 format(" needed coarse grid size ",2i5," allocated ",2i5)
if (nrowc .gt. ihi-ilo+2 .or. ncolc .gt. jhi-jlo+2) then
write(*,*)" did not make big enough work space in filrecur "
write(*,*)" need coarse space with nrowc,ncolc ",nrowc,ncolc
write(*,*)" coarser level is ",levc," nghost ",nghost
write(*,*)" with ratios lratiox lratioy ",lratiox,lratioy
write(*,*)" made space for ilo,ihi,jlo,jhi ",ilo,ihi,jlo,jhi
write(*,*)" isl,isr,jsb,jst ",isl,isr,jsb,jst
write(*,*)"iplo,iphi,jplo,jphi ",iplo,iphi,jplo,jphi
write(*,*)" orig il,ir,jb,jt ",il,ir,jb,jt
write(*,*)"filpatch called with mitot,mjtot ",mitot,mjtot
call outtre(1,.false.,nvar,naux)
stop
endif
c loccrse = igetsp(ntot)
c locauxc = loccrse + nrowc*ncolc*nvar
if (naux.gt.0) then
maxmx = nrowc - 2*nghost
mx = maxmx
maxmy = ncolc - 2*nghost
my = maxmy
xl = xlc + nghost*hxc
yb = ybc + nghost*hyc
call setaux(maxmx,maxmy,nghost,mx,my,xl,yb,hxc,hyc,
& naux,auxcrse)
c & naux,alloc(locauxc))
endif
if ((xperdom .or. (yperdom .or. spheredom)) .and.
& sticksout(iplo,iphi,jplo,jphi)) then
call prefilrecur(levc,nvar,valcrse,auxcrse,
1 naux,time,nrowc,ncolc,1,1,
2 iplo,iphi,jplo,jphi)
else
c call filpatch2(levc,nvar,alloc(loccrse),alloc(locauxc),naux,
call filrecur(levc,nvar,valcrse,auxcrse,naux,
1 time,nrowc,ncolc,1,1,
2 iplo,iphi,jplo,jphi)
endif
c interpolate back up
20 continue
* !loop through coarse cells determining intepolation slopes
* !these will be saved for fine grid loop
* !prevents finding the same slope possibly lratiox*lratioy times
* !all fine gid depths will be found before any momentum
reloop = .false.
toldry= drytolerance
do ic = 2, nrowc-1
do jc = 2, ncolc-1
icount(icrse(ic,jc)) = 0
finemass(icrse(ic,jc)) = 0.d0
do ivar=1,nvar
fineflag(ivalc(ic,jc,ivar)) = .false.
enddo
* !find interpolation slope for eta = q(:,1)+ aux(:,1)
do i=-1,1
etacrse(icrse(ic+i,jc)) = valcrse(ivalc(ic+i,jc,1))
& + auxcrse(iauxc(ic+i,jc))
if (valcrse(ivalc(ic+i,jc,1)).lt.toldry) then
etacrse(icrse(ic+i,jc)) = sealevel
endif
enddo
s1 = etacrse(icrse(ic,jc))- etacrse(icrse(ic-1,jc))
s2 = etacrse(icrse(ic+1,jc))- etacrse(icrse(ic,jc))
if (s1*s2.le.0) then
slopex(icrse(ic,jc))= 0.d0
else
slopex(icrse(ic,jc))=dmin1(dabs(s1),dabs(s2))*dsign(1.d0,
& etacrse(icrse(ic+1,jc))- etacrse(icrse(ic-1,jc)))
endif
do j=-1,1
etacrse(icrse(ic,jc+j)) = valcrse(ivalc(ic,jc+j,1))
& + auxcrse(iauxc(ic,jc+j))
if (valcrse(ivalc(ic,jc+j,1)).lt.toldry) then
etacrse(icrse(ic,jc+j)) = sealevel
endif
enddo
s1 = etacrse(icrse(ic,jc))- etacrse(icrse(ic,jc-1))
s2 = etacrse(icrse(ic,jc+1))- etacrse(icrse(ic,jc))
if (s1*s2.le.0) then
slopey(icrse(ic,jc))= 0.d0
else
slopey(icrse(ic,jc))=dmin1(dabs(s1),dabs(s2))*dsign(1.d0,
& etacrse(icrse(ic,jc+1))- etacrse(icrse(ic,jc-1)))
endif
end do
end do
* !loop through patch: note this includes multiple coarse cells
do iff = 1,nrowp
ic = 2 + (iff - (isl - ilo) - 1)/lratiox
eta1 = (-0.5d0+dble(mod(iff-1,lratiox)))/dble(lratiox)
do jf = 1,ncolp
jc = 2 + (jf - (jsb - jlo) - 1)/lratioy
eta2 = (-0.5d0+dble(mod(jf -1,lratioy)))/dble(lratioy)
cc = icrse(ic,jc)
c flag = alloc(iadflag(iff,jf))
flag = flaguse(iff,jf)
if (flag .eq. 0.0) then
* !interp. from coarse cells to fine grid to find eta
icount(icrse(ic,jc)) = icount(icrse(ic,jc)) + 1
etafine = etacrse(icrse(ic,jc))
& + eta1*slopex(icrse(ic,jc))+eta2*slopey(icrse(ic,jc))
hfine = max(etafine - aux(iff+nrowst-1,jf+ncolst-1,1),
& 0.d0)
valbig(iff+nrowst-1,jf+ncolst-1,1) = hfine
finemass(icrse(ic,jc)) = finemass(icrse(ic,jc)) +
& valbig(iff+nrowst-1,jf+ncolst-1,1)
if (valbig(iff+nrowst-1,jf+ncolst-1,1).lt.toldry) then
fineflag(ivalc(ic,jc,1)) = .true.
reloop = .true.
endif
endif
enddo
enddo
c ! determine momentum
do ivar = 2,nvar
* !find interpolation slope for momentum = q(:,ivar)
do ic = 2, nrowc-1
do jc = 2, ncolc-1
s1 = valcrse(ivalc(ic,jc,ivar))
& - valcrse(ivalc(ic-1,jc,ivar))
s2 = valcrse(ivalc(ic+1,jc,ivar))
& - valcrse(ivalc(ic,jc,ivar))
if (s1*s2.le.0) then
slopex(icrse(ic,jc))= 0.d0
else
slopex(icrse(ic,jc))=dmin1(dabs(s1),dabs(s2))
& *dsign(1.d0, valcrse(ivalc(ic+1,jc,ivar))
& - valcrse(ivalc(ic-1,jc,ivar)))
endif
s1 = valcrse(ivalc(ic,jc,ivar))
& - valcrse(ivalc(ic,jc-1,ivar))
s2 = valcrse(ivalc(ic,jc+1,ivar))
& - valcrse(ivalc(ic,jc,ivar))
if (s1*s2.le.0) then
slopey(icrse(ic,jc))= 0.d0
else
slopey(icrse(ic,jc))=dmin1(dabs(s1),dabs(s2))
& *dsign(1.d0, valcrse(ivalc(ic,jc+1,ivar))
& - valcrse(ivalc(ic,jc-1,ivar)))
endif
if (valcrse(ivalc(ic,jc,1)).gt.toldry) then
velmax(icrse(ic,jc)) = valcrse(ivalc(ic,jc,ivar))
& /valcrse(ivalc(ic,jc,1))
velmin(icrse(ic,jc)) = valcrse(ivalc(ic,jc,ivar))
& /valcrse(ivalc(ic,jc,1))
else
velmax(icrse(ic,jc)) = 0.d0
velmin(icrse(ic,jc)) = 0.d0
endif
* !look for bounds on velocity to avoid generating new extrema
* !necessary since interpolating momentum linearly
* !yet depth is not interpolated linearly
do ii = -1,1,2
if (valcrse(ivalc(ic+ii,jc,1)).gt.toldry) then
velmax(icrse(ic,jc)) = max(velmax(icrse(ic,jc))
& ,valcrse(ivalc(ic+ii,jc,ivar))
& /valcrse(ivalc(ic+ii,jc,1)))
velmin(icrse(ic,jc)) = min(velmin(icrse(ic,jc))
& ,valcrse(ivalc(ic+ii,jc,ivar))
& /valcrse(ivalc(ic+ii,jc,1)))
endif
if (valcrse(ivalc(ic,jc+ii,1)).gt.toldry) then
velmax(icrse(ic,jc)) = max(velmax(icrse(ic,jc))
& ,valcrse(ivalc(ic,jc+ii,ivar))
& /valcrse(ivalc(ic,jc+ii,1)))
velmin(icrse(ic,jc)) = min(velmin(icrse(ic,jc))
& ,valcrse(ivalc(ic,jc+ii,ivar))
& /valcrse(ivalc(ic,jc+ii,1)))
endif
enddo
end do
end do
* !determine momentum in fine cells
do iff = 1,nrowp
ic = 2 + (iff - (isl - ilo) - 1)/lratiox
eta1 = (-0.5d0+dble(mod(iff-1,lratiox)))/dble(lratiox)
do jf = 1,ncolp
jc = 2 + (jf - (jsb - jlo) - 1)/lratioy
eta2 = (-0.5d0+dble(mod(jf -1,lratioy)))/dble(lratioy)
flag = flaguse(iff,jf)
if (flag .eq. 0.0) then
if (.not.(fineflag(ivalc(ic,jc,1)))) then
* !this is a normal wet cell. intepolate normally
hvf = valcrse(ivalc(ic,jc,ivar))
& + eta1*slopex(icrse(ic,jc))
& + eta2*slopey(icrse(ic,jc))
vf = hvf/valbig(iff+nrowst-1,jf+ncolst-1,1)
if (vf.lt.velmin(icrse(ic,jc)).or.
& vf.gt.velmax(icrse(ic,jc))) then
fineflag(ivalc(ic,jc,ivar))=.true.
reloop = .true.
else
valbig(iff+nrowst-1,jf+ncolst-1,ivar) = hvf
endif
endif
endif
enddo
enddo
* !loop again and reset momentum to conserve momentum
* !in the case of gained momentum, or if velocity bounds violated
if (reloop) then
do iff = 1,nrowp
ic = 2 + (iff - (isl - ilo) - 1)/lratiox
eta1 =(-0.5d0+dble(mod(iff-1,lratiox)))/dble(lratiox)
do jf = 1,ncolp
jc = 2 + (jf - (jsb - jlo) - 1)/lratioy
eta2 = (-0.5d0+dble(mod(jf -1,lratioy)))/dble(lratioy)
flag = flaguse(iff,jf)
if (flag.eq.0.0) then
if (fineflag(ivalc(ic,jc,1))
& .or.fineflag(ivalc(ic,jc,ivar))) then
if (finemass(icrse(ic,jc)).gt.toldry) then
hcrse = valcrse(ivalc(ic,jc,1))
hcnt = dble(icount(icrse(ic,jc)))
hfineave = finemass(icrse(ic,jc))/hcnt
dividemass = max(hcrse,hfineave)
hfine = valbig(iff+nrowst-1,jf+ncolst-1,1)
Vnew = valcrse(ivalc(ic,jc,ivar))/dividemass
valbig(iff+nrowst-1,jf+ncolst-1,ivar) =
& Vnew*valbig(iff+nrowst-1,jf+ncolst-1,1)
else
valbig(iff+nrowst-1,jf+ncolst-1,ivar)=0.d0
endif
endif
endif
enddo
enddo
endif
enddo
c call reclam(loccrse,ntot)
90 continue
c
c set bcs, whether or not recursive calls needed. set any part of patch that stuck out
c
call bc2amr(valbig,aux,mitot,mjtot,nvar,naux,
1 hxf,hyf,level,time,
2 xlp,xrp,ybp,ytp,
3 xlower,ylower,xupper,yupper,
4 xperdom,yperdom,spheredom)
c call reclam(locuse,nrowp*ncolp)
return
end