|
claw1.f.html |
|
|
Source file: claw1.f
|
|
Directory: /home/rjl/git/rjleveque/clawpack-4.x/clawpack/1d/lib
|
|
Converted: Sun May 15 2011 at 19:15:42
using clawcode2html
|
|
This documentation file will
not reflect any later changes in the source file.
|
c
c ==============================================================
subroutine claw1(maxmx,meqn,mwaves,mbc,mx,
& q,aux,xlower,dx,tstart,tend,dtv,cflv,nv,method,mthlim,
& mthbc,work,mwork,info,bc1,rp1,src1,b4step1)
c ==============================================================
c
c Solves a hyperbolic system of conservation laws in one space dimension
c of the general form
c
c capa * q_t + A q_x = psi
c
c The "capacity function" capa(x) and source term psi are optional
c (see below).
c
c For a more complete description see the documentation at
c http://www.amath.washington.edu/~claw
c
c Sample driver programs and user-supplied subroutines are available.
c See the the directories claw/clawpack/1d/example* for some examples, and
c codes in claw/applications for more extensive examples.
c
c --------------------------------------------------------
c
c The user must supply the following subroutines:
c
c bc1, rp1 subroutines specifying the boundary conditions and
c Riemann solver.
c These are described in greater detail below.
c
c b4step1 The routine b4step1 is called each time step and
c can be supplied by the user in order to perform
c other operations that are necessary every time
c step. For example, if the variables stored in
c the aux arrays are time-dependent then these
c values can be set.
c
c In addition, if the equation contains source terms psi, then the user
c must provide:
c
c src1 subroutine that solves capa * q_t = psi
c over a single time step.
c
c These routines must be declared EXTERNAL in the main program.
c For description of the calling sequences, see below.
c
c Dummy routines b4step1.f and src1.f are available in
c claw/clawpack/1d/lib
c
c
c
c Description of parameters...
c ----------------------------
c
c
c maxmx is the maximum number of interior grid points in x,
c and is used in declarations of the array q.
c
c meqn is the number of equations in the system of
c conservation laws.
c
c mwaves is the number of waves that result from the
c solution of each Riemann problem. Often mwaves = meqn but
c for some problems these may be different.
c
c mbc is the number of "ghost cells" that must be added on to each
c side of the domain to handle boundary conditions. The cells
c actually in the physical domain are labelled from 1 to mx in x.
c The arrays are dimensioned actually indexed from 1-mbc to mx+mbc.
c For the methods currently implemented, mbc = 2 should be used.
c If the user implements another method that has a larger stencil and
c hence requires more ghost cells, a larger value of mbc could be used.
c q is extended from the physical domain to the ghost cells by the
c user-supplied routine bc1.
c
c mx is the number of grid cells in the x-direction, in the
c physical domain. In addition there are mbc grid cells
c along each edge of the grid that are used for boundary
c conditions.
c Must have mx .le. maxmx
c
c q(1-mbc:maxmx+mbc, meqn)
c On input: initial data at time tstart.
c On output: final solution at time tend.
c q(i,m) = value of mth component in the i'th cell.
c Values within the physical domain are in q(i,m)
c for i = 1,2,...,mx
c mbc extra cells on each end are needed for boundary conditions
c as specified in the routine bc1.
c
c aux(1-mbc:maxmx+mbc, maux)
c Array of auxiliary variables that are used in specifying the problem.
c If method(7) = 0 then there are no auxiliary variables and aux
c can be a dummy variable.
c If method(7) = maux > 0 then there are maux auxiliary variables
c and aux must be dimensioned as above.
c
c Capacity functions are one particular form of auxiliary variable.
c These arise in some applications, e.g. variable coefficients in
c advection or acoustics problems.
c See Clawpack Note # 5 for examples.
c
c If method(6) = 0 then there is no capacity function.
c If method(6) = mcapa > 0 then there is a capacity function and
c capa(i), the "capacity" of the i'th cell, is assumed to be
c stored in aux(i,mcapa).
c In this case we require method(7).ge.mcapa.
c
c dx = grid spacing in x.
c (for a computation in ax <= x <= bx, set dx = (bx-ax)/mx.)
c
c tstart = initial time.
c
c tend = Desired final time (on input).
c If tend
c time step has been taken (single-step mode).
c Otherwise, as many steps are taken as needed to reach tend,
c up to a maximum of nv(1).
c = Actual time reached (on output).
c
c dtv(1:5) = array of values related to the time step:
c (Note: method(1)=1 indicates variable size time steps)
c dtv(1) = value of dt to be used in all steps if method(1) = 0
c = value of dt to use in first step if method(1) = 1
c dtv(2) = unused if method(1) = 0.
c = maximum dt allowed if method(1) = 1.
c dtv(3) = smallest dt used (on output)
c dtv(4) = largest dt used (on output)
c dtv(5) = dt used in last step (on output)
c
c cflv(1:4) = array of values related to Courant number:
c cflv(1) = maximum Courant number to be allowed. With variable
c time steps the step is repeated if the Courant
c number is larger than this value. With fixed time
c steps the routine aborts. Usually cflv(1)=1.0
c should work.
c cflv(2) = unused if method(1) = 0.
c = desired Courant number if method(1) = 1.
c Should be somewhat less than cflv(1), e.g. 0.9
c cflv(3) = largest Courant number observed (on output).
c cflv(4) = Courant number in last step (on output).
c
c nv(1:2) = array of values related to the number of time steps:
c nv(1) = unused if method(1) = 0
c = maximum number of time steps allowed if method(1) = 1
c nv(2) = number of time steps taken (on output).
c
c method(1:7) = array of values specifying the numerical method to use
c method(1) = 0 if fixed size time steps are to be taken.
c In this case, dt = dtv(1) in all steps.
c = 1 if variable time steps are to be used.
c In this case, dt = dtv(1) in the first step and
c thereafter the value cflv(2) is used to choose the
c next time step based on the maximum wave speed seen
c in the previous step. Note that since this value
c comes from the previous step, the Courant number will
c not in general be exactly equal to the desired value
c If the actual Courant number in the next step is
c greater than 1, then this step is redone with a
c smaller dt.
c
c method(2) = 1 if Godunov's method is to be used, with no 2nd order
c corrections.
c = 2 if second order correction terms are to be added, with
c a flux limiter as specified by mthlim.
c
c method(3) is not used in one-dimension.
c
c method(4) = 0 to suppress printing
c = 1 to print dt and Courant number every time step
c
c method(5) = 0 if there is no source term psi. In this case
c the subroutine src1 is never called so a dummy
c parameter can be given.
c = 1 if there is a source term. In this case
c the subroutine src1 must be provided and a
c fractional step method is used.
c In each time step the following sequence is followed:
c call bc to extend data to ghost cells
c call step1 to advance hyperbolic eqn by dt
c call src1 to advance source terms by dt
c = 2 if there is a source term and Strang splitting is to
c be used instead of the Godunov splitting above.
c In each time step the following sequence is followed:
c call bc to extend data to ghost cells
c call src1 to advance source terms by dt/2
c call step1 to advance hyperbolic equation by dt
c call src1 to advance source terms by dt/2
c For most problems 1 is recommended rather than 2
c since it is less expensive and works essentially as
c well on most problems.
c
c method(6) = 0 if there is no capacity function capa.
c = mcapa > 0 if there is a capacity function. In this case
c aux(i,mcapa) is the capacity of the i'th cell and you
c must also specify method(7) .ge. mcapa and set aux.
c
c method(7) = 0 if there is no aux array used.
c = maux > 0 if there are maux auxiliary variables.
c
c
c The recommended choice of methods for most problems is
c method(1) = 1, method(2) = 2.
c
c mthlim(1:mwaves) = array of values specifying the flux limiter to be used
c in each wave family mw. Often the same value will be used
c for each value of mw, but in some cases it may be
c desirable to use different limiters. For example,
c for the Euler equations the superbee limiter might be
c used for the contact discontinuity (mw=2) while another
c limiter is used for the nonlinear waves. Several limiters
c are built in and others can be added by modifying the
c subroutine philim.
c
c mthlim(mw) = 0 for no limiter
c = 1 for minmod
c = 2 for superbee
c = 3 for van Leer
c = 4 for monotonized centered
c
c
c work(mwork) = double precision work array of length at least mwork
c
c mwork = length of work array. Must be at least
c (maxmx + 2*mbc) * (2 + 4*meqn + mwaves + meqn*mwaves)
c If mwork is too small then the program returns with info = 4
c and prints the necessary value of mwork to unit 6.
c
c
c info = output value yielding error information:
c = 0 if normal return.
c = 1 if mx.gt.maxmx or mbc.lt.2
c = 2 if method(1)=0 and dt doesn't divide (tend - tstart).
c = 3 if method(1)=1 and cflv(2) > cflv(1).
c = 4 if mwork is too small.
c = 11 if the code attempted to take too many time steps, n > nv(1).
c This could only happen if method(1) = 1 (variable time steps).
c = 12 if the method(1)=0 and the Courant number is greater than 1
c in some time step.
c
c Note: if info.ne.0, then tend is reset to the value of t actually
c reached and q contains the value of the solution at this time.
c
c User-supplied subroutines
c -------------------------
c
c bc1 = subroutine that specifies the boundary conditions.
c This subroutine should extend the values of q from cells
c 1:mx to the mbc ghost cells along each edge of the domain.
c
c The form of this subroutine is
c -------------------------------------------------
c subroutine bc1(maxmx,meqn,mbc,mx,xlower,dx,q,maux,aux,t,mthbc)
c implicit double precision (a-h,o-z)
c dimension q(1-mbc:maxmx+mbc, meqn)
c dimension aux(1-mbc:maxmx+mbc, *)
c dimension mthbc(2)
c -------------------------------------------------
c
c The routine claw/clawpack/1d/lib/bc1.f can be used to specify
c various standard boundary conditions.
c
c
c rp1 = user-supplied subroutine that implements the Riemann solver
c
c The form of this subroutine is
c -------------------------------------------------
c subroutine rp1(maxmx,meqn,mwaves,mbc,mx,ql,qr,auxl,auxr,wave,s,amdq,apdq)
c implicit double precision (a-h,o-z)
c dimension ql(1-mbc:maxmx+mbc, meqn)
c dimension qr(1-mbc:maxmx+mbc, meqn)
c dimension auxl(1-mbc:maxmx+mbc, *)
c dimension auxr(1-mbc:maxmx+mbc, *)
c dimension wave(1-mbc:maxmx+mbc, meqn, mwaves)
c dimension s(1-mbc:maxmx+mbc, mwaves)
c dimension amdq(1-mbc:maxmx+mbc, meqn)
c dimension apdq(1-mbc:maxmx+mbc, meqn)
c -------------------------------------------------
c
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 auxl contains auxiliary values at the left edge of each cell
c auxr contains auxiliary values at the right edge of each cell
c
c Note that the i'th Riemann problem has left state qr(i-1,:)
c and right state ql(i,:)
c In the standard clawpack routines, this Riemann solver is
c called with ql=qr=q along this slice. More flexibility is allowed
c in case the user wishes to implement another solution method
c that requires left and rate states at each interface.
c If method(7)=maux > 0 then the auxiliary variables along this slice
c are passed in using auxl and auxr. Again, in the standard routines
c auxl=auxr=aux in the call to rp1.
c
c On output,
c wave(i,m,mw) is the m'th component of the jump across
c wave number mw in the ith Riemann problem.
c s(i,mw) is the wave speed of wave number mw in the
c ith Riemann problem.
c amdq(i,m) = m'th component of A^- Delta q,
c apdq(i,m) = m'th component of A^+ Delta q,
c the decomposition of the flux difference
c f(qr(i-1)) - f(ql(i))
c into leftgoing and rightgoing parts respectively.
c
c It is assumed that each wave consists of a jump discontinuity
c propagating at a single speed, as results, for example, from a
c Roe approximate Riemann solver. An entropy fix can be included
c into the specification of amdq and apdq.
c
c src1 = subroutine for the source terms that solves the equation
c capa * q_t = psi
c over time dt.
c
c If method(5)=0 then the equation does not contain a source
c term and this routine is never called. A dummy argument can
c be used with many compilers, or provide a dummy subroutine that
c does nothing (such a subroutine can be found in
c claw/clawpack/1d/lib/src1.f)
c
c The form of this subroutine is
c -------------------------------------------------
c subroutine src1(maxmx,meqn,mbc,mx,xlower,dx,q,maux,aux,t,dt)
c implicit double precision (a-h,o-z)
c dimension q(1-mbc:maxmx+mbc, meqn)
c dimension aux(1-mbc:maxmx+mbc, *)
c -------------------------------------------------
c If method(7)=0 or the auxiliary variables are not needed in this solver,
c then the latter dimension statement can be omitted, but aux should
c still appear in the argument list.
c
c On input, q(i,m) contains the data for solving the
c source term equation.
c On output, q(i,m) should have been replaced by the solution to
c the source term equation after a step of length dt.
c
c
c b4step1 = subroutine that is called from claw1 before each call to
c step1. Use to set time-dependent aux arrays or perform
c other tasks which must be done every time step.
c
c The form of this subroutine is
c
c -------------------------------------------------
c subroutine b4step1(maxmx,mbc,mx,meqn,q,xlower,dx,time,dt,maux,aux)
c implicit double precision (a-h,o-z)
c dimension q(1-mbc:maxmx+mbc, meqn)
c dimension aux(1-mbc:maxmx+mbc, *)
c -------------------------------------------------
c
c
c
c
c =========================================================================
c
c Copyright 1994 -- 2002 R. J. LeVeque
c
c This software is made available for research and instructional use only.
c You may copy and use this software without charge for these non-commercial
c purposes, provided that the copyright notice and associated text is
c reproduced on all copies. For all other uses (including distribution of
c modified versions), please contact the author at the address given below.
c
c *** This software is made available "as is" without any assurance that it
c *** will work for your purposes. The software may in fact have defects, so
c *** use the software at your own risk.
c
c --------------------------------------
c CLAWPACK Version 4.1, August, 2002
c Webpage: http://www.amath.washington.edu/~claw
c --------------------------------------
c Author: Randall J. LeVeque
c Applied Mathematics
c Box 352420
c University of Washington,
c Seattle, WA 98195-2420
c rjl@amath.washington.edu
c =========================================================================
c
c
c
c
c ======================================================================
c Beginning of claw1 code
c ======================================================================
c
implicit double precision (a-h,o-z)
external bc1,rp1,src1,b4step1
dimension q(1-mbc:maxmx+mbc, meqn)
dimension aux(1-mbc:maxmx+mbc, *)
dimension work(mwork)
dimension mthlim(mwaves),method(7),dtv(5),cflv(4),nv(2)
dimension mthbc(2)
common /comxt/ dtcom,dxcom,tcom
c
c
info = 0
t = tstart
maxn = nv(1)
dt = dtv(1) !# initial dt
cflmax = 0.d0
dtmin = dt
dtmax = dt
nv(2) = 0
maux = method(7)
c
c # check for errors in data:
c
if (mx .gt. maxmx) then
info = 1
go to 900
endif
c
if (method(1) .eq. 0) then
c # fixed size time steps. Compute the number of steps:
if (tend .lt. tstart) then
c # single step mode
maxn = 1
else
maxn = (tend - tstart + 1d-10) / dt
if (dabs(maxn*dt - (tend-tstart)) .gt.
& 1d-5*(tend-tstart)) then
c # dt doesn't divide time interval integer number of times
info = 2
go to 900
endif
endif
endif
c
if (method(1).eq.1 .and. cflv(2).gt.cflv(1)) then
info = 3
go to 900
endif
c
c # partition work array into pieces for passing into step1:
i0f = 1
i0wave = i0f + (maxmx + 2*mbc) * meqn
i0s = i0wave + (maxmx + 2*mbc) * meqn * mwaves
i0dtdx = i0s + (maxmx + 2*mbc) * mwaves
i0qwork = i0dtdx + (maxmx + 2*mbc)
i0amdq = i0qwork + (maxmx + 2*mbc) * meqn
i0apdq = i0amdq + (maxmx + 2*mbc) * meqn
i0dtdx = i0apdq + (maxmx + 2*mbc) * meqn
i0end = i0dtdx + (maxmx + 2*mbc) - 1
c
if (mwork .lt. i0end) then
write(6,*) 'mwork must be increased to ',i0end
info = 4
go to 900
endif
c
c -----------
c # main loop
c -----------
c
if (maxn.eq.0) go to 900
do 100 n=1,maxn
told = t !# time at beginning of time step.
c # adjust dt to hit tend exactly if we're near end of computation
c # (unless tend < tstart, which is a flag to take only a single step)
if (told+dt.gt.tend .and. tstart.lt.tend) dt = tend - told
if (method(1).eq.1) then
c # save old q in case we need to retake step with smaller dt:
call copyq1(maxmx,meqn,mbc,mx,q,work(i0qwork))
endif
c
40 continue
dt2 = dt / 2.d0
thalf = t + dt2 !# midpoint in time for Strang splitting
t = told + dt !# time at end of step
c # store dt and t in the common block comxt in case they are needed
c # in the Riemann solvers (for variable coefficients)
tcom = told
dtcom = dt
dxcom = dx
c
c ------------------------------------------------------------------
c # main steps in algorithm:
c ------------------------------------------------------------------
c
c # extend data from grid to bordering boundary cells:
call bc1(maxmx,meqn,mbc,mx,xlower,dx,q,maux,aux,told,dt,mthbc)
c
c
c # call user-supplied routine which might set aux arrays
c # for this time step, for example.
call b4step1(maxmx,mbc,mx,meqn,q,
& xlower,dx,told,dt,maux,aux)
c
c
if (method(5).eq.2) then
c # with Strang splitting for source term:
call src1(maxmx,meqn,mbc,mx,xlower,dx,q,maux,aux,told,dt2)
endif
c
c # take a step on the homogeneous conservation law:
call step1(maxmx,meqn,mwaves,mbc,mx,q,aux,dx,dt,
& method,mthlim,cfl,work(i0f),work(i0wave),
& work(i0s),work(i0amdq),work(i0apdq),work(i0dtdx),
& rp1)
c
if (method(5).eq.2) then
c # source terms over a second half time step for Strang splitting:
c # Note it is not so clear what time t should be used here if
c # the source terms are time-dependent!
call src1(maxmx,meqn,mbc,mx,xlower,dx,q,maux,aux,thalf,dt2)
endif
if (method(5).eq.1) then
c # source terms over a full time step:
call src1(maxmx,meqn,mbc,mx,xlower,dx,q,maux,aux,t,dt)
endif
c
c
c ------------------------------------------------------------------
c
if (method(4) .eq. 1) write(6,601) n,cfl,dt,t
601 format('CLAW1... Step',i4,
& ' Courant number =',f6.3,' dt =',d12.4,
& ' t =',d12.4)
c
if (method(1) .eq. 1) then
c # choose new time step if variable time step
if (cfl .gt. 0.d0) then
dt = dmin1(dtv(2), dt * cflv(2)/cfl)
dtmin = dmin1(dt,dtmin)
dtmax = dmax1(dt,dtmax)
else
dt = dtv(2)
endif
endif
c
c # check to see if the Courant number was too large:
c
if (cfl .le. cflv(1)) then
c # accept this step
cflmax = dmax1(cfl,cflmax)
else
c # reject this step
t = told
call copyq1(maxmx,meqn,mbc,mx,work(i0qwork),q)
c
if (method(4) .eq. 1) then
write(6,602)
602 format('CLAW1 rejecting step... ',
& 'Courant number too large')
endif
if (method(1).eq.1) then
c # if variable dt, go back and take a smaller step
go to 40
else
c # if fixed dt, give up and return
cflmax = dmax1(cfl,cflmax)
go to 900
endif
endif
c
c # see if we are done:
nv(2) = nv(2) + 1
if (t .ge. tend) go to 900
c
100 continue
c
900 continue
c
c # return information
c
if (method(1).eq.1 .and. t.lt.tend .and. nv(2) .eq. maxn) then
c # too many timesteps
info = 11
endif
c
if (method(1).eq.0 .and. cflmax .gt. cflv(1)) then
c # Courant number too large with fixed dt
info = 12
endif
tend = t
cflv(3) = cflmax
cflv(4) = cfl
dtv(3) = dtmin
dtv(4) = dtmax
dtv(5) = dt
return
end