You are on page 1of 20

Nonlinear Conservation

equations: Practice

Warm-up Codlets:

Bur.f: Burgers equation


KPZ.f: KPZ equation
Sand.f: sandpile model

Sauro Succi
Burgers codlet

The codlet bur.f employs simple centered differences


More sophisticated schemes can be applied based
On what we learned with continuity equations.
Bur.f

c Solve the Burgers equation by a simple centered FD scheme,


c possibly with Lax variant and dynamic time-stepping
c Disclaimer: just a warm-up codlet, not intended for production
runs.
c Sauro Succi AC274, Fall 2016
c =====================================================
parameter (nx=100)
dimension u(0:nx+1),unew(0:nx+1)
logical lax
c -----------------------------------
open(36,file='movie.out')
open(37,file='spacetime.out')
c -----------------------------------------------
Bur.f: 2
dt = 0.1
dx = 1.0
vis = 0.1
cfl = 0.1
dtd = 1.0
if(vis.ne.0.0) dtd = 0.5*dx*dx/dif
NT = 1000
sigma = nx/10
lax = .true.
umax = -9.e19
do j=0,nx+1
x = float(j-nx/2)/sigma
u(j) = sin(4.*x)
u(j) = exp(-0.5*x*x)
if(abs(u(j)).gt.umax) umax = abs(u(j))
end do
c now estimate advective CFL
dta = 1.0
if(umax.ne.0.) dta = dx/umax
dt = cfl*min(dta,dtd)
write(6,*) 'dx,dt', dx,dt
Bur.f: 3
c time evolution
do it=1,NT
u(0) = u(nx)
u(nx+1) = u(1)
do j=1,nx
uj = u(j)
c Lax variant
if(lax.eqv..true.) uj=0.5*(u(j-1)+u(j+1))
c the CFL coeff's must be updated in case dt has changed
alfa = uj*dt/dx
delta = vis*dt/(dx*dx)
a = 0.5*alfa+delta
b = -0.5*alfa+delta
c = 1.0-a-b
unew(j) = a*u(j-1)+c*u(j)+b*u(j+1)
end do
Bur.f: 4

c prepare new timestep


umax = -1.e19
do j=1,nx
u(j) = unew(j)
if(abs(u(j)).gt.umax) umax = abs(u(j))
end do
dta = dx/umax
dt = cfl*min(dta,dtd)
alfa = uj*dt/dx
Bur.f: 5

if(mod(it,10).eq.1) then
do j=1,nx
write(36,*) j,u(j)
write(37,*) it,j,u(j)
end do
write(36,'(bn)')
write(36,'(bn)')
write(37,'(bn)')
endif
write(6,*) 'max velocity, dt',umax,dt

end do

stop
end
Kardar-Parisi-Zhang

The codlet kpz.f solves the 1d kpz equation with


simple centered differences.
The stochastic noise is treated by a simple Euler scheme,
More sophisticated method can be found in the huge
literature for stochastic PDEs
KPZ.f: 1
c Solve the KPZ equation with centered FD
c Disclaimer: just a warm-up codlet, not intended for production runs.
c Sauro Succi AC274, Fall 2016
c =====================================================
implicit double precision (a-h,o-z)
parameter (nx=100)
dimension h(0:nx+1),hnew(0:nx+1)
real lam
c ----------------------------------------------
open(9,file='mom.out')
open(50,file='movie.out')
c ----------------------------------------
KPZ.f: 2
nstep = 1000
nout = 2
nreal = 1 ! number of realizations, just 1 for now
c this time we don't do CFL, but take lattice units dx=dt=1
dt = 1.0
dx = 1.0
dif = 0.1 !
lam = 0.1 ! nonlinearity lambda
ramp = 0.5 ! noise amplitude, play with it
h0 = 1.0 ! initial average height
delta = dif*dt/dx/dx
iseed = 95315571
iout = 30
c initial conditions
do i=0,nx+1
h(i) = 2.*h0*ranpang(iseed)
end do
KPZ.f: 3
C loop over many random realizations
do ir=1,nreal
iseed = iseed + ir ! seed of random generator
t = 0.
do it=0,nstep
c periodic bc
h(0) = h(nx)
h(nx+1) = h(1)
c update
do i=1,nx
g = 0.5*(h(i+1)-h(i-1))/dx ! slope
a = delta
b = delta
c = 1.0-a-b
r = ramp*(2.*ranpang(iseed)-1.) ! ramp is adjusted empirically
hnew(i) = a*h(i-1)+c*h(i)+b*h(i+1)
$ + lam*g*g*dt + r*sqrt(dt)/dx

end do
KPZ.f: 4
c advance to next time step
t = t+dt
do i=1,nx
h(i) = hnew(i)
end do
c diagnostics ----------------------------------------------
htot = 0.
hvar = 0.
hlen = 0.
do i=1,nx
g = 0.5*(h(i+1)-h(i-1))/dx
htot = htot + h(i)
hvar = hvar + h(i)*h(i)
hlen = hlen + sqrt(1.0+g*g)*dx
end do
aveh = htot/nx
wid = sqrt(hvar/nx-aveh*aveh)
write(6,*) 'it,t,aveh,width,length',it,t,aveh,wid,hlen
write(9,*) t,aveh,wid,hlen
KPZ.f: 5
c movie for postproc
if(mod(it,nout).eq.0) then
do i=1,nx
write(50,*) i,h(i)
end do
write(50,'(bn)')
write(50,'(bn)')
endif
c -----------------------------------------------------
end do ! end evolution
c end realizations
write(6,*) 'Final time of realization ', ir, t
end do

stop
end
KPZ.f: 6
function ranpang(iseed)
c random number generator, from Pang, p.47
implicit double precision (a-h,o-z)
i2e30 = 2**30
ia=16807
ic=i2e30-1 ! ic=2**31-1, but 2**31 is a overflow
ic=ic+i2e30
iq=ic/ia
ir=mod(ic,ia)
ih=iseed/iq
il=mod(iseed,iq)
it=ia*il-ir*ih
if(it.gt.0) then
iseed=it
else
iseed=it+ic
endif
ranpang=iseed/float(ic)
return
end
Sandpile cellular automaton

The codlet sand.f illustrates the simple sandpile


Cellular automaton with four neighbors.
It is eaily generalized to more
sophisticated variants with 8 or more neighbors.
The evolution depends strongly on initial conditions
And also the rainfall rate as typical of
Nonlinear Driven Dissipative systems.
Sand.f: 1

c Sandpile cellular automaton


c Disclaimer: just a warm-up codlet,
c not intended for production runs.
c Sauro Succi AC274, Fall 2016
c =====================================================
implicit double precision (a-h,o-z)
parameter (nx=8,ny=8)
integer h(0:nx+1,0:ny+1),hrain
c --------------------------------
open(9,file='diagno.out')
open(36,file='movie.out')
Sand.f: 2

Nsteps = 100
hrain = 2 ! play with it
c initial configuration: empty, play wit it
do j=0,ny+1
do i=0,nx+1
h(i,j)=int(0*rand())
end do
end do
Sand.f: 3
c time evolution
do it=1,Nsteps
c load the central site (you may want to load a site at random)
ir = nx/2
jr = ny/2
h(ir,jr)=h(ir,jr)+hrain
c the boundary buffers collect the outgoing flux from the bulk
do j=1,ny
do i=1,nx
if(h(i,j).gt.4) then
h(i,j) = h(i,j)-4
h(i+1,j)=h(i+1,j)+1
h(i-1,j)=h(i-1,j)+1
h(i,j+1)=h(i,j+1)+1
h(i,j-1)=h(i,j-1)+1
endif
end do
end do
Sand.f: 4
c diagnostic
htot = 0
do j=0,ny+1
do i=0,nx+1
htot = htot + h(i,j)
write(36,*) i,j,h(i,j)
end do
write(36,'(bn)')
end do
write(36,'(bn)')
write(36,'(bn)’)
write(6,*), it,htot,ir,jr,h(ir,jr)
write(9,*), it,htot,h(ir,jr)
end do

stop
end
End of the Lecture

Enjoy the sim’s!

You might also like