In [17]:
import sympy
import numpy
import matplotlib.pyplot as plt
%matplotlib inline
from matplotlib import rcParams
rcParams['font.family'] = 'serif'
rcParams['font.size'] = 16
from sympy import init_printing
from sympy.utilities.lambdify import lambdify
init_printing()
from JSAnimation.IPython_display import display_animation
from matplotlib import animation
In [18]:
V_max = 136 # km/hr. The maximum velocity of cars on the road.
L = 11 # km. The length of the stretch of road.
rho_max = 250 # cars/km. Maximum density of cars before traffic stops.
nx = 51 # number of grid points in the x direction
dt = 0.001 # hours.
sigma = 0.5 # CFL number we use.
BG_VAL = 20 # The background value used for initial data (see below)
In [19]:
hours = lambda minutes: minutes/60.
minutes = lambda hours: hours*60.
mps = lambda kph: (1000./3600.)*kph # cast km/h to m/s
V = lambda rho: V_max * (1 - (rho/rho_max))
flux = lambda rho: V(rho)*rho
In [20]:
x = numpy.linspace(0,L,nx)
dx = x[1]-x[0]
print "dx = ",dx
In [21]:
def rhs(rho):
"""
given the equation
d rho/dt = f(rho)
returns f(rho)
Inputs:
--- rho, a vector of floats of lenth nx.
Returns:
drho/dt on the grid excluding the zeroth element, which is not set
"""
F = flux(rho)
return -(F[1:]-F[:-1])/dx
In [22]:
def time_step(rho,rho0):
"""
Given rho at time t, return rho at time t+dt
Inputs:
--- rho, rho(x) at time t
--- rho0, the boundary condition, rho(x=0) for all t
"""
out = numpy.empty_like(rho)
out[1:] = rho[1:] + dt*rhs(rho)
out[0] = rho0
return out
In [23]:
def initial_data(background):
"""
Given an array x, returns an array rho(x) at time 0.
Initial configuration is a tophat function
rho(x[i]) = 50 if 10 <= i <= 20
rho(x[i]) = background otherwise
"""
rho0 = numpy.ones(nx)*background
rho0[10:20] = 50
return rho0
In [24]:
def integrate(rho0_background,t_f,rho0):
"""
Integrate the system from time t0 = 0 to time t_f.
Inputs:
--- rho0_background, "background" in initial data function
--- t_f, the final time we integrate to.
--- rho0, the boundary condition, rho(x=0) for all t
"""
t = numpy.arange(0,t_f,dt)
rho = numpy.empty((len(t),nx))
rho[0] = initial_data(rho0_background)
for i in range(1,len(t)):
rho[i] = time_step(rho[i-1],rho0)
return t,rho
In [25]:
def make_animation(x,t,rho):
"""
Animate our traffic solution given an analytic solution
rho(x,t) given by the arrays x,t,rho
"""
In [26]:
t,rho=integrate(BG_VAL,hours(7),BG_VAL)
Find indices for times we care about:
In [27]:
i3 = numpy.where(minutes(t)==3)[0][0]
i6 = numpy.where(minutes(t)==6)[0][0]
print i3,i6
Find velocities we care about.
In [30]:
print "Minimum velocity at time zero is: {} m/s".format(mps(numpy.min(V(rho[0]))))
print "Average velocity at time t=3 minutes is: {} m/s".format(mps(numpy.mean(V(rho[i3]))))
print "Minimum velocity at time t=3 minutes is: {} m/s".format(mps(numpy.min(V(rho[i3]))))
print "Minimum velocity at time t=6 minutes is: {} m/s".format(mps(numpy.min(V(rho[i6]))))
In [29]:
fig = plt.figure(figsize=(11,8))
ax = plt.axes(xlim=(0,L),ylim=(0,1.1*numpy.max(rho)))
line = ax.plot([],[],lw=2)[0]
time_text = ax.text(0.1*x[-1],0.9*numpy.max(rho),'',
transform=ax.transAxes)
def init():
line.set_data([],[])
time_text.set_text('')
return line,time_text
def animate(i):
line.set_data(x,rho[i])
time_text.set_text('t = {}'.format(t[i]))
return line,time_text
animation.FuncAnimation(fig,animate,frames=len(t),
init_func=init,interval=100)
Out[29]:
In [29]: