You are on page 1of 19

Conservative Equations: Practice

Sauro Succi

Sample codlets for the 1d continuity equation:

Conti.f (Centered and Upwind)

Shasta.f (SHASTA)
Conti.1

c Solve the 1d continuity equation using centered and upwind


c periodic boundary conditions (thru buffers at j=0 and j=NX+1)
c
c //////////////////////////////////////////////////////
c Disclaimer: Just a warm-up example, not a fully
debugged/validated
c no liability is taken for improper use
c S. Succi, AC274, Fall semester 2016
c ----------------------------------------------------------
Conti.2
parameter (NX=100,NM=4)
dimension x(NX),u(0:NX+1),f(0:NX+1),fnew(0:NX+1)
dimension def(NX)
dimension fmom(0:NM),hent(0:NM)
c --------------------------------------
open(31,file='moment.out')
open(32,file='entropy.out')
open(36,file='movie.out')
c --------------------------------------
c baseline parameters and input data
c ifd=0 centered, ifd=1 upwind
write(6,*) 'enter ifd'
read(5,*) ifd
write(6,*) ifd
Nsteps = 100
nout = 2 ! output every 10 steps
sizex = 1.0
dif = 0.0
vel = 0.1
adif = -0.125 ! antidiffusion
dx = sizex/float(nx-1)
Conti.3

c CFL numbers fix the timestep


cfl = 0.1
dtd = 1.0
if(dif.ne.0.0) dtd = dx*dx/dif
if(vel.ne.0.0) dta = dx/vel
dt = cfl*min(dta,dtd)
write(6,*) 'dx and dt',dx,dt
delta = dif*dt/(dx*dx)
Conti.4
c initial conditions: unnormalized (play with them)
wid = 4
sigma = wid*dx ! play with width
xm = 0.5*(sizex-sigma)
xp = 0.5*(sizex+sigma)
do j=1,NX
x(j) = dx*float(j-1)
c xj = (x(j)-sizex/2)/sigma
c f(j) = exp(-0.5*xj*xj)
c box
f(j) = 0.0
if(x(j).gt.xm.and.x(j).lt.xp) f(j) = 1.0
xj = (x(j)-sizex/2)/(sizex/2)
u(j) = vel*(1-xj*xj)
end do
u(0) = u(nx)
u(nx+1) = u(1)
Conti.5
c time-stepper ---------------------------------
do it=1,Nsteps
f(0) = f(nx)
f(nx+1) = f(1)
do j=1,NX
alfal = u(j-1)*dt/dx
alfac = u(j)*dt/dx
alfar = u(j+1)*dt/dx
c build the tridiagonal coefficients
if(ifd.eq.0) then
c centered conservative (unstable)
a = delta+0.5*alfal
b = delta-0.5*alfar
c = 1.0-2.0*delta
fnew(j) = a*f(j-1)+c*f(j)+b*f(j+1)
endif
Conti.6
c upwind -----------------------------
if(ifd.eq.1) then
if(u(j).gt.0) then
a = alfal+delta ! f(j)-f(j-1)
b = delta
c = 1.-alfac-2.0*delta
else ! f(j+1)-f(j)
a = delta
b = delta-alfar
c = 1.0+alfac-2.0*delta
endif
fnew(j) = a*f(j-1)+c*f(j)+b*f(j+1)
endif
end do
c prepare for new timestep
do j=1,NX
f(j) = fnew(j)
end do
Conti.7
c diagnostics: standard moments, tail moment and entropies
if(mod(it,nout).eq.0) then
do m=0,NM
fmom(m) = 0.0
hent(m) = 0.0
end do
xmom = 0.0
do j=1,NX
fj = f(j)*dx
fmom(0) = fmom(0) + fj
fmom(1) = fmom(1) + fj*x(j)
fmom(2) = fmom(2) + fj*x(j)*x(j)

hent(2) = hent(2) - fj*fj


hent(3) = hent(3) - fj*fj*fj
hent(4) = hent(4) - fj*fj*fj*fj
c probe the tail, should grow exponentially in time
if(x(j).gt.0.99*sizex) xmom=xmom+fj
c output for gnuplot movies
write(36,*) j,f(j),u(j)
end do
Conti.8
c blank lines for gnuplot movies
write(36,'(bn)')
write(36,'(bn)')
c monitor the moments in time
fmean = fmom(1)/fmom(0)
fvar = fmom(2)/fmom(0)-fmean*fmean
write(31,*),
it,fmom(0),fmean,fvar,xmom/fmom(0)
write(32,*), it,hent(2),hent(3),hent(4)
endif
write(6,*) 'completed time
step',it,fmom(0)
c end evolution -----------------------------------------
------------
end do

stop
end
SHASTA.1

c Solve the 1d continuity equation using


SHASTA
c periodic boundary conditions (thru buffers
at j=0 and j=NX+1)
c
/////////////////////////////////////////////////
////////////////////
c Disclaimer: Just a warm-up example, not a
fully debugged/validated
c no liability is taken for improper use
c S. Succi, AC274, Fall semester 2016
SHASTA.2
open(31,file='moment.out')
open(32,file='entropy.out')
open(36,file='movie.out')
c baseline parameters and input data
c 0: no antidif, no limiter, 1: antidif only, 2:
antidif+limiter
write(6,*) 'enter shasta option'
read(5,*) lop
write(6,*) lop
Nsteps = 100
nout = 2 ! output every 10 steps
sizex = 1.0
dif = 0.0
vel = 1.0
adif = -0.125 ! antidiffusion
dx = sizex/float(nx-1)
SHASTA.3

c CFL numbers fix the timestep


cfl = 0.1
dtd = 1.0
if(dif.ne.0.0) dtd = dx*dx/dif
if(vel.ne.0.0) dta = dx/vel
dt = cfl*min(dta,dtd)
write(6,*) 'dx and dt',dx,dt
delta = dif*dt/(dx*dx)
SHASTA.4
c initial conditions: unnormalized (play wity them)
sigma = 4.0*dx ! play with width
xm = 0.5*(sizex-sigma)
xp = 0.5*(sizex+sigma)
do j=1,NX
x(j) = dx*float(j-1)
c box
f(j) = 0.0
if(x(j).gt.xm.and.x(j).lt.xp) f(j) = 1.0
xj = (x(j)-sizex/2)/(sizex/2)
u(j) = vel*(1-xj*xj)
end do

c periodicity, note extra buffers because shasta


requires double-neighbor info
u(-1) = u(nx-1)
u(0) = u(nx)
u(nx+1) = u(1)
u(nx+2) = u(2)
SHASTA.5
c time-stepper ---------------------------------
do it=1,Nsteps
f(-1) = f(nx-1)
f(0) = f(nx)
f(nx+1) = f(1)
f(nx+2) = f(2)
do j=1,NX
alfal = u(j-1)*dt/dx
alfac = u(j)*dt/dx
alfar = u(j+1)*dt/dx
ql = (0.5+alfac)/(1.0-(alfal-alfac))
qr = (0.5-alfac)/(1.0+(alfar-alfac))
a = 0.5*ql*ql
b = 0.5*qr*qr
c = ql+qr-0.5*(ql*ql+qr*qr)

fnew(j) = a*f(j-1)+c*f(j)+b*f(j+1)
SHASTA.6

fluxl = 0.0
fluxr = 0.0
if (lop.eq.1) then
fluxr = abs(adif)*(f(j+1)-f(j))
fluxl = adif*(f(j-1)-f(j))
fnew(j) = fnew(j) + fluxl - fluxr
write(6,*) 'lop',lop, fluxl,fluxr
endif
SHASTA.7
c ***************************** WARNING !!!!
c This option is based on eq. 23 of Boris-Book paper
c I did not re-derive myself. Boris-Book only gives the
c rightward flux (fluxr) expression, so there might be an
c ambiguity/error in the way i constructed the left flux (fluxl)
c Their notation leaves several ambiguities on the signs of the fluxes
c so, although it seems to give reasonable results,
c I have no guarantee that the implementation is correct
c ****************************************
SHASTA.8
c flux limiter: compact form
dl1 = f(j-1)-f(j)
dl2 = f(j-2)-f(j-1)
dr1 = f(j+1)-f(j)
dr2 = f(j+2)-f(j+1)
sr1 = 0.0
if(abs(dr1).gt.0.) sr1 = dr1/abs(dr1)
sl1 = 0.0
if(abs(dl1).gt.0.) sl1 = dl1/abs(dl1)

fminr = min(min(dr1*sr1,abs(adif)*abs(dr1)),dr2*sr1)
fluxr = sr1*max(0.0,fminr)
fminl = min(min(dl1*sl1,adif*abs(dl1)),dl2*sl1)
fluxl = sl1*max(0.0,fminl)

fnew(j) = fnew(j) + fluxl fluxr


c prepare for new timestep
do j=1,NX
f(j) = fnew(j)
end do
SHASTA.9

The diagnostic part is exactly the same


as in all previous codlets
adr1.f page 7

Run and Enjoy!

Actual codlet: /PART1Codes/ADR/adr1.f