C C AUTHOR: ALFIO BORZI' C INSTITUT FÜR MATHEMATIK C UND WISSENSCHAFTLICHES RECHNEN C KARL-FRANZENS-UNIVRSITÄT GRAZ C HEINRICHSTR. 36, A-8010 GRAZ C AUSTRIA C E-MAIL: ALFIO.BORZI@UNI-GRAZ.AT C C DATE: 2004 C PROJECT: FAS MULTIGRID FOR REACTION-DIFFUSION OPTIMALITY SYSTEMS C OPEN-LOOP CONTROL AND RECEDING HORIZON TECHNIQUES C LANGUAGE: FORTRAN 77 C CONSTRAINTS: NONE - PUBLIC DOMAIN SOFTWARE C C FOR THE PRESENTATION OF THIS CODE AND FURTHER REFERENCES SEE: C ALFIO BORZI' C Space-time multigrid methods for solving unsteady C optimal control problems C C appear in the proceedings of the C C Second Sandia Workshop on PDE-Constrained Optimization: C Toward Real-time and Online PDE-constrained Optimization C May 19-21, 2004 C Bishop's Lodge, Santa Fe, New Mexico C C Workshop organizing committee: C C Larry Biegler, Omar Ghattas, Matthias Heinkenschloss, C David Keyes, Bart van Bloemen Waanders. C C program santafe implicit real*8 (a-h,o-z) c c description: min J(u,f), e(u,f)=0. c c constraint: c Parabolic (2+1)-dimensional FAS Multigrid solver (with FDM) c Dirichlet b.c. + initial condition, c c Optimal control problem: c C -Ut + GNL(U) + sigma * DELTA(U) = F C C min J(U,F):= alfa ||U-Zd||^2/2 + beta ||U(T)-ZT||^2/2 + rnu ||F||^2/2 C (distributed control) C C with Receding horizon techniques ..... C c c c running indeces for space and time: i->x, j->y, n->t. c c q(nst(i,j,le)+n)=var(x,y,t) c q(nst(i,j,le+ne)+n)=rhs(var) c c le=1,ne - le index of the equation; ne number of equations c c The storage required is c d d c 2*ne*n*2 /(2 - 1) c c where c ne is the number of equations c n the number of finest grid points c d dimensions of the domain c c c Residuals are transferred by full weighting c c meaning of some flags c c iwrite 1 dump the solution (for debugging purpose) c 2 don't dump the solution c nvw 1 v cycle c 2 w cycle c c x0 - x1 domain of integration in x c y0 - y1 domain of integration in y c t0 - t1 domain of integration in t c nx0 # of meshes of the coarsest grid in c x direction c ny0 # of meshes of the coarsest grid in c y direction c nt0 # of meshes of the coarsest grid in c t (time) direction c m # of level used c ncycle # of cycle for each MG cycle c nrf # of sweeps before CGC c nrc # of sweeps after CGC c isor = 1 performs max relax sweeps starting from level c 'ksor' c itstl= 1 TS-CGS relax; itstl= 2 TL-CGS relax c nwin number of time windows of size t1-t0 for receding horizon c common/qarr/q(50000000) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) common/sor/isor,nmax,ksor,itstl common/grid/x0,x1,y0,y1,t0,t1 common/twindow/t00 common/tol/tol common/albe/sigma common/cweight/rnu,alfa,beta common/horiz/nwin c external fsol,fqin,frhs,fqb save c qdim=50000000 c open(unit=14,status='unknown',file='out.dat') open(unit=17,status='unknown',file='midsol.dat',access='append') open(unit=20,status='unknown',file='santafe.dat') c pi=acos(-1.0d+0) t00=0.0d0 c ne=2 read(20,*) x0,x1,y0,y1,t0,t1 read(20,*) nx0,ny0,nt0,m read(20,*) ncycle,nrc,nrf,ncrst,nvw read(20,*) tol,wmax read(20,*) isor,nmax,ksor,itstl read(20,*) sigma read(20,*) rnu,alfa,beta read(20,*) nwin close(20) t00=t0 c write(14,80) write(14,99) write(14,100) nx0,ny0,nt0 write(14,105) m,ncycle write(14,106) nrf write(14,107) nrc write(14,110) x0,x1,y0,y1,t0,t1 c call cpu_time(time1) c call multig(nx0,ny0,nt0,x0,y0,t0,x1,y1,t1,m,qdim,wmax,fsol, * frhs,fqin,fqb,ne,ncycle,nrc,nrf,ncrst,nvw) call cpu_time(time2) write(*,*)' Total CPU time (s) ',time2-time1 write(14,175) time2-time1 c 80 format(19x,44('*'),/,19x,'*',42x,'*',/,19x,'* ','Multigrid sol', * 'ution of Poisson equation',' *',/,19x,'*',42x,'*',/, * 19x,44('*'),///) 99 format(' coarsest grid:') 100 format(' # of x-intervals',i5, * ' # of y-intervals',i5,' # of t-intervals',i5) 105 format(' # of levels used =',i3,' # of mgm-cycles per level =' * ,i3) 106 format(' # of sweeps before coarse grid correction =',i3) 107 format(' # of sweeps after coarse grid correction =',i3) 110 format(' domain of integration : x0=',f9.3,' x1=',f9.3, * /,29x,'y0=',f9.3,' y1=',f9.3, * /,29x,'t0=',f9.3,' t1=',f9.3) 175 format(' total cpu time = ',f12.2,' secs') stop end c------------------------------------------------ real*8 function gnl(u) implicit real*8 (a-h,o-z) c c---- the nonlinear function c gnl=exp(u) return end c------------------------------------------------ real*8 function d1gnl(u) implicit real*8 (a-h,o-z) c c---- the 1st derivative of the nonlinear function c d1gnl=exp(u) return end c------------------------------------------------ real*8 function d2gnl(u) implicit real*8 (a-h,o-z) c c---- the 2nd derivative of the nonlinear function c d2gnl=exp(u) return end c------------------------------------------------ real*8 function zf(x,y,t) implicit real*8 (a-h,o-z) common/cweight/rnu,alfa,beta pi=acos(-1.0d+0) pi2=pi*pi pi4=pi2*pi2 c c---- the objective function c zf=(1.+t)*(x-x**2)*(y-y**2)*cos(4.0*pi*t) return end c------------------------------------------------ real*8 function fsol(x,y,t,i) implicit real*8 (a-h,o-z) common/cweight/rnu,alfa,beta c c---- the analytic solution (?) c pi=acos(-1.0d+0) pi2=pi*pi if(i.eq.1) then fsol=(1.+t)*(x-x**2)*(y-y**2)*cos(4.0*pi*t) else fsol=0.0 endif return end c------------------------------------------------ function fqb(x,y,t,i) implicit real*8 (a-h,o-z) if(i.eq.1) then fqb=0.0 else fqb=0.0 endif return end c------------------------------------------------ real*8 function fqin(x,y,t,i) implicit real*8 (a-h,o-z) external fsol if(i.eq.1) then fqin=fsol(x,y,t,1) else fqin=fsol(x,y,t,2) endif return end c------------------------------------------------ function frhs(x,y,t,i) implicit real*8 (a-h,o-z) pi=acos(-1.0d+0) if(i.eq.1) then frhs=0.0 else frhs=0.0 endif return end c------------------------------------------------ subroutine crsres(k,ne) implicit real*8 (a-h,o-z) common/qarr/q(50000000) common/pntrs/ist(129,129),is(129,129,8), X isp(129,129),isf(129,129,8) common/albe/sigma common/cweight/rnu,alfa,beta external zf,gnl,d1gnl c n2=2*ne do 2 l=1,n2 call key(k,l,ist,imax,jmax,nmax,x0,y0,t0,hx,hy,ht) do 1 i=1,imax do 1 j=1,jmax 1 is(i,j,l)=ist(i,j) 2 continue c imax1=imax-1 jmax1=jmax-1 nmax1=nmax-1 c coe1=sigma*ht/(hx*hx) coe2=sigma*ht/(hy*hy) coe3=1.0 coe=2.0d0*(coe1+coe2)+coe3 c c* state equation le=1 do 20 i=2,imax1 do 20 j=2,jmax1 iom=is(i-1,j,le) io=is(i,j,le) iop=is(i+1,j,le) jom=is(i,j-1,le) jop=is(i,j+1,le) ifo=is(i,j,ne+le) c x=(i-1)*hx y=(j-1)*hy do 40 n=2,nmax nm=n-1 t=t0+(n-1)*ht ax=q(iom+n)-2.0d0*q(io+n)+q(iop+n) ay=q(jom+n)-2.0d0*q(io+n)+q(jop+n) at=q(io+nm)-q(io+n) a1=q(ifo+n)+(coe1*ax+coe2*ay+coe3*at) a1=a1+ht*gnl(q(io+n))-ht*q(is(i,j,2)+n)/rnu q(ifo+n)=a1 40 continue 20 continue c c* adjoint equation le=2 do 30 i=2,imax1 do 30 j=2,jmax1 iom=is(i-1,j,le) io=is(i,j,le) iop=is(i+1,j,le) jom=is(i,j-1,le) jop=is(i,j+1,le) ifo=is(i,j,ne+le) x=(i-1)*hx y=(j-1)*hy do 30 na=2,nmax1 n=nmax-na+1 nm=n+1 t=t0+(n-1)*ht ax=q(iom+n)-2.0d0*q(io+n)+q(iop+n) ay=q(jom+n)-2.0d0*q(io+n)+q(jop+n) at=q(io+nm)-q(io+n) a1=q(ifo+n)+(coe1*ax+coe2*ay+coe3*at) yvar=q(is(i,j,1)+n) a1=a1+ht*d1gnl(yvar)*q(io+n)+ht*alfa*(yvar-zf(x,y,t)) q(ifo+n)=a1 30 continue return end c------------------------------------------------ subroutine fas(fs,lev,mm,wu,ne, * ncycle,nrc,nrf,ncrst,nvw) implicit real*8 (a-h,o-z) c c fix algorithm c dimension error(260),work(260) dimension err(12),ivw(10) common/qarr/q(50000000) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) common/tol/tol common/cweight/rnu,alfa,beta c external fs c do 1 n=1,12 1 err(n)=0.0d0 write(14,170) c m=mm lwork=lev do 5 k=1,m 5 ivw(k)=0 errmx=1.0d0 c c* cycle do 100 nc=1,ncycle k=lev errold=errmx c 10 do 20 ir=1,nrf call relax(k,err,errm,ne) c wu=wu+4.**(k-lwork) write(14,190) k,wu,(err(i),i=1,ne) 20 continue if(lev.eq.1) goto 80 c c coarse grid correction c ---------------------- c H H h h h H H h c r = I (f - L u ) + L (I u ) c h h c call rescal(k,k-1,ne) call putu(k,k-1,ne) call crsres(k-1,ne) c ivw(k)=ivw(k)+1 k=k-1 if(k.ne.1) goto 10 c c make now ncrst sweeps on the coarsest grid c do 42 n=1,ncrst call relax(k,err,errm,ne) write(14,190) k,wu,(err(i),i=1,ne) 42 continue if(ivw(lev).ne.1) goto 44 44 write(14,190) k,wu,(err(i),i=1,ne) c 45 k=k+1 c c transfer to finer grid and addition c ----------------------------------- c c h h h H h H c u = u + I (u - I u ) c H H call subtrt(k-1,k,ne) call intadd(k-1,k,ne) c do 60 ir=1,nrc call relax(k,err,errm,ne) wu=wu+4.0d0**(k-lwork) write(14,190) k,wu,(err(i),i=1,ne) 60 continue c if(k.ne.2) goto 65 if(ivw(k).ne.1) goto 10 ivw(k)=0 if(k.eq.lev) goto 80 goto 45 65 if(k.eq.lev) goto 80 if(ivw(k).ne.nvw) goto 10 ivw(k)=0 goto 45 c 80 work(nc)=wu c error(nc)=err(1)+err(2) write(14,200) nc if(k.eq.lev) errmx=(err(1)+err(2)) write(14,130) nc, errmx/errold write(*,130) nc, errmx/errold if(errmx.lt.tol) goto 150 100 continue c 150 if(ncycle.le.2) return ncf=nc do 110 nc=2,ncf tw=work(nc)-work(nc-1) ta=work(nc)-work(1) ew=error(nc)/error(nc-1) if(ew.lt.1e-20)ew=1e-20 ea=error(nc)/error(1) if(ea.lt.1e-20)ea=1e-20 efw=ew**(1./tw) efa=ea**(1./ta) write(14,210) nc,ew,ea write(*,210) nc,ew,ea 110 continue c 130 format(10x,'nc =',i4,15x,'obs. rho =',f8.4) 170 format(' level',2x,'work',18x,'residual norms (i,b)') 190 format(i2,2x,f6.2,2x,2(1pe8.1)) 200 format(1x,24(1h-),'end cycle no.',i3) 210 format(14x,'cycle no.',i3,5x,' cycle eff.',f6.3,5x,'acc.eff.' 1,f6.3) return end c------------------------------------------------ subroutine grdfn(k,l,imax,jmax,nmax,x0a,y0a,t0a,hhx,hhy,hht) implicit real*8 (a-h,o-z) common/grd/nst(20,10),imx(20),jmx(20),nmx(20), * hx(20),hy(20),ht(20),x0,y0,t0 common/iq/iq nst(k,l)=iq imx(k)=imax jmx(k)=jmax nmx(k)=nmax x0=x0a y0=y0a t0=t0a hx(k)=hhx hy(k)=hhy ht(k)=hht iq=iq+imax*jmax*nmax return end c----------------------------------------------------------------- subroutine intadd(km,k,ne) implicit real*8 (a-h,o-z) c common/qarr/q(50000000) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) do 30 le=1,ne call key(k,le,ist,iif,jjf,nnf,x0,y0,t0,hxf,hyf,htf) call key(km,le,ism,iic,jjc,nnc,x0,y0,t0,hxc,hyc,htc) c c no time coarsening c c c side i=1 c ic=1 if=2*ic-1 do 55 jc=2,jjc jf=2*jc-1 ifq=ist(if,jf) jfqm=ist(if,jf-1) icq=ism(ic,jc) jcqm=ism(ic,jc-1) do 55 nc=2,nnc nf=nc c a=.50d0*(q(icq+nc)+q(jcqm+nc)) q(ifq+nf)=q(ifq+nf)+q(icq+nc) q(jfqm+nf)=q(jfqm+nf)+a 55 continue c c edge i=1,j=1 ic=1 if=1 jc=1 jf=1 c corner i=1,j=1,n=1 ifq=ist(if,jf) icq=ism(ic,jc) q(ifq+1)=q(ifq+1)+q(icq+1) c do 56 nc=2,nnc nf=nc c q(ifq+nf)=q(ifq+nf)+q(icq+nc) 56 continue c side j=1 jc=1 jf=2*jc-1 do 510 ic=2,iic if=2*ic-1 ifq=ist(if,jf) ifqm=ist(if-1,jf) icq=ism(ic,jc) icqm=ism(ic-1,jc) do 510 nc=2,nnc nf=nc c am=.50d0*(q(icqm+nc)+q(icq+nc)) q(ifq+nf)=q(ifq+nf)+q(icq+nc) q(ifqm+nf)=q(ifqm+nf)+am 510 continue c c edge j=1,n=1 jc=1 jf=1 nc=1 nf=1 do 511 ic=2,iic if=2*ic-1 ifq=ist(if,jf) ifqm=ist(if-1,jf) icq=ism(ic,jc) icqm=ism(ic-1,jc) c am=.50d0*(q(icqm+nc)+q(icq+nc)) q(ifq+nf)=q(ifq+nf)+q(icq+nc) q(ifqm+nf)=q(ifqm+nf)+am 511 continue c side n=1 nc=1 nf=1 do 515 ic=2,iic if=2*ic-1 do 515 jc=2,jjc jf=2*jc-1 ifq=ist(if,jf) ifqm=ist(if-1,jf) jfqm=ist(if,jf-1) jfqmm=ist(if-1,jf-2) ijfqm=ist(if-1,jf-1) icq=ism(ic,jc) icqm=ism(ic-1,jc) jcqm=ism(ic,jc-1) ijcqm=ism(ic-1,jc-1) c a=.50d0*(q(icq+nc)+q(jcqm+nc)) q(ifq+nf)=q(ifq+nf)+q(icq+nc) q(jfqm+nf)=q(jfqm+nf)+a a=.50d0*(q(icqm+nc)+q(icq+nc)) am=.250d0*(q(icq+nc)+q(icqm+nc) X +q(jcqm+nc)+q(ijcqm+nc)) q(ifqm+nf)=q(ifqm+nf)+a q(ijfqm+nf)=q(ijfqm+nf)+am 515 continue c edge n=1,i=1 nc=1 nf=1 ic=1 if=1 do 516 jc=2,jjc jf=2*jc-1 ifq=ist(if,jf) jfqm=ist(if,jf-1) icq=ism(ic,jc) jcqm=ism(ic,jc-1) a=.50d0*(q(icq+nc)+q(jcqm+nc)) q(ifq+nf)=q(ifq+nf)+q(icq+nc) q(jfqm+nf)=q(jfqm+nf)+a 516 continue c internal points and outer sides do 520 ic=2,iic if=2*ic-1 do 520 jc=2,jjc jf=2*jc-1 ifq=ist(if,jf) ifqm=ist(if-1,jf) jfqm=ist(if,jf-1) jfqmm=ist(if-1,jf-2) ijfqm=ist(if-1,jf-1) icq=ism(ic,jc) icqm=ism(ic-1,jc) jcqm=ism(ic,jc-1) ijcqm=ism(ic-1,jc-1) do 520 nc=2,nnc nf=nc c a=.50d0*(q(icq+nc)+q(jcqm+nc)) q(ifq+nf)=q(ifq+nf)+q(icq+nc) q(jfqm+nf)=q(jfqm+nf)+a a=.50d0*(q(icqm+nc)+q(icq+nc)) am=.250d0*(q(icqm+nc)+q(icq+nc)+q(jcqm+nc)+q(ijcqm+nc)) q(ifqm+nf)=q(ifqm+nf)+a q(ijfqm+nf)=q(ijfqm+nf)+am 520 continue 30 continue return end c------------------------------------------------ subroutine key(k,l,ist,imax,jmax,nmax,x0a,y0a,t0a,hhx,hhy,hht) implicit real*8 (a-h,o-z) common/grd/nst(20,10),imx(20),jmx(20),nmx(20), * hx(20),hy(20),ht(20),x0,y0,t0 common/twindow/t00 dimension ist(129,129) imax=imx(k) jmax=jmx(k) nmax=nmx(k) is=nst(k,l)-nmax-1 do 1 i=1,imax do 1 j=1,jmax is=is+nmax ist(i,j)=is 1 continue x0a=x0 y0a=y0 t0a=t00 hhx=hx(k) hhy=hy(k) hht=ht(k) return end c------------------------------------------------ subroutine multig(nx0,ny0,nt0,x0,y0,t0,x1,y1,t1,mm, * qdim,wmax,fs,fr,fi,fb,ne,ncycle,nrc,nrf,ncrst,nvw) implicit real*8 (a-h,o-z) dimension err(12) common/qarr/q(50000000) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) common/sor/isor,nmax,ksor,itstl common/albe/sigma common/cweight/rnu,alfa,beta common/iqco/iqco common/finest/m common/tol/tol common/iq/iq common/twindow/t00 common/horiz/nwin external fs,fr,fi,fb c iq=1 iqco=1 c wu=0.0d0 m=mm c hx0=(x1-x0)/nx0 hy0=(y1-y0)/ny0 ht0=(t1-t0)/nt0 np=(nx0+1)*(ny0+1)*(nt0+1) n2=2*ne do 10 k=1,m k2=2**(k-1) k4=1 npx=nx0*k2+1 npy=ny0*k2+1 npt=nt0*k4+1 hx=hx0/k2 hy=hy0/k2 ht=ht0/k4 write(*,*) 'k nx nt',k,npx,npt c do 5 l=1,n2 call grdfn(k,l,npx,npy,npt,x0,y0,t0,hx,hy,ht) 5 continue 10 continue c if(iq.gt.qdim) write(*,*)' iq qdim ',iq,qdim if(iq.gt.qdim) stop'mem' c c nwin=number of time windows with size dtwin c dtwin=t1-t0 ery=0.0 erp=0.0 erz=0.0 do 100 iw=1,nwin write(*,*) ' time window: ', iw,dtwin t0=(iw-1)*dtwin t00=t0 t1=t0+dtwin write(*,*) ' from ',t0,' to ',t1 do 1 n=1,12 1 err(n)=0.0d0 c do 12 k=1,m call putf(k,fr,ne) 12 continue c do 19 k=1,m 19 call putb(k,ne,iw) c if(isor.eq.0) goto 25 c c solve by sor c wusor=0. errmx=1.0d0 write(14,170) do 24 l=ksor,m write(14,*) 'Level ',l do 23 nrel=1,nmax errold=errmx call relax(l,err,errm,ne) errmx=(err(1)+err(2)) wusor=wusor+1. write(14,130) errmx/errold write(*,130) errmx/errold res=(err(1)+err(2)) write(14,190) wusor, (err(i),i=1,ne) 23 continue 24 continue return c c multigrid c 25 continue k=m call fas(fs,k,m,wu,ne,ncycle,nrc,nrf,ncrst,nvw) call store(m,ne,iw,dtwin,erry,errp,errz) ery=ery+erry*erry erp=erp+errp*errp erz=erz+errz*errz 100 continue write(*,*) ' ' write(*,*) ' Receding horizon: Tracking ' write(*,*) ' Total time ', dtwin*nwin, ' No. windows ',nwin write(*,*) ' Total tracking error ', sqrt(erz) c 130 format(45x,'obs. rho =',f8.4) 170 format('level',4x,'work',6x,'residual norms(i,b)') 190 format('WU ',f8.4,5x,2(1pe10.3)) return end c------------------------------------------------ subroutine putb(k,ne,iwin) implicit real*8 (a-h,o-z) common/qarr/q(50000000) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) external fsol c do 30 l=1,ne call key(k,l,ist,ii,jj,nn,x0,y0,t0,hx,hy,ht) c* lateral boundary i=1 x=x0 do 2 j=1,jj io=ist(i,j) y=y0+(j-1)*hy do 2 n=1,nn t=t0+(n-1)*ht q(io+n)=0.0 2 continue c i=ii x=x0+(i-1)*hx do 4 j=1,jj io=ist(i,j) y=y0+(j-1)*hy do 4 n=1,nn t=t0+(n-1)*ht q(io+n)=0.0 4 continue c j=1 y=y0 do 6 i=1,ii x=x0+(i-1)*hx io=ist(i,j) do 6 n=1,nn t=t0+(n-1)*ht q(io+n)=0.0 6 continue c j=jj y=y0+(j-1)*hy do 8 i=1,ii x=x0+(i-1)*hx io=ist(i,j) do 8 n=1,nn t=t0+(n-1)*ht q(io+n)=0.0 8 continue c* i.c. ii1=ii-1 jj1=jj-1 c* initial condition for the state eq. if(l.eq.1) then if(iwin.eq.1) then n=1 t=t0 do 10 i=2,ii1 x=x0+(i-1)*hx do 10 j=2,jj1 y=y0+(j-1)*hy io=ist(i,j) q(io+n)=fsol(x,y,t,1) 10 continue else n=1 t=t0 do 11 i=2,ii1 x=x0+(i-1)*hx do 11 j=2,jj1 y=y0+(j-1)*hy io=ist(i,j) q(io+n)=q(io+nn) 11 continue endif endif c c* final condition for the adjoint eq. if(l.eq.2) then n=nn t=t0+(nn-1)*ht do 12 i=2,ii1 x=x0+(i-1)*hx do 12 j=2,jj1 y=y0+(j-1)*hy io=ist(i,j) cc q(io+n)=0.0 12 continue if(iwin.gt.1) then n=1 do 14 i=2,ii1 do 14 j=2,jj1 io=ist(i,j) q(io+n)=q(io+nn) 14 continue endif endif 30 continue c c initialize c do 13 l=1,ne call key(k,l,ist,imax,jmax,nmax,x0,y0,t0,hx,hy,ht) do 1 i=1,imax x=x0+(i-1)*hx do 1 j=1,jmax io=ist(i,j) y=y0+(j-1)*hy do 1 n=2,nmax t=t0+(n-1)*ht q(io+n)=0.0 1 continue 13 continue return end c------------------------------------------------ subroutine putf(m,fr,ne) implicit real*8 (a-h,o-z) common/qarr/q(50000000) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) common/albe/sigma external fr k=m c do 20 l=1,ne call key(k,l+ne,ist,imax,jmax,nmax,x0,y0,t0,hx,hy,ht) hs=ht c* state rhs if(l.eq.1) then do 3 i=1,imax x=x0+(i-1)*hx do 3 j=1,jmax io=ist(i,j) y=y0+(j-1)*hy do 3 n=1,nmax t=t0+(n-1)*ht q(io+n)=fr(x,y,t,l)*hs 3 continue else c* adjoint rhs do 6 i=1,imax x=x0+(i-1)*hx do 6 j=1,jmax io=ist(i,j) y=y0+(j-1)*hy do 6 na=1,nmax n=nmax-na+1 t=t0+(n-1)*ht q(io+n)=fr(x,y,t,l)*hs 6 continue endif 20 continue return end c------------------------------------------------ subroutine putu(k,km,ne) implicit real*8 (a-h,o-z) common/qarr/q(50000000) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) do 20 l=1,ne call key(k,l,ist,iif,jjf,nnf,x0,y0,t0,hxf,hyf,htf) call key(km,l,ism,iic,jjc,nnc,x0,y0,t0,hxc,hyc,htc) do 2 i=1,iif do 2 j=1,jjf 2 isf(i,j,l)=ist(i,j) do 3 i=1,iic do 3 j=1,jjc 3 isc(i,j,l)=ism(i,j) iic1=iic-1 jjc1=jjc-1 nnc1=nnc-1 c do 9 ic=1,iic if=2*ic-1 do 9 jc=1,jjc jf=2*jc-1 icq=isc(ic,jc,l) ifq=isf(if,jf,l) do 9 nc=1,nnc nf=nc q(icq+nc)=q(ifq+nf) 9 continue 20 continue return end c------------------------------------------------ subroutine relax(k,err,errmax,ne) implicit real*8 (a-h,o-z) dimension err(12) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) common/sor/isor,nmax,ksor,itstl common/tol/tol c c* TS/TL - Gauss-Seidel if(itstl.eq.1) call relaxts(k,err,errmax,ne) if(itstl.eq.2) call relaxtl(k,err,errmax,ne) c write(*,100) k, (err(i),i=1,ne) 100 format('err(i,e)(',i2,')=',d13.6,4x,d13.6) return end c------------------------------------------------ subroutine resca1(k,ne,le) implicit real*8 (a-h,o-z) common/qarr/q(50000000) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) common/res/resf(129,129,830) common/albe/sigma common/cweight/rnu,alfa,beta external gnl c do 3 l=1,ne call key(k,l,ist,iif,jjf,nnf,x0,y0,t0,hxf,hyf,htf) do 1 i=1,iif do 1 j=1,jjf 1 isf(i,j,l)=ist(i,j) call key(k,l+ne,ist,iif,jjf,nnf,x0,y0,t0,hxf,hyf,htf) do 3 i=1,iif do 3 j=1,jjf 3 isf(i,j,l+ne)=ist(i,j) c c compute residuals on the fine grid c coe1=sigma*htf/(hxf*hxf) coe2=sigma*htf/(hyf*hyf) coe3=1.0 coe=2.0d0*(coe1+coe2)+coe3 iif1=iif-1 jjf1=jjf-1 nnf1=nnf-1 c do 10 if=2,iif1 do 10 jf=2,jjf1 ifom=isf(if-1,jf,le) ifo=isf(if,jf,le) ifop=isf(if+1,jf,le) jfom=isf(if,jf-1,le) jfop=isf(if,jf+1,le) iffo=isf(if,jf,ne+le) ifo2=isf(if,jf,2) x=(if-1)*hxf y=(jf-1)*hyf c do 10 nf=2,nnf nfm=nf-1 t=t0+(nf-1)*htf ax=q(ifom+nf)-2.0d0*q(ifo+nf)+q(ifop+nf) ay=q(jfom+nf)-2.0d0*q(ifo+nf)+q(jfop+nf) at=q(ifo+nfm)-q(ifo+nf) a1=q(iffo+nf)-(coe1*ax+coe2*ay+coe3*at) a1=a1-htf*gnl(q(ifo+nf))+htf*q(ifo2+nf)/rnu resf(if,jf,nf)=a1 10 continue return end c------------------------------------------------ subroutine resca2(k,ne,le) implicit real*8 (a-h,o-z) common/qarr/q(50000000) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) common/res/resf(129,129,830) common/albe/sigma common/cweight/rnu,alfa,beta external zf,d1gnl c do 3 l=1,ne call key(k,l,ist,iif,jjf,nnf,x0,y0,t0,hxf,hyf,htf) do 1 i=1,iif do 1 j=1,jjf 1 isf(i,j,l)=ist(i,j) call key(k,l+ne,ist,iif,jjf,nnf,x0,y0,t0,hxf,hyf,htf) do 3 i=1,iif do 3 j=1,jjf 3 isf(i,j,l+ne)=ist(i,j) c c compute residuals on the fine grid c coe1=sigma*htf/(hxf*hxf) coe2=sigma*htf/(hyf*hyf) coe3=1.0 coe=2.0d0*(coe1+coe2)+coe3 iif1=iif-1 jjf1=jjf-1 nnf1=nnf-1 c do 10 if=2,iif1 do 10 jf=2,jjf1 ifom=isf(if-1,jf,le) ifo=isf(if,jf,le) ifop=isf(if+1,jf,le) jfom=isf(if,jf-1,le) jfop=isf(if,jf+1,le) iffo=isf(if,jf,ne+le) ifo1=isf(if,jf,1) x=(if-1)*hxf y=(jf-1)*hyf c do 10 nfa=2,nnf1 nf=nnf-nfa+1 nfm=nf+1 t=t0+(nf-1)*htf ax=q(ifom+nf)-2.0d0*q(ifo+nf)+q(ifop+nf) ay=q(jfom+nf)-2.0d0*q(ifo+nf)+q(jfop+nf) at=q(ifo+nfm)-q(ifo+nf) a1=q(iffo+nf)-(coe1*ax+coe2*ay+coe3*at) yvar=q(ifo1+nf) a1=a1-htf*d1gnl(yvar)*q(ifo+nf)-htf*alfa*(yvar-zf(x,y,t)) resf(if,jf,nf)=a1 10 continue return end c------------------------------------------------ subroutine rescal(k,km,ne) implicit real*8 (a-h,o-z) common/res/resf(129,129,830) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) c do 30 le=1,ne call key(k,le,ist,iif,jjf,nnf,x0,y0,t0,hxf,hyf,htf) call key(km,le,ism,iic,jjc,nnc,x0,y0,t0,hxc,hyc,htc) do 1 if=1,iif do 1 jf=1,jjf do 1 nf=1,nnf 1 resf(if,jf,nf)=0.0d0 if(le.eq.1) then call resca1(k,ne,le) call trare1(k,km,ne,le) else call resca2(k,ne,le) call trare2(k,km,ne,le) endif 30 continue return end c------------------------------------------------ subroutine store(k,ne,iwin,dtwin,erry,errp,errz) c c store the solution, compute sol. error and stat. residual c implicit real*8 (a-h,o-z) common/qarr/q(50000000) common/pntrs/ist(129,129),is(129,129,8), X ism(129,129),isc(129,129,8) common/albe/sigma common/cweight/rnu,alfa,beta common/horiz/nwin dimension err(12) external fsol,zf,gnl,d1gnl c n2=2*ne do 2 l=1,n2 call key(k,l,ist,ii,jj,nn,x0,y0,t0,hx,hy,ht) do 1 i=1,ii do 1 j=1,jj 1 is(i,j,l)=ist(i,j) 2 continue i1=ii-1 j1=jj-1 n1=nn-1 write(*,*) write(*,*) ' ii= ',ii write(*,*) ' jj= ',jj write(*,*) ' nn= ',nn write(*,*) ' h = ',hx,hy,ht c coe1=sigma*ht/(hx*hx) coe2=sigma*ht/(hy*hy) coe3=1.0 coe=2.0d0*(coe1+coe2)+coe3 write(*,*) ' sigma * gamma = ', coe1 c c---- static residual c c* state le=1 err(le)=0.0d0 erry =0.0d0 errz =0.0d0 errt =0.0d0 c do 20 n=2,n1 t=t0+(n-1)*ht nm=n-1 do 20 i=2,i1 do 20 j=2,j1 x=(i-1)*hx y=(j-1)*hy iom=is(i-1,j,le) io =is(i,j,le) iop=is(i+1,j,le) jom=is(i,j-1,le) jop=is(i,j+1,le) ifo=is(i,j,ne+le) io2 =is(i,j,2) c ax=q(iom+n)-2.0d0*q(io+n)+q(iop+n) ay=q(jom+n)-2.0d0*q(io+n)+q(jop+n) at=q(io+nm)-q(io+n) a1=q(ifo+n)-(coe1*ax+coe2*ay+coe3*at) pvar=q(io2+n) a1=a1-ht*gnl(q(io+n))+ht*pvar/rnu err(le)=err(le)+a1**2 erry=erry+(fsol(x,y,t,le)-q(io+n))**2 errz=errz+(zf(x,y,t)-q(io+n))**2 20 continue err(le)=sqrt(err(le)*hx*hy/ht) erry=sqrt(erry*hx*hy*ht) errz=sqrt(errz*hx*hy*ht) write(*,*)' eq.n and static residue ',le,err(le) write(*,*)' eq.n and solution error ',le,erry write(*,*) c* adjoint le=2 err(le)=0.0d0 errp =0.0d0 c do 40 n=2,n1 t=t0+(n-1)*ht nm=n+1 do 40 i=2,i1 do 40 j=2,j1 x=(i-1)*hx y=(j-1)*hy iom=is(i-1,j,le) io =is(i,j,le) iop=is(i+1,j,le) jom=is(i,j-1,le) jop=is(i,j+1,le) ifo=is(i,j,ne+le) io1 =is(i,j,1) c ax=q(iom+n)-2.0d0*q(io+n)+q(iop+n) ay=q(jom+n)-2.0d0*q(io+n)+q(jop+n) at=(q(io+nm)-q(io+n)) a1=q(ifo+n)-(coe1*ax+coe2*ay+coe3*at) yvar=q(io1+n) a1=a1-ht*d1gnl(yvar)*q(io+n)-ht*alfa*(yvar-zf(x,y,t)) err(le)=err(le)+a1**2 errp=errp+(fsol(x,y,t,le)-q(io+n))**2 40 continue err(le)=sqrt(err(le)*hx*hy/ht) errp=sqrt(errp*hx*hy*ht) write(*,*)' eq.n and static residue ',le,err(le) write(*,*)' eq.n and solution error ',le,errp c c terminal c erest =0.0d0 n=nn t=t0+(n-1)*ht do 50 i=2,i1 do 50 j=2,j1 x=(i-1)*hx y=(j-1)*hy io1 =is(i,j,1) io2 =is(i,j,2) errt = errt+(zf(x,y,t)-q(io1+n))**2 erest = erest+(q(io2+n)-beta*(zf(x,y,t)-q(io1+n)))**2 50 continue errt=sqrt(errt*hx*hy) erest=sqrt(erest*hx*hy) write(*,*)' terminal eq. res. ',erest c write(*,*)' tracking error ',errz write(*,*)' terminal error ',errt c c store for matlab c cc open(unit=17,status='unknown',file='midsol.dat',access='append') C PRINT THE SOLUTION VALUE AT A MESH POINT FOR ALL TIMES C i=(ii+1)/2 j=(jj+1)/2 x=(i-1)*hx y=(j-1)*hy do 95 n=1,nn-1 t=t0+(n-1)*ht cont=q(is(i,j,2)+n)/rnu 95 write(17,133) t,q(is(i,j,1)+n),zf(x,y,t),cont 133 format(1x,4(1x,f16.8)) return end c------------------------------------------------ subroutine subtrt(kc,kf,ne) implicit real*8 (a-h,o-z) common/qarr/q(50000000) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) do 20 l=1,ne call key(kf,l,ist,iif,jjf,nnf,x0,y0,t0,hxf,hyf,htf) call key(kc,l,ism,iic,jjc,nnc,x0,y0,t0,hxc,hyc,htc) do 2 i=1,iif do 2 j=1,jjf 2 isf(i,j,l)=ist(i,j) do 3 i=1,iic do 3 j=1,jjc 3 isc(i,j,l)=ism(i,j) iic1=iic-1 jjc1=jjc-1 nnc1=nnc-1 c* no time coarsening do 17 ic=1,iic if=2*ic-1 do 17 jc=1,jjc jf=2*jc-1 ifq=isf(if,jf,l) icq=isc(ic,jc,l) do 17 nc=1,nnc nf=nc q(icq+nc)=q(icq+nc)-q(ifq+nf) 17 continue 20 continue return end c------------------------------------------------------------ subroutine trare1(k,km,ne,le) implicit real*8 (a-h,o-z) common/qarr/q(50000000) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) common/res/resf(129,129,830) common/albe/sigma c call key(km,le+ne,ism,iic,jjc,nnc,x0,y0,t0,hxc,hyc,htc) do 3 i=1,iic do 3 j=1,jjc 3 isc(i,j,le+ne)=ism(i,j) c c half-full weighting of the internal residuals c iic1=iic-1 jjc1=jjc-1 nnc1=nnc-1 c* no time coarsening do 75 ic=2,iic1 if=2*ic-1 ifm=if-1 ifp=if+1 do 75 jc=2,jjc1 jf=2*jc-1 jfm=jf-1 jfp=jf+1 icf=isc(ic,jc,le+ne) do 75 nc=2,nnc nf=nc nfm=nf-1 nfp=nf+1 C Half-weighting sq=resf(if-1,jf,nf)+resf(if+1,jf,nf) X +resf(if,jf-1,nf)+resf(if,jf+1,nf) q(icf+nc)=0.5*resf(if,jf,nf)+0.125*sq 75 continue return end c------------------------------------------------------------ subroutine trare2(k,km,ne,le) implicit real*8 (a-h,o-z) common/qarr/q(50000000) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) common/res/resf(129,129,830) common/albe/sigma call key(km,le+ne,ism,iic,jjc,nnc,x0,y0,t0,hxc,hyc,htc) do 3 i=1,iic do 3 j=1,jjc 3 isc(i,j,le+ne)=ism(i,j) c c half-full weighting of the internal residuals c iic1=iic-1 jjc1=jjc-1 nnc1=nnc-1 c* no time coarsening do 75 ic=2,iic1 if=2*ic-1 ifm=if-1 ifp=if+1 do 75 jc=2,jjc1 jf=2*jc-1 jfm=jf-1 jfp=jf+1 icf=isc(ic,jc,le+ne) do 75 nca=2,nnc nc=nnc-nca+1 nf=nc nfm=nf+1 nfp=nf-1 C Half-weighting sq=resf(if-1,jf,nf)+resf(if+1,jf,nf) X +resf(if,jf-1,nf)+resf(if,jf+1,nf) q(icf+nc)=0.5*resf(if,jf,nf)+0.125*sq 75 continue return end c------------------------------------------------------------ subroutine intr2(km,k,ne) implicit real*8 (a-h,o-z) c common/qarr/q(50000000) common/pntrs/ist(129,129),isf(129,129,8), X ism(129,129),isc(129,129,8) do 30 le=1,ne call key(k,le,ist,iif,jjf,nnf,x0,y0,t0,hxf,hyf,htf) call key(km,le,ism,iic,jjc,nnc,x0,y0,t0,hxc,hyc,htc) c c no time coarsening c c c side i=1 c ic=1 if=2*ic-1 do 55 jc=2,jjc jf=2*jc-1 ifq=ist(if,jf) jfqm=ist(if,jf-1) icq=ism(ic,jc) jcqm=ism(ic,jc-1) do 55 nc=2,nnc nf=nc c a=.50d0*(q(icq+nc)+q(jcqm+nc)) q(ifq+nf)=q(icq+nc) q(jfqm+nf)=a 55 continue c c edge i=1,j=1 ic=1 if=1 jc=1 jf=1 c corner i=1,j=1,n=1 ifq=ist(if,jf) icq=ism(ic,jc) q(ifq+1)=q(icq+1) c do 56 nc=2,nnc nf=nc c q(ifq+nf)=q(icq+nc) 56 continue c side j=1 jc=1 jf=2*jc-1 do 510 ic=2,iic if=2*ic-1 ifq=ist(if,jf) ifqm=ist(if-1,jf) icq=ism(ic,jc) icqm=ism(ic-1,jc) do 510 nc=2,nnc nf=nc c am=.50d0*(q(icqm+nc)+q(icq+nc)) q(ifq+nf)=q(icq+nc) q(ifqm+nf)=am 510 continue c c edge j=1,n=1 jc=1 jf=1 nc=1 nf=1 do 511 ic=2,iic if=2*ic-1 ifq=ist(if,jf) ifqm=ist(if-1,jf) icq=ism(ic,jc) icqm=ism(ic-1,jc) c am=.50d0*(q(icqm+nc)+q(icq+nc)) q(ifq+nf)=q(icq+nc) q(ifqm+nf)=am 511 continue c side n=1 nc=1 nf=1 do 515 ic=2,iic if=2*ic-1 do 515 jc=2,jjc jf=2*jc-1 ifq=ist(if,jf) ifqm=ist(if-1,jf) jfqm=ist(if,jf-1) jfqmm=ist(if-1,jf-2) ijfqm=ist(if-1,jf-1) icq=ism(ic,jc) icqm=ism(ic-1,jc) jcqm=ism(ic,jc-1) ijcqm=ism(ic-1,jc-1) c a=.50d0*(q(icq+nc)+q(jcqm+nc)) q(ifq+nf)=q(icq+nc) q(jfqm+nf)=a a=.50d0*(q(icqm+nc)+q(icq+nc)) am=.250d0*(q(icq+nc)+q(icqm+nc) X +q(jcqm+nc)+q(ijcqm+nc)) q(ifqm+nf)=a q(ijfqm+nf)=am 515 continue c edge n=1,i=1 nc=1 nf=1 ic=1 if=1 do 516 jc=2,jjc jf=2*jc-1 ifq=ist(if,jf) jfqm=ist(if,jf-1) icq=ism(ic,jc) jcqm=ism(ic,jc-1) a=.50d0*(q(icq+nc)+q(jcqm+nc)) q(ifq+nf)=q(icq+nc) q(jfqm+nf)=a 516 continue c internal points and outer sides do 520 ic=2,iic if=2*ic-1 do 520 jc=2,jjc jf=2*jc-1 ifq=ist(if,jf) ifqm=ist(if-1,jf) jfqm=ist(if,jf-1) jfqmm=ist(if-1,jf-2) ijfqm=ist(if-1,jf-1) icq=ism(ic,jc) icqm=ism(ic-1,jc) jcqm=ism(ic,jc-1) ijcqm=ism(ic-1,jc-1) do 520 nc=2,nnc nf=nc c a=.50d0*(q(icq+nc)+q(jcqm+nc)) q(ifq+nf)=q(icq+nc) q(jfqm+nf)=a a=.50d0*(q(icqm+nc)+q(icq+nc)) am=.250d0*(q(icqm+nc)+q(icq+nc)+q(jcqm+nc)+q(ijcqm+nc)) q(ifqm+nf)=a q(ijfqm+nf)=am 520 continue 30 continue return end c------------------------------------------------------------ subroutine relaxts(k,err,errm,ne) c---- time-splitted collective Gauss-Seidel iteration implicit real*8 (a-h,o-z) dimension err(12) common/qarr/q(50000000) common/pntrs/ist(129,129),iss(129,129,8), X ism(129,129),isc(129,129,8) common/albe/sigma common/cweight/rnu,alfa,beta common/horiz/nwin external zf,gnl,d1gnl,d2gnl c n2=2*ne do 2 l=1,n2 call key(k,l,ist,imax,jmax,nmax,x0,y0,t0,hx,hy,ht) do 1 i=1,imax do 1 j=1,jmax 1 iss(i,j,l)=ist(i,j) 2 continue i1=imax-1 j1=jmax-1 n1=nmax-1 ht2=ht*ht h2xy=hx*hy dt=ht h2=h2xy c coe1=sigma*ht/(hx*hx) coe2=sigma*ht/(hy*hy) coe3=1.0 coe=2.0d0*(coe1+coe2)+coe3 c c* state & adjoint errm=0.0d0 errq=0.0 erru=0.0 le1=1 le2=2 err(le1)=0.0 err(le2)=0.0 do 40 i=2,i1 do 40 j=2,j1 iom1=iss(i-1,j,le1) io1=iss(i,j,le1) iop1=iss(i+1,j,le1) jom1=iss(i,j-1,le1) jop1=iss(i,j+1,le1) ifo1=iss(i,j,ne+le1) iom2=iss(i-1,j,le2) io2=iss(i,j,le2) iop2=iss(i+1,j,le2) jom2=iss(i,j-1,le2) jop2=iss(i,j+1,le2) ifo2=iss(i,j,ne+le2) x=(i-1)*hx y=(j-1)*hy do 20 n=2,nmax-1 nm=n-1 np=n+1 t=t0+(n-1)*ht na=nmax-n+1 nam=na-1 nap=na+1 ta=t0+(na-1)*ht c ax=q(iom1+n)-2.0d0*q(io1+n)+q(iop1+n) ay=q(jom1+n)-2.0d0*q(io1+n)+q(jop1+n) at=q(io1+nm)-q(io1+n) a1=q(ifo1+n)-(coe1*ax+coe2*ay+coe3*at) pvar=q(io2+n) a1=a1-ht*gnl(q(io1+n))+ht*pvar/rnu axa=q(iom1+na)-2.0d0*q(io1+na)+q(iop1+na) aya=q(jom1+na)-2.0d0*q(io1+na)+q(jop1+na) ata=q(io1+nam)-q(io1+na) a1a=q(ifo1+na)-(coe1*axa+coe2*aya+coe3*ata) pvara=q(io2+na) a1a=a1a-ht*gnl(q(io1+na))+ht*pvara/rnu c bx=q(iom2+n)-2.0d0*q(io2+n)+q(iop2+n) by=q(jom2+n)-2.0d0*q(io2+n)+q(jop2+n) bt=q(io2+np)-q(io2+n) b1=q(ifo2+n)-(coe1*bx+coe2*by+coe3*bt) yvar=q(io1+n) b1=b1-ht*d1gnl(yvar)*q(io2+n)-ht*alfa*(yvar-zf(x,y,t)) bxa=q(iom2+na)-2.0d0*q(io2+na)+q(iop2+na) bya=q(jom2+na)-2.0d0*q(io2+na)+q(jop2+na) bta=q(io2+nap)-q(io2+na) b1a=q(ifo2+na)-(coe1*bxa+coe2*bya+coe3*bta) yvara=q(io1+na) b1a=b1a-ht*d1gnl(yvara)*q(io2+na)-ht*alfa*(yvara-zf(x,y,ta)) c rt1=-(1.0 + 4.0*coe1)+ht*d1gnl(q(io1+n)) rt2=(ht*ht/rnu)*(alfa+d2gnl(q(io1+n))*q(io2+n)) rden = rt1*rt1+rt2 rnum11= rt1*a1 rnum12= (ht/rnu)*b1 rnum1 = rnum11+rnum12 c rt1a=-(1.0 + 4.0*coe1)+ht*d1gnl(q(io1+na)) rt2a=(ht*ht/rnu)*(alfa+d2gnl(q(io1+na))*q(io2+na)) rdena =rt1a*rt1a+rt2a rnum21=-ht*(alfa+d2gnl(q(io1+na))*q(io2+na))*a1a rnum22= rt1a*b1a rnum2 = rnum21+rnum22 qx=q(io1+n)+rnum1/rden ux=q(io2+na)+rnum2/rdena erq=q(io1+n)-qx eru=q(io2+na)-ux errq=errq+erq*erq erru=erru+eru*eru q(io1+n)=qx q(io2+na)=ux 20 continue c c terminal condition p(T) = beta*(y(T)-z_T) c n=nmax t=t0+(n-1)*ht ax=q(iom1+n)-2.0d0*q(io1+n)+q(iop1+n) ay=q(jom1+n)-2.0d0*q(io1+n)+q(jop1+n) at=q(io1+nm)-q(io1+n) a1=q(ifo1+n)-(coe1*ax+coe2*ay+coe3*at) a1=a1-ht*gnl(q(io1+n))+ht*q(io2+n)/rnu b1=q(io2+n) - beta*(q(io1+n)-zf(x,y,t)) rden=beta*dt+(1.0+4.0*coe1)*rnu-ht*rnu*d1gnl(q(io1+n)) qx=q(io1+n)-(rnu*a1-ht*b1)/rden ux=q(io2+n)-(beta*rnu*a1 X +rnu*(1.0+4.0*coe1-ht*d1gnl(q(io1+n)))*b1)/rden q(io1+n)=qx q(io2+n)=ux 40 continue errm=0.0 err(le1)=sqrt(errq*hx*hy*ht) err(le2)=sqrt(erru*hx*hy*ht)/rnu errm=err(le1)+err(le2) return end c------------------------------------------------------------ subroutine relaxtl(k,err,errm,ne) c---- t-line collective Gauss-Seidel iteration implicit real*8 (a-h,o-z) dimension err(12) common/qarr/q(50000000) common/pntrs/ist(129,129),iss(129,129,8), X ism(129,129),isc(129,129,8) common/albe/sigma common/cweight/rnu,alfa,beta common/horiz/nwin dimension aa2(2,2,333),bb2(2,2,333),cc2(2,2,333), * ff(2,333),xx2(2,333) external zf,gnl,d1gnl,d2gnl c n2=2*ne do 2 l=1,n2 call key(k,l,ist,imax,jmax,nmax,x0,y0,t0,hx,hy,ht) do 1 i=1,imax do 1 j=1,jmax 1 iss(i,j,l)=ist(i,j) 2 continue i1=imax-1 j1=jmax-1 n1=nmax-1 ht2=ht*ht h2xy=hx*hy dt=ht h2=h2xy c coe1=sigma*ht/(hx*hx) coe2=sigma*ht/(hy*hy) coe3=1.0 coe=2.0d0*(coe1+coe2)+coe3 c do 5 n=1,nmax do 5 i=1,2 ff(i,n)=0. xx2(i,n)=0. do 5 j=1,2 aa2(i,j,n)=0. bb2(i,j,n)=0. cc2(i,j,n)=0. 5 continue c c* state & adjoint c le1=1 le2=2 erry=0.0d0 errp=0.0d0 err(le1)=0.0 err(le2)=0.0 c do 40 i=2,i1 do 40 j=2,j1 x=(i-1)*hx y=(j-1)*hy io1=iss(i,j,le1) io2=iss(i,j,le2) im=i-1 if(i.eq.1) im=i+1 iom1=iss(im,j,le1) iom2=iss(im,j,le2) ip=i+1 if(i.eq.imax) ip=i-1 iop1=iss(ip,j,le1) iop2=iss(ip,j,le2) jm=j-1 if(j.eq.1) jm=j+1 jom1=iss(i,jm,le1) jom2=iss(i,jm,le2) jp=j+1 if(j.eq.jmax) jp=j-1 jop1=iss(i,jp,le1) jop2=iss(i,jp,le2) ifo1=iss(i,j,ne+le1) ifo2=iss(i,j,ne+le2) c c in (0,T) c n=2 nm=n-1 np=n+1 t=t0+(n-1)*dt cc y-rhs ax=q(iom1+n)-2.0d0*q(io1+n)+q(iop1+n) ay=q(jom1+n)-2.0d0*q(io1+n)+q(jop1+n) at=q(io1+nm)-q(io1+n) a1=q(ifo1+n)-(coe1*ax+coe2*ay+coe3*at) a1=a1-ht*gnl(q(io1+n))+ht*q(io2+n)/rnu cc p-rhs bx=q(iom2+n)-2.0d0*q(io2+n)+q(iop2+n) by=q(jom2+n)-2.0d0*q(io2+n)+q(jop2+n) bt=q(io2+np)-q(io2+n) b1=q(ifo2+n)-(coe1*bx+coe2*by+coe3*bt) b1=b1-ht*d1gnl(q(io1+n))*q(io2+n)-ht*alfa*(q(io1+n)-zf(x,y,t)) cc aa2(1,1,n) = -(1.+4.*coe1) + ht*d1gnl(q(io1+n)) aa2(2,2,n) = -(1.+4.*coe1) + ht*d1gnl(q(io1+n)) aa2(1,2,n) = -dt/rnu aa2(2,1,n) = ht*(alfa + d2gnl(q(io1+n))*q(io2+n)) cc cc2(1,1,n) = 0.0 cc2(2,2,n) = 1.0 cc2(1,2,n) = 0.0 cc2(2,1,n) = 0.0 cc ff(1,n) = a1 ff(2,n) = b1 cc do 30 n=3,n1 nm=n-1 np=n+1 t=t0+(n-1)*dt cc y-rhs ax=q(iom1+n)-2.0d0*q(io1+n)+q(iop1+n) ay=q(jom1+n)-2.0d0*q(io1+n)+q(jop1+n) at=q(io1+nm)-q(io1+n) a1=q(ifo1+n)-(coe1*ax+coe2*ay+coe3*at) a1=a1-ht*gnl(q(io1+n))+ht*q(io2+n)/rnu cc p-rhs bx=q(iom2+n)-2.0d0*q(io2+n)+q(iop2+n) by=q(jom2+n)-2.0d0*q(io2+n)+q(jop2+n) bt=q(io2+np)-q(io2+n) b1=q(ifo2+n)-(coe1*bx+coe2*by+coe3*bt) b1=b1-ht*d1gnl(q(io1+n))*q(io2+n)-dt*alfa*(q(io1+n)-zf(x,y,t)) cc aa2(1,1,n) = -(1.+4.*coe1) + ht*d1gnl(q(io1+n)) aa2(2,2,n) = -(1.+4.*coe1) + ht*d1gnl(q(io1+n)) aa2(1,2,n) = -dt/rnu aa2(2,1,n) = ht*(alfa + d2gnl(q(io1+n))*q(io2+n)) cc bb2(1,1,n) = 1.0 bb2(2,2,n) = 0.0 bb2(1,2,n) = 0.0 bb2(2,1,n) = 0.0 cc cc2(1,1,n) = 0.0 cc2(2,2,n) = 1.0 cc2(1,2,n) = 0.0 cc2(2,1,n) = 0.0 ff(1,n) = a1 ff(2,n) = b1 30 continue c c terminal condition p(T)=beta*(y(T)-z_T) c n=nmax nm=n-1 t=t0+(n-1)*dt cc y-rhs ax=q(iom1+n)-2.0d0*q(io1+n)+q(iop1+n) ay=q(jom1+n)-2.0d0*q(io1+n)+q(jop1+n) at=q(io1+nm)-q(io1+n) a1=q(ifo1+n)-(coe1*ax+coe2*ay+coe3*at) a1=a1-ht*gnl(q(io1+n))+ht*q(io2+n)/rnu cc p-rhs b1=q(io2+n) - beta*(q(io1+n)-zf(x,y,t)) cc aa2(1,1,n) = -(1.+4.*coe1) + ht*d1gnl(q(io1+n)) aa2(2,2,n) = -1.0 aa2(1,2,n) = -dt/rnu aa2(2,1,n) = beta cc bb2(1,1,n) = 1.0 bb2(2,2,n) = 0.0 bb2(1,2,n) = 0.0 bb2(2,1,n) = 0.0 ff(1,n) = a1 ff(2,n) = b1 c c block tridiagonal solve c call tridb4(aa2,bb2,cc2,ff,xx2,2,nmax) do 20 n=2,nmax ery=xx2(1,n) erry=erry+ery*ery erp=xx2(2,n) errp=errp+erp*erp q(io1+n) = q(io1+n) + ery q(io2+n) = q(io2+n) + erp 20 continue 40 continue errm=0.0 err(le1)=sqrt(erry*hx*hy*ht) err(le2)=sqrt(errp*hx*hy*ht)/rnu errm=err(le1)+err(le2) return end c---------------------------------------------------- subroutine tridb4(aa,bb,cc,df,x,ni,nf) implicit real*8 (a-h,o-z) parameter (np=2) c c---- solution of ( np x np )-block tridiagonal systems c b a c dimension aa(np,np,333),bb(np,np,333),cc(np,np,333), * ga(np,np,333),af(np,np),y(np,333),x(np,333), * df(np,333) dimension ax(np,np),bx(np,np) nip=ni+1 k=ni c c af = aa do 5 i=1,np do 5 j=1,np af(i,j)=aa(i,j,k) 5 continue c c solve af * y = df c call gaussj(a,n,np,b,m,mp) do 50 i=1,np bx(i,1)=df(i,k) do 50 j=1,np ax(i,j)=af(i,j) 50 continue call gaussj(ax,np,np,bx,1,np) do 55 i=1,np y(i,k)=bx(i,1) 55 continue do 10 k=nip,nf k1=k-1 c c solve af * ga = cc by columns for ga c call gaussj(a,n,np,b,m,mp) do 60 i=1,np do 60 j=1,np bx(i,j)=cc(i,j,k1) ax(i,j)=af(i,j) 60 continue call gaussj(ax,np,np,bx,np,np) do 65 i=1,np do 65 j=1,np ga(i,j,k) = bx(i,j) 65 continue c c af = aa - bb * ga do 80 i=1,np do 80 j=1,np af(i,j)=aa(i,j,k) 80 continue do 85 i=1,np do 85 j=1,np do 85 l=1,np af(i,j)=af(i,j)-bb(i,l,k)*ga(l,j,k) 85 continue c c solve af * y = df - b * y do 90 i=1,np do 90 l=1,np df(i,k) = df(i,k)-bb(i,l,k)*y(l,k1) 90 continue c c call gaussj(a,n,np,b,m,mp) do 70 i=1,np bx(i,1)=df(i,k) do 70 j=1,np ax(i,j)=af(i,j) 70 continue call gaussj(ax,np,np,bx,1,np) do 75 i=1,np y(i,k)=bx(i,1) 75 continue 10 continue c c---- back substitution do 2 i=1,np x(i,nf)=y(i,nf) 2 continue do 20 k=nf-1,1,-1 k1=k+1 do 4 i=1,np x(i,k)=y(i,k) do 4 l=1,np x(i,k)=x(i,k)-ga(i,l,k1)*x(l,k1) 4 continue 20 continue return end c----------------------------------------------------------------- SUBROUTINE gaussj(a,n,np,b,m,mp) implicit real*8 (a-h,o-z) INTEGER m,mp,n,np,NMAX PARAMETER (NMAX=1000) INTEGER i,icol,irow,j,k,l,ll,indxc(NMAX),indxr(NMAX),ipiv(NMAX) c REAL a(np,np),b(np,mp) DIMENSION a(np,np),b(np,mp) c REAL big,dum,pivinv do 11 j=1,n ipiv(j)=0 11 continue do 22 i=1,n big=0. do 13 j=1,n if(ipiv(j).ne.1)then do 12 k=1,n if (ipiv(k).eq.0) then if (abs(a(j,k)).ge.big)then big=abs(a(j,k)) irow=j icol=k endif else if (ipiv(k).gt.1) then pause 'singular matrix in gaussj' endif 12 continue endif 13 continue ipiv(icol)=ipiv(icol)+1 if (irow.ne.icol) then do 14 l=1,n dum=a(irow,l) a(irow,l)=a(icol,l) a(icol,l)=dum 14 continue do 15 l=1,m dum=b(irow,l) b(irow,l)=b(icol,l) b(icol,l)=dum 15 continue endif indxr(i)=irow indxc(i)=icol if (abs(a(icol,icol)).lt.1.0e-13) X pause 'singular matrix in gaussj' pivinv=1./a(icol,icol) a(icol,icol)=1. do 16 l=1,n a(icol,l)=a(icol,l)*pivinv 16 continue do 17 l=1,m b(icol,l)=b(icol,l)*pivinv 17 continue do 21 ll=1,n if(ll.ne.icol)then dum=a(ll,icol) a(ll,icol)=0. do 18 l=1,n a(ll,l)=a(ll,l)-a(icol,l)*dum 18 continue do 19 l=1,m b(ll,l)=b(ll,l)-b(icol,l)*dum 19 continue endif 21 continue 22 continue do 24 l=n,1,-1 if(indxr(l).ne.indxc(l))then do 23 k=1,n dum=a(k,indxr(l)) a(k,indxr(l))=a(k,indxc(l)) a(k,indxc(l))=dum 23 continue endif 24 continue return END