program driver c c Generic driver routine for claw1 c c Author: Randall J. LeVeque c Version of March, 1999 -- CLAWPACK Version 4.0 c c implicit double precision (a-h,o-z) c # set parameters for maximum array sizes used in declarations c # these must be increased for larger problems. c c parameter (maxmx = 500) parameter (mwork = 4032) parameter (mbc = 2) parameter (meqn = 1) parameter (mwaves = 1) parameter (maux = 0) c dimension q(1-mbc:maxmx+mbc, meqn) dimension aux(1) !# dummy variable since no aux arrays used dimension work(mwork) dimension mthlim(mwaves) call claw1ez(maxmx,meqn,mwaves,mbc,maux,mwork,mthlim, & q,work,aux) stop end c c c ========================================================= subroutine qinit(maxmx,meqn,mbc,mx,xlower,dx,q,maux,aux) c ========================================================= c c # Set initial conditions for q. c c implicit double precision (a-h,o-z) dimension q(1-mbc:maxmx+mbc, meqn) dimension aux(1-mbc:maxmx+mbc, *) common /comic/ beta c c pi2 = 8.d0*datan(1.d0) !# = 2 * pi do 150 i=1,mx xcell = xlower + (i-0.5d0)*dx q(i,1) = dexp(-beta * (xcell-0.25d0)**2) 150 continue c return end c c c ========================================================= subroutine rp1(maxmx,meqn,mwaves,mbc,mx,ql,qr,auxl,auxr, & wave,s,amdq,apdq) c ========================================================= c c # solve Riemann problems for the 1D advection equation q_t + u*q_x = 0. c # For constant advection velocity u, passed in common block. c c # The advection speed u is passed in the common block comrp c # On input, ql contains the state vector at the left edge of each cell c # qr contains the state vector at the right edge of each cell c # On output, wave contains the waves, c # s the speeds, c # amdq the left-going flux difference A^- \Delta q c # apdq the right-going flux difference A^+ \Delta q c c # Note that the i'th Riemann problem has left state qr(i-1,:) c # and right state ql(i,:) c # From the basic clawpack routine step1, rp is called with ql = qr = q. c c implicit double precision (a-h,o-z) dimension ql(1-mbc:maxmx+mbc, meqn) dimension qr(1-mbc:maxmx+mbc, meqn) dimension s(1-mbc:maxmx+mbc, mwaves) dimension wave(1-mbc:maxmx+mbc, meqn, mwaves) dimension amdq(1-mbc:maxmx+mbc, meqn) dimension apdq(1-mbc:maxmx+mbc, meqn) common /comrp/ u c c c do 30 i=2-mbc,mx+mbc c c # Compute the wave and speed c wave(i,1,1) = ql(i,1) - qr(i-1,1) s(i,1) = u c c c # Compute the wave and speed c wave(i,1,1) = ql(i,1) - qr(i-1,1) s(i,1) = u amdq(i,1) = dmin1(u, 0.d0) * wave(i,1,1) apdq(i,1) = dmax1(u, 0.d0) * wave(i,1,1) 30 continue c return end subroutine setprob implicit double precision (a-h,o-z) common /comrp/ u common /comic/ beta common /comsrc/ rate c c # Set the velocity for scalar advection c # This value is passed to the Riemann solver rp1.f in a common block c c # Set the width of the initial Gaussian pulse c # beta is passed to qinit.f in comic c c # Set the rate in the source term c # beta is passed to src1.f in comsrc c open(unit=7,file='setprob.data',status='old',form='formatted') read(7,*) u read(7,*) beta read(7,*) rate return end c c c ========================================================= subroutine src1(maxmx,meqn,mbc,mx,xlower,dx,q,aux,t,dt) c ========================================================= implicit double precision (a-h,o-z) dimension q(1-mbc:maxmx+mbc, meqn) common /comsrc/ rate c c # solve q' = -rate*q c # use the exact solution operator c do i=1,mx xcell = xlower + (i-0.5d0) * dx rate = 1.d0 - xcell c # 2-stage Runge-Kutta method: qstar = (1.d0 - 0.5d0*dt*rate) * q(i,1) q(i,1) = q(i,1) - dt*rate*qstar c c # Note that one could instead use the exact solution operator c # for this source term: c q(i,1) = dexp(-dt*rate) * q(i,1) enddo c return end c c c ===================================================== subroutine bc1(maxmx,meqn,mbc,mx,xlower,dx,q,maux,aux,t,mthbc) c ===================================================== c c # Standard boundary condition choices for claw2 c c # At each boundary k = 1 (left), 2 (right): c # mthbc(k) = 0 for user-supplied BC's (must be inserted!) c # = 1 for zero-order extrapolation c # = 2 for periodic boundary coniditions c # = 3 for solid walls, assuming this can be implemented c # by reflecting the data about the boundary and then c # negating the 2'nd component of q. c ------------------------------------------------ c c # Extend the data from the computational region c # i = 1, 2, ..., mx2 c # to the virtual cells outside the region, with c # i = 1-ibc and i = mx+ibc for ibc=1,...,mbc c implicit double precision (a-h,o-z) dimension q(1-mbc:maxmx+mbc, meqn) dimension aux(1-mbc:maxmx+mbc, *) dimension mthbc(2) c c c------------------------------------------------------- c # left boundary: c------------------------------------------------------- go to (100,110,120,130) mthbc(1)+1 c 100 continue c # user-specified boundary conditions go here in place of error output write(6,*) '*** ERROR *** mthbc(1)=0 and no BCs specified in bc1' stop go to 199 c 110 continue c # zero-order extrapolation: do 115 m=1,meqn do 115 ibc=1,mbc q(1-ibc,m) = q(1,m) 115 continue go to 199 120 continue c # periodic: do 125 m=1,meqn do 125 ibc=1,mbc q(1-ibc,m) = q(mx+1-ibc,m) 125 continue go to 199 130 continue c # solid wall (assumes 2'nd component is velocity or momentum in x): do 135 m=1,meqn do 135 ibc=1,mbc q(1-ibc,m) = q(ibc,m) 135 continue c # negate the normal velocity: do 136 ibc=1,mbc q(1-ibc,2) = -q(ibc,2) 136 continue go to 199 199 continue c c------------------------------------------------------- c # right boundary: c------------------------------------------------------- go to (200,210,220,230) mthbc(2)+1 c 200 continue c # user-specified boundary conditions go here in place of error output write(6,*) '*** ERROR *** mthbc(2)=0 and no BCs specified in bc2' stop go to 299 210 continue c # zero-order extrapolation: do 215 m=1,meqn do 215 ibc=1,mbc q(mx+ibc,m) = q(mx,m) 215 continue go to 299 220 continue c # periodic: do 225 m=1,meqn do 225 ibc=1,mbc q(mx+ibc,m) = q(ibc,m) 225 continue go to 299 230 continue c # solid wall (assumes 2'nd component is velocity or momentum in x): do 235 m=1,meqn do 235 ibc=1,mbc q(mx+ibc,m) = q(mx+1-ibc,m) 235 continue do 236 ibc=1,mbc q(mx+ibc,2) = -q(mx+1-ibc,2) 236 continue go to 299 299 continue c return end c ============================================ subroutine setaux(maxmx,mbc,mx,xlower,dx,maux,aux) c ============================================ c c # set auxiliary arrays c # dummy routine when no auxiliary arrays c c implicit double precision (a-h,o-z) dimension aux(1-mbc:maxmx+mbc, *) c return end c c c subroutine claw1ez(maxmx,meqn,mwaves,mbc,maux,mwork,mthlim, & q,work,aux) c c An easy-to-use clawpack driver routine for simple applications c c Author: Randall J. LeVeque c Version of March, 1999 -- CLAWPACK Version 4.0 c implicit double precision (a-h,o-z) external bc1,rp1,src1 dimension q(1-mbc:maxmx+mbc, meqn) dimension aux(1-mbc:maxmx+mbc, maux) dimension work(mwork) dimension mthlim(mwaves) c dimension method(7),dtv(5),cflv(4),nv(2),mthbc(2) dimension tout(100) logical outt0 c open(55,file='claw1ez.data',status='old',form='formatted') open(10,file='fort.info',status='unknown',form='formatted') open(11,file='fort.nplot',status='unknown',form='formatted') c c c # Read the input in standard form from input.claw: c # See input.doc for description of each input variable c Number of grid cells: read(55,*) mx c i/o variables read(55,*) nout read(55,*) outstyle if (outstyle.eq.1) read(55,*) tfinal if (outstyle.eq.2) read(55,*) (tout(i), i=1,nout) if (outstyle.eq.3) read(55,*) nsteps c timestepping variables read(55,*) dtv(1) read(55,*) dtv(2) read(55,*) cflv(1) read(55,*) cflv(2) read(55,*) nv(1) c c # input parameters for clawpack routines read(55,*) method(1) read(55,*) method(2) read(55,*) method(3) read(55,*) method(4) read(55,*) method(5) read(55,*) method(6) read(55,*) method(7) read(55,*) meqn1 read(55,*) mwaves1 read(55,*) (mthlim(mw), mw=1,mwaves) c # physical domain: read(55,*) t0 read(55,*) xlower read(55,*) xupper c c # boundary conditions: read(55,*) mbc1 read(55,*) mthbc(1) read(55,*) mthbc(2) if (method(7) .ne. maux) then write(6,*) '*** ERROR *** maux set wrong in input or driver' stop endif if (meqn1 .ne. meqn) then write(6,*) '*** ERROR *** meqn set wrong in input or driver' stop endif if (mwaves1 .ne. mwaves) then write(6,*) '*** ERROR *** mwaves set wrong in input or driver' stop endif if (mbc1 .ne. mbc) then write(6,*) '*** ERROR *** mbc set wrong in input or driver' stop endif c if ((mthbc(1).eq.2 .and. mthbc(2).ne.2) .or. & (mthbc(2).eq.2 .and. mthbc(1).ne.2)) then write(6,*) '*** ERROR *** periodic boundary conditions require' write(6,*) ' mthbc(1) and mthbc(2) BOTH be set to 2' stop endif c c # check that enough storage has been allocated: c mwork1 = (maxmx + 2*mbc) * (2 + 4*meqn + mwaves + meqn*mwaves) c if (mx.gt.maxmx .or. mwork.lt.mwork1) then c # insufficient storage maxmx1 = max0(mx,maxmx) mwork1 = (maxmx1 + 2*mbc) * (2 + 4*meqn + mwaves + meqn*mwaves) write(6,*) ' ' write(6,*) '*** ERROR *** Insufficient storage allocated' write(6,*) 'Recompile after increasing values in driver.f:' write(6,611) maxmx1 write(6,613) mwork1 611 format(/,'parameter (maxmx = ',i5,')') 613 format('parameter (mwork = ',i7,')',/) stop endif c c write(6,*) 'running...' write(6,*) ' ' c c # grid spacing dx = (xupper - xlower) / float(mx) c c # time increments between outputing solution: if (outstyle .eq. 1) then dtout = (tfinal - t0)/float(nout) endif c write(11,1101) nout c 1101 format(i5) c c # call user's routine setprob to set any specific parameters c # or other initialization required. c call setprob c c # set aux array: c if (maux .gt. 0) then call setaux(maxmx,mbc,mx,xlower,dx,maux,aux) endif c c # set initial conditions: c call qinit(maxmx,meqn,mbc,mx,xlower,dx,q,maux,aux) c outt0 = .true. if (outt0) then c # output initial data call out1(maxmx,meqn,mbc,mx,xlower,dx,q,t0,0) endif c c ---------- c Main loop: c ---------- c tend = t0 do 100 n=1,nout tstart = tend if (outstyle .eq. 2) then tend = tout(n) else tend = tstart + dtout endif c call claw1(maxmx,meqn,mwaves,mbc,mx, & q,aux,xlower,dx,tstart,tend,dtv,cflv,nv,method,mthlim, & mthbc,work,mwork,info,bc1,rp1,src1) c c # check to see if an error occured: if (info .ne. 0) then write(6,*) '*** ERROR in claw1 *** info =',info if (info.eq.1) then write(6,*) '*** either mx > maxmx or mbc < 2' endif if (info.eq.2) then write(6,*) '*** dt does not divide (tend - tstart)' write(6,*) '*** and dt is fixed since method(1)=0' endif if (info.eq.3) then write(6,*) '*** method(1)=1 and cflv(2) > cflv(1)' endif if (info.eq.4) then write(6,*) '*** mwork is too small' endif if (info.eq.11) then write(6,*) '*** Too many times steps, n > nv(1)' endif if (info.eq.12) then write(6,*) '*** The Courant number is greater than cflv(1)' write(6,*) '*** and dt is fixed since method(1)=0' endif go to 999 endif c dtv(1) = dtv(5) !# use final dt as starting value on next call c c # output solution at this time c ------------------------------ do 50 i=1,mx if (dabs(q(i,1)) .lt. 1d-90) q(i,1) = 0.d0 50 continue c call out1(maxmx,meqn,mbc,mx,xlower,dx,q,tend,n) c c # write out information about this call to claw: c write(6,601) nv(2),tend,info 601 format('CLAW1 returning after ',i3,' steps, t =',e13.5, & ' info =',i3,/) c write(10,1010) tend,info,dtv(3),dtv(4),dtv(5), & cflv(3),cflv(4),nv(2) 1010 format('tend =',d15.4,/, & 'info =',i5,/,'smallest dt =',d15.4,/,'largest dt =', & d15.4,/,'last dt =',d15.4,/,'largest cfl =', & d15.4,/,'last cfl =',d15.4,/,'steps taken =',i4,/) c 100 continue c 999 continue c return end c c c ========================================================= subroutine out1(maxmx,meqn,mbc,mx,xlower,dx,q,t,iframe) c ========================================================= c c # Output the results for a general system of conservation laws c # in 1 dimension c implicit double precision (a-h,o-z) dimension q(1-mbc:maxmx+mbc, meqn) character*10 fname1, fname2 c c # Write the results to the file fort.q