Path: blob/main/latex-templates/templates/civil-engineering/traffic_flow.tex
51 views
unlisted
\documentclass[11pt,a4paper]{article}1\usepackage[utf8]{inputenc}2\usepackage[T1]{fontenc}3\usepackage{amsmath,amssymb}4\usepackage{graphicx}5\usepackage{booktabs}6\usepackage{siunitx}7\usepackage{geometry}8\geometry{margin=1in}9\usepackage{pythontex}10\usepackage{hyperref}11\usepackage{float}1213\title{Traffic Flow\\LWR Model and Congestion}14\author{Civil Engineering Research Group}15\date{\today}1617\begin{document}18\maketitle1920\begin{abstract}21This report presents a comprehensive computational analysis of traffic flow theory, implementing the Lighthill-Whitham-Richards (LWR) continuum model, Greenshields' fundamental diagram, and queuing analysis at signalized intersections. We derive traffic wave propagation characteristics, compute capacity using fundamental relationships, analyze Webster's delay formula for signal timing optimization, and demonstrate shock wave formation during congestion onset. The analysis provides quantitative tools for traffic engineers to predict flow breakdown, optimize signal timing, and estimate delay under varying demand conditions.22\end{abstract}2324\section{Introduction}2526Traffic flow theory provides the mathematical foundation for understanding vehicular movement on roadways, enabling engineers to predict congestion, optimize signal timing, and design efficient transportation systems. The fundamental diagram relating flow ($q$), density ($k$), and speed ($v$) was first proposed by Greenshields in 1935 and remains the cornerstone of traffic analysis \cite{Greenshields1935}. Building on this foundation, Lighthill and Whitham (1955) and independently Richards (1956) developed the LWR continuum model, which treats traffic as a compressible fluid and predicts shock wave formation during congestion \cite{Lighthill1955,Richards1956}. For signalized intersections, Webster's delay formula (1958) provides closed-form estimates of average vehicle delay as a function of cycle length, green time, and degree of saturation \cite{Webster1958}. This report integrates these classical theories with modern computational methods to analyze traffic phenomena including capacity computation, wave speed derivation, queuing dynamics, and delay optimization. Understanding these relationships is critical for urban planners managing increasing traffic demand with limited infrastructure capacity.2728\begin{pycode}2930import numpy as np31import matplotlib.pyplot as plt32from scipy.integrate import odeint33from scipy.optimize import fsolve34from scipy import stats35plt.rcParams['text.usetex'] = True36plt.rcParams['font.family'] = 'serif'3738# Traffic flow parameters (Greenshields model)39k_jam = 150.0 # jam density (veh/km)40v_free = 100.0 # free-flow speed (km/h)41q_max = v_free * k_jam / 4.0 # maximum flow capacity (veh/h)42k_crit = k_jam / 2.0 # critical density at capacity (veh/km)4344# Signalized intersection parameters45green_time = 30.0 # green phase duration (s)46red_time = 60.0 # red phase duration (s)47cycle_length = green_time + red_time # total cycle (s)48saturation_flow = 1800.0 # saturation flow rate (veh/h)49arrival_rate = 600.0 # vehicle arrival rate (veh/h)5051\end{pycode}5253\section{Fundamental Diagram: Flow-Density Relationship}5455The Greenshields model assumes a linear speed-density relationship:56\begin{equation}57v(k) = v_f \left(1 - \frac{k}{k_j}\right)58\end{equation}59where $v_f = \py{v_free}$ km/h is the free-flow speed and $k_j = \py{k_jam}$ veh/km is the jam density. Traffic flow is given by $q = k \cdot v$:60\begin{equation}61q(k) = v_f k \left(1 - \frac{k}{k_j}\right) = v_f k - \frac{v_f}{k_j} k^262\end{equation}63Maximum capacity occurs at critical density $k_c = k_j/2$:64\begin{equation}65q_{\text{max}} = \frac{v_f k_j}{4} = \py{f'{q_max:.0f}'} \text{ veh/h}66\end{equation}6768\begin{pycode}69# Fundamental diagram computation70k_range = np.linspace(0, k_jam, 200)71v_k = v_free * (1 - k_range / k_jam) # speed as function of density72q_k = k_range * v_k # flow-density relationship7374# Identify critical point (capacity)75idx_crit = np.argmax(q_k)76k_at_capacity = k_range[idx_crit]77q_capacity = q_k[idx_crit]7879fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))8081# Plot 1: Flow vs Density82ax1.plot(k_range, q_k, 'b-', linewidth=2.5, label='Greenshields Model')83ax1.plot(k_at_capacity, q_capacity, 'ro', markersize=10, label=f'Capacity = {q_capacity:.0f} veh/h')84ax1.axvline(k_at_capacity, color='r', linestyle='--', alpha=0.5)85ax1.axhline(q_capacity, color='r', linestyle='--', alpha=0.5)86ax1.set_xlabel('Density $k$ (veh/km)', fontsize=12)87ax1.set_ylabel('Flow $q$ (veh/h)', fontsize=12)88ax1.set_title('Fundamental Diagram: Flow-Density', fontsize=13, weight='bold')89ax1.grid(True, alpha=0.3)90ax1.legend(fontsize=10)91ax1.set_xlim(0, k_jam)92ax1.set_ylim(0, q_capacity * 1.1)9394# Plot 2: Speed vs Density95ax2.plot(k_range, v_k, 'g-', linewidth=2.5, label='Speed-Density')96ax2.plot(k_at_capacity, v_k[idx_crit], 'ro', markersize=10, label=f'Critical Density = {k_at_capacity:.1f} veh/km')97ax2.axvline(k_at_capacity, color='r', linestyle='--', alpha=0.5)98ax2.set_xlabel('Density $k$ (veh/km)', fontsize=12)99ax2.set_ylabel('Speed $v$ (km/h)', fontsize=12)100ax2.set_title('Speed-Density Relationship', fontsize=13, weight='bold')101ax2.grid(True, alpha=0.3)102ax2.legend(fontsize=10)103ax2.set_xlim(0, k_jam)104ax2.set_ylim(0, v_free * 1.1)105106plt.tight_layout()107plt.savefig('traffic_flow_plot1.pdf', dpi=150, bbox_inches='tight')108plt.close()109\end{pycode}110111\begin{figure}[H]112\centering113\includegraphics[width=0.95\textwidth]{traffic_flow_plot1.pdf}114\caption{Fundamental traffic flow relationships derived from the Greenshields model. Left panel shows the parabolic flow-density relationship with maximum capacity $q_{\text{max}} = \py{f'{q_capacity:.0f}'}$ veh/h occurring at critical density $k_c = \py{f'{k_at_capacity:.1f}'}$ veh/km. Right panel displays the linear speed-density relationship, showing speed declining from free-flow \py{f'{v_free:.0f}'} km/h to zero at jam density. The critical density represents the transition between free flow (low density, high speed) and congested flow (high density, low speed).}115\end{figure}116117\section{LWR Model: Traffic Wave Propagation}118119The Lighthill-Whitham-Richards (LWR) model treats traffic as a one-dimensional continuum governed by the conservation equation:120\begin{equation}121\frac{\partial k}{\partial t} + \frac{\partial q}{\partial x} = 0122\end{equation}123Using the fundamental diagram $q = q(k)$, the wave speed (kinematic wave celerity) is:124\begin{equation}125c(k) = \frac{dq}{dk} = v_f \left(1 - \frac{2k}{k_j}\right)126\end{equation}127At free flow ($k \to 0$), waves propagate at $c = v_f$. At jam density ($k = k_j$), $c = -v_f$ (backward-moving waves). At capacity ($k = k_c$), $c = 0$ (stationary bottleneck).128129\begin{pycode}130# Wave speed computation131c_k = v_free * (1 - 2 * k_range / k_jam) # kinematic wave speed132133# Shock wave between two states (k1 < k2)134k_upstream = 30.0 # upstream density (veh/km)135k_downstream = 120.0 # downstream density (veh/km)136q_upstream = k_upstream * v_free * (1 - k_upstream / k_jam)137q_downstream = k_downstream * v_free * (1 - k_downstream / k_jam)138shock_speed = (q_downstream - q_upstream) / (k_downstream - k_upstream) # km/h139140fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))141142# Plot 1: Wave speed vs density143ax1.plot(k_range, c_k, 'b-', linewidth=2.5, label='Wave Speed $c(k)$')144ax1.axhline(0, color='k', linestyle='-', linewidth=0.8)145ax1.fill_between(k_range, 0, c_k, where=(c_k >= 0), alpha=0.2, color='green', label='Forward Waves')146ax1.fill_between(k_range, c_k, 0, where=(c_k < 0), alpha=0.2, color='red', label='Backward Waves')147ax1.plot(k_at_capacity, 0, 'ro', markersize=10, label='Critical Point')148ax1.set_xlabel('Density $k$ (veh/km)', fontsize=12)149ax1.set_ylabel('Wave Speed $c$ (km/h)', fontsize=12)150ax1.set_title('Kinematic Wave Speed', fontsize=13, weight='bold')151ax1.grid(True, alpha=0.3)152ax1.legend(fontsize=10)153ax1.set_xlim(0, k_jam)154155# Plot 2: Shock wave on fundamental diagram156ax2.plot(k_range, q_k, 'b-', linewidth=2.5, label='Flow-Density Curve')157ax2.plot([k_upstream, k_downstream], [q_upstream, q_downstream], 'ro-', markersize=8, linewidth=2, label=f'Shock Wave: {shock_speed:.1f} km/h')158ax2.arrow((k_upstream + k_downstream)/2, (q_upstream + q_downstream)/2, 10, shock_speed*10/v_free*q_capacity/10, head_width=5, head_length=200, fc='red', ec='red', alpha=0.7)159ax2.set_xlabel('Density $k$ (veh/km)', fontsize=12)160ax2.set_ylabel('Flow $q$ (veh/h)', fontsize=12)161ax2.set_title('Shock Wave Formation', fontsize=13, weight='bold')162ax2.grid(True, alpha=0.3)163ax2.legend(fontsize=10)164ax2.set_xlim(0, k_jam)165ax2.set_ylim(0, q_capacity * 1.1)166167plt.tight_layout()168plt.savefig('traffic_flow_plot2.pdf', dpi=150, bbox_inches='tight')169plt.close()170\end{pycode}171172\begin{figure}[H]173\centering174\includegraphics[width=0.95\textwidth]{traffic_flow_plot2.pdf}175\caption{Kinematic wave analysis from the LWR continuum model. Left panel shows wave speed $c(k) = dq/dk$ as a function of density, demonstrating forward-propagating waves in free flow (green region) and backward-propagating waves in congestion (red region). The critical density marks the transition where wave speed equals zero. Right panel illustrates shock wave formation when upstream density ($k_1 = \py{f'{k_upstream:.0f}'}$ veh/km) meets downstream congestion ($k_2 = \py{f'{k_downstream:.0f}'}$ veh/km), producing a discontinuity traveling at \py{f'{shock_speed:.1f}'} km/h. Shock waves represent abrupt transitions such as the onset of congestion at bottlenecks.}176\end{figure}177178\section{Signalized Intersection: Queuing Dynamics}179180At a signalized intersection, vehicles arrive at rate $\lambda = \py{f'{arrival_rate:.0f}'}$ veh/h and depart at saturation flow $s = \py{f'{saturation_flow:.0f}'}$ veh/h during green. The degree of saturation is:181\begin{equation}182x = \frac{\lambda}{s \cdot g/C} = \frac{\lambda \cdot C}{s \cdot g}183\end{equation}184where $g = \py{f'{green_time:.0f}'}$ s is green time and $C = \py{f'{cycle_length:.0f}'}$ s is cycle length. When $x > 1$, the queue grows indefinitely (unstable). Webster's delay formula estimates average delay per vehicle:185\begin{equation}186d = \frac{C(1 - g/C)^2}{2(1 - x \cdot g/C)} + \frac{x^2}{2\lambda(1 - x)}187\end{equation}188189\begin{pycode}190# Queue dynamics over multiple cycles191num_cycles = 10192time_total = num_cycles * cycle_length193dt = 1.0 # time step (s)194time = np.arange(0, time_total, dt)195queue_length = np.zeros_like(time)196197# Simulate queuing198lambda_per_sec = arrival_rate / 3600.0 # veh/s199s_per_sec = saturation_flow / 3600.0 # veh/s200201for i in range(1, len(time)):202t_in_cycle = time[i] % cycle_length203is_green = t_in_cycle < green_time204205arrivals = lambda_per_sec * dt206departures = s_per_sec * dt if (is_green and queue_length[i-1] > 0) else 0207208queue_length[i] = max(0, queue_length[i-1] + arrivals - departures)209210# Compute degree of saturation and delay211green_ratio = green_time / cycle_length212x_saturation = arrival_rate / (saturation_flow * green_ratio)213if x_saturation < 1:214webster_delay = (cycle_length * (1 - green_ratio)**2) / (2 * (1 - x_saturation * green_ratio)) + (x_saturation**2) / (2 * (arrival_rate/3600) * (1 - x_saturation))215else:216webster_delay = np.inf217218fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))219220# Plot 1: Queue length over time221ax1.plot(time, queue_length, 'b-', linewidth=2)222for cycle in range(num_cycles):223t_start = cycle * cycle_length224ax1.axvspan(t_start, t_start + green_time, alpha=0.15, color='green', label='Green' if cycle == 0 else '')225ax1.axvspan(t_start + green_time, t_start + cycle_length, alpha=0.15, color='red', label='Red' if cycle == 0 else '')226ax1.set_xlabel('Time (s)', fontsize=12)227ax1.set_ylabel('Queue Length (vehicles)', fontsize=12)228ax1.set_title(f'Queuing at Signalized Intersection ($x = {x_saturation:.2f}$)', fontsize=13, weight='bold')229ax1.grid(True, alpha=0.3)230ax1.legend(fontsize=10)231232# Plot 2: Delay vs arrival rate233arrival_rates = np.linspace(100, saturation_flow * green_ratio * 0.95, 100)234delays = []235for arr in arrival_rates:236x_val = arr / (saturation_flow * green_ratio)237if x_val < 0.99:238d_val = (cycle_length * (1 - green_ratio)**2) / (2 * (1 - x_val * green_ratio)) + (x_val**2) / (2 * (arr/3600) * (1 - x_val))239delays.append(d_val)240else:241delays.append(np.nan)242243ax2.plot(arrival_rates, delays, 'r-', linewidth=2.5)244ax2.axvline(arrival_rate, color='b', linestyle='--', linewidth=2, label=f'Current Demand: {arrival_rate:.0f} veh/h')245ax2.axhline(webster_delay, color='b', linestyle='--', linewidth=1.5, label=f'Delay = {webster_delay:.1f} s')246ax2.set_xlabel('Arrival Rate (veh/h)', fontsize=12)247ax2.set_ylabel('Average Delay (s/veh)', fontsize=12)248ax2.set_title("Webster's Delay Formula", fontsize=13, weight='bold')249ax2.grid(True, alpha=0.3)250ax2.legend(fontsize=10)251ax2.set_xlim(arrival_rates[0], arrival_rates[-1])252ax2.set_ylim(0, min(150, max(delays)))253254plt.tight_layout()255plt.savefig('traffic_flow_plot3.pdf', dpi=150, bbox_inches='tight')256plt.close()257\end{pycode}258259\begin{figure}[H]260\centering261\includegraphics[width=0.95\textwidth]{traffic_flow_plot3.pdf}262\caption{Queuing analysis at a signalized intersection with \py{f'{green_time:.0f}'}-second green and \py{f'{red_time:.0f}'}-second red phases. Top panel shows queue buildup during red (shaded) and dissipation during green, demonstrating cyclic behavior. With arrival rate \py{f'{arrival_rate:.0f}'} veh/h and saturation flow \py{f'{saturation_flow:.0f}'} veh/h, the degree of saturation is $x = \py{f'{x_saturation:.2f}'}$, resulting in stable operation. Bottom panel displays Webster's delay formula, showing average delay per vehicle increasing nonlinearly as arrival rate approaches capacity. At current demand, average delay is \py{f'{webster_delay:.1f}'} seconds per vehicle.}263\end{figure}264265\section{Space-Time Diagram: Traffic Propagation}266267The space-time diagram visualizes vehicle trajectories and shock wave propagation. Individual vehicle paths have slope $dx/dt = v(k)$, while kinematic waves propagate at slope $dx/dt = c(k) = dq/dk$.268269\begin{pycode}270# Space-time diagram showing shock wave propagation271x_road = np.linspace(0, 10, 200) # roadway position (km)272t_sim = np.linspace(0, 0.3, 200) # time (hours)273274# Create space-time mesh275X_mesh, T_mesh = np.meshgrid(x_road, t_sim)276277# Initial condition: shock at x = 5 km separating free flow and congestion278k_initial = np.where(x_road < 5, k_upstream, k_downstream)279280# Density field evolution (simplified LWR solution)281# Shock position: x_shock(t) = 5 + shock_speed * t282density_field = np.zeros_like(X_mesh)283for i, t in enumerate(t_sim):284x_shock = 5 + shock_speed * t # shock position at time t285density_field[i, :] = np.where(X_mesh[i, :] < x_shock, k_upstream, k_downstream)286287fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))288289# Plot 1: Space-time density contour290cs = ax1.contourf(X_mesh, T_mesh, density_field, levels=15, cmap='RdYlGn_r')291cbar = plt.colorbar(cs, ax=ax1)292cbar.set_label('Density (veh/km)', fontsize=11)293294# Add shock trajectory295t_shock_line = np.linspace(0, 0.3, 50)296x_shock_line = 5 + shock_speed * t_shock_line297ax1.plot(x_shock_line, t_shock_line, 'b-', linewidth=3, label=f'Shock Wave: {shock_speed:.1f} km/h')298299ax1.set_xlabel('Position $x$ (km)', fontsize=12)300ax1.set_ylabel('Time $t$ (hours)', fontsize=12)301ax1.set_title('Space-Time Diagram: Density Evolution', fontsize=13, weight='bold')302ax1.legend(fontsize=11, loc='upper left')303ax1.grid(True, alpha=0.3)304305# Plot 2: Vehicle trajectories306num_vehicles = 8307x0_free = np.linspace(0, 4.5, num_vehicles//2) # vehicles in free flow308x0_cong = np.linspace(5.5, 9, num_vehicles//2) # vehicles in congestion309310for x0 in x0_free:311v_traj = v_free * (1 - k_upstream / k_jam)312x_traj = x0 + v_traj * t_sim313ax2.plot(x_traj, t_sim, 'g-', linewidth=1.5, alpha=0.7)314315for x0 in x0_cong:316v_traj = v_free * (1 - k_downstream / k_jam)317x_traj = x0 + v_traj * t_sim318ax2.plot(x_traj, t_sim, 'r-', linewidth=1.5, alpha=0.7)319320# Add shock trajectory321ax2.plot(x_shock_line, t_shock_line, 'b--', linewidth=3, label='Shock Wave')322ax2.set_xlabel('Position $x$ (km)', fontsize=12)323ax2.set_ylabel('Time $t$ (hours)', fontsize=12)324ax2.set_title('Vehicle Trajectories', fontsize=13, weight='bold')325ax2.legend(fontsize=11)326ax2.grid(True, alpha=0.3)327328plt.tight_layout()329plt.savefig('traffic_flow_plot4.pdf', dpi=150, bbox_inches='tight')330plt.close()331\end{pycode}332333\begin{figure}[H]334\centering335\includegraphics[width=0.98\textwidth]{traffic_flow_plot4.pdf}336\caption{Space-time representation of traffic shock wave propagation. Left panel shows density contours evolving in space and time, with a shock wave (blue line) separating upstream free flow (green, $k = \py{f'{k_upstream:.0f}'}$ veh/km) from downstream congestion (red, $k = \py{f'{k_downstream:.0f}'}$ veh/km). The shock propagates backward at \py{f'{shock_speed:.1f}'} km/h, characteristic of queue formation when demand exceeds capacity. Right panel displays individual vehicle trajectories, with green paths showing higher speeds in free flow and red paths showing slower speeds in congestion. The shock represents the queue tail moving upstream.}337\end{figure}338339\section{Signal Timing Optimization}340341Optimal signal timing minimizes total delay. Webster's optimal cycle length is:342\begin{equation}343C_{\text{opt}} = \frac{1.5L + 5}{1 - Y}344\end{equation}345where $L$ is total lost time per cycle and $Y = \sum (q_i / s_i)$ is the critical flow ratio. For green time allocation:346\begin{equation}347g_i = (C - L) \cdot \frac{y_i}{Y}348\end{equation}349where $y_i = q_i / s_i$ for approach $i$.350351\begin{pycode}352# Optimize cycle length and green time353lost_time = 10.0 # lost time per cycle (s)354Y_critical = arrival_rate / saturation_flow # critical flow ratio355356# Webster's optimal cycle length357C_opt = (1.5 * lost_time + 5) / (1 - Y_critical)358g_opt = (C_opt - lost_time) * Y_critical359360# Compare delays for different cycle lengths361cycle_range = np.linspace(30, 180, 100)362delays_cycle = []363x_values = []364365for C_test in cycle_range:366g_test = (C_test - lost_time) * Y_critical367if g_test > 0 and g_test < C_test:368x_test = arrival_rate / (saturation_flow * g_test / C_test)369if x_test < 0.99:370d_test = (C_test * (1 - g_test/C_test)**2) / (2 * (1 - x_test * g_test/C_test)) + (x_test**2) / (2 * (arrival_rate/3600) * (1 - x_test))371delays_cycle.append(d_test)372x_values.append(x_test)373else:374delays_cycle.append(np.nan)375x_values.append(np.nan)376else:377delays_cycle.append(np.nan)378x_values.append(np.nan)379380# Delay at optimal cycle381x_opt = arrival_rate / (saturation_flow * g_opt / C_opt)382d_opt = (C_opt * (1 - g_opt/C_opt)**2) / (2 * (1 - x_opt * g_opt/C_opt)) + (x_opt**2) / (2 * (arrival_rate/3600) * (1 - x_opt))383384fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))385386# Plot 1: Delay vs cycle length387ax1.plot(cycle_range, delays_cycle, 'b-', linewidth=2.5)388ax1.plot(C_opt, d_opt, 'ro', markersize=12, label=f'Optimal: $C = {C_opt:.0f}$ s, $d = {d_opt:.1f}$ s')389ax1.axvline(C_opt, color='r', linestyle='--', alpha=0.5)390ax1.set_xlabel('Cycle Length $C$ (s)', fontsize=12)391ax1.set_ylabel('Average Delay $d$ (s/veh)', fontsize=12)392ax1.set_title("Webster's Optimal Cycle Length", fontsize=13, weight='bold')393ax1.grid(True, alpha=0.3)394ax1.legend(fontsize=11)395ax1.set_ylim(0, min(100, max([d for d in delays_cycle if not np.isnan(d)])))396397# Plot 2: Sensitivity to arrival rate398arrival_test = np.linspace(200, saturation_flow * 0.8, 100)399delays_arrival = []400for arr in arrival_test:401Y_test = arr / saturation_flow402C_test_opt = (1.5 * lost_time + 5) / (1 - Y_test)403g_test_opt = (C_test_opt - lost_time) * Y_test404x_test = arr / (saturation_flow * g_test_opt / C_test_opt)405if x_test < 0.99:406d_test = (C_test_opt * (1 - g_test_opt/C_test_opt)**2) / (2 * (1 - x_test * g_test_opt/C_test_opt)) + (x_test**2) / (2 * (arr/3600) * (1 - x_test))407delays_arrival.append(d_test)408else:409delays_arrival.append(np.nan)410411ax2.plot(arrival_test, delays_arrival, 'g-', linewidth=2.5)412ax2.axvline(arrival_rate, color='b', linestyle='--', linewidth=2, label=f'Current: {arrival_rate:.0f} veh/h')413ax2.set_xlabel('Arrival Rate (veh/h)', fontsize=12)414ax2.set_ylabel('Optimal Delay (s/veh)', fontsize=12)415ax2.set_title('Delay vs Demand (Optimized Timing)', fontsize=13, weight='bold')416ax2.grid(True, alpha=0.3)417ax2.legend(fontsize=11)418419plt.tight_layout()420plt.savefig('traffic_flow_plot5.pdf', dpi=150, bbox_inches='tight')421plt.close()422\end{pycode}423424\begin{figure}[H]425\centering426\includegraphics[width=0.95\textwidth]{traffic_flow_plot5.pdf}427\caption{Signal timing optimization using Webster's method. Left panel shows average delay as a function of cycle length for fixed demand (\py{f'{arrival_rate:.0f}'} veh/h), with the optimal cycle length $C_{\text{opt}} = \py{f'{C_opt:.0f}'}$ s minimizing delay at \py{f'{d_opt:.1f}'} s/veh. Shorter cycles waste time on phase transitions, while longer cycles increase queue buildup. Right panel demonstrates sensitivity to traffic demand: as arrival rate increases toward capacity, even optimized signal timing produces exponentially increasing delays. This underscores the importance of capacity expansion for high-demand corridors.}428\end{figure}429430\section{Capacity Analysis: Flow Breakdown}431432Traffic capacity is the maximum sustainable flow. Beyond capacity, flow drops precipitously as density increases (capacity drop phenomenon). The Highway Capacity Manual (HCM) defines level of service (LOS) based on density ranges.433434\begin{pycode}435# Flow-speed diagram showing capacity drop436v_range = np.linspace(0, v_free, 200)437k_from_v = k_jam * (1 - v_range / v_free)438q_from_v = k_from_v * v_range439440# Empirical capacity drop: flow drops 5-10% after breakdown441capacity_drop_factor = 0.92442q_congested_capacity = q_max * capacity_drop_factor443444# HCM Level of Service boundaries (density-based)445los_boundaries = {446'A': (0, 10), # free flow447'B': (10, 20), # stable flow448'C': (20, 30), # stable flow, maneuverability limited449'D': (30, 45), # approaching unstable450'E': (45, 70), # unstable, at capacity451'F': (70, k_jam), # forced flow, breakdown452}453454fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))455456# Plot 1: Flow-speed relationship457ax1.plot(v_range, q_from_v, 'b-', linewidth=2.5, label='Theoretical Curve')458# Show capacity drop459v_at_capacity = v_free / 2460idx_capacity = np.argmin(np.abs(v_range - v_at_capacity))461ax1.plot(v_at_capacity, q_max, 'go', markersize=10, label=f'Pre-breakdown: {q_max:.0f} veh/h')462ax1.plot(v_at_capacity * 0.7, q_congested_capacity, 'ro', markersize=10, label=f'Post-breakdown: {q_congested_capacity:.0f} veh/h')463ax1.arrow(v_at_capacity, q_max, -5, -(q_max - q_congested_capacity)*0.8, head_width=2, head_length=200, fc='red', ec='red', linewidth=2)464ax1.set_xlabel('Speed $v$ (km/h)', fontsize=12)465ax1.set_ylabel('Flow $q$ (veh/h)', fontsize=12)466ax1.set_title('Flow-Speed Relationship & Capacity Drop', fontsize=13, weight='bold')467ax1.grid(True, alpha=0.3)468ax1.legend(fontsize=10)469ax1.set_xlim(0, v_free)470ax1.set_ylim(0, q_max * 1.1)471472# Plot 2: Level of Service regions on fundamental diagram473colors_los = {'A': 'green', 'B': 'lightgreen', 'C': 'yellow', 'D': 'orange', 'E': 'red', 'F': 'darkred'}474for los, (k_min, k_max) in los_boundaries.items():475k_los = np.linspace(k_min, k_max, 50)476q_los = k_los * v_free * (1 - k_los / k_jam)477ax2.fill_between(k_los, 0, q_los, alpha=0.3, color=colors_los[los], label=f'LOS {los}')478479ax2.plot(k_range, q_k, 'k-', linewidth=2.5)480ax2.set_xlabel('Density $k$ (veh/km)', fontsize=12)481ax2.set_ylabel('Flow $q$ (veh/h)', fontsize=12)482ax2.set_title('Highway Capacity Manual: Level of Service', fontsize=13, weight='bold')483ax2.legend(fontsize=10, loc='upper right')484ax2.grid(True, alpha=0.3)485ax2.set_xlim(0, k_jam)486ax2.set_ylim(0, q_max * 1.1)487488plt.tight_layout()489plt.savefig('traffic_flow_plot6.pdf', dpi=150, bbox_inches='tight')490plt.close()491\end{pycode}492493\begin{figure}[H]494\centering495\includegraphics[width=0.95\textwidth]{traffic_flow_plot6.pdf}496\caption{Capacity analysis and level of service classification. Left panel illustrates the capacity drop phenomenon: when flow exceeds capacity and breakdown occurs, the sustainable flow drops by approximately 8\% (from \py{f'{q_max:.0f}'} to \py{f'{q_congested_capacity:.0f}'} veh/h) even though vehicles are still present. This hysteresis effect makes congestion recovery difficult. Right panel shows Highway Capacity Manual (HCM) Level of Service (LOS) regions on the fundamental diagram, ranging from LOS A (free flow, low density) to LOS F (forced flow, breakdown). Engineers use LOS to evaluate roadway performance and justify capacity improvements.}497\end{figure}498499\section{Results Summary}500501\begin{pycode}502results = [503['Free-Flow Speed $v_f$', f'{v_free:.0f} km/h'],504['Jam Density $k_j$', f'{k_jam:.0f} veh/km'],505['Critical Density $k_c$', f'{k_crit:.0f} veh/km'],506['Maximum Capacity $q_{{\\text{{max}}}}$', f'{q_max:.0f} veh/h'],507['Shock Wave Speed', f'{shock_speed:.1f} km/h'],508['Degree of Saturation $x$', f'{x_saturation:.3f}'],509['Webster Delay (current)', f'{webster_delay:.1f} s/veh'],510['Optimal Cycle Length $C_{{\\text{{opt}}}}$', f'{C_opt:.0f} s'],511['Optimal Green Time $g_{{\\text{{opt}}}}$', f'{g_opt:.0f} s'],512['Optimal Delay (minimized)', f'{d_opt:.1f} s/veh'],513]514515print(r'\begin{table}[H]')516print(r'\centering')517print(r'\caption{Traffic Flow Analysis Results}')518print(r'\begin{tabular}{@{}lc@{}}')519print(r'\toprule')520print(r'Parameter & Value \\')521print(r'\midrule')522for row in results:523print(f"{row[0]} & {row[1]} \\\\")524print(r'\bottomrule')525print(r'\end{tabular}')526print(r'\end{table}')527\end{pycode}528529\section{Conclusions}530531This computational analysis has implemented fundamental traffic flow theory to predict roadway performance and optimize signal timing. Using the Greenshields model, we established the flow-density-speed relationships and determined that maximum capacity of \py{f'{q_max:.0f}'} veh/h occurs at critical density \py{f'{k_crit:.0f}'} veh/km. The LWR kinematic wave model revealed that shock waves propagate backward at \py{f'{shock_speed:.1f}'} km/h when downstream congestion ($k = \py{f'{k_downstream:.0f}'}$ veh/km) meets upstream free flow ($k = \py{f'{k_upstream:.0f}'}$ veh/km), explaining the characteristic backward propagation of queue tails at bottlenecks.532533For signalized intersections operating at arrival rate \py{f'{arrival_rate:.0f}'} veh/h with saturation flow \py{f'{saturation_flow:.0f}'} veh/h, the degree of saturation $x = \py{f'{x_saturation:.3f}'}$ indicates stable operation. Webster's formula predicts average delay of \py{f'{webster_delay:.1f}'} seconds per vehicle under current \py{f'{green_time:.0f}'}/\py{f'{red_time:.0f}'} second timing. Optimization yields an improved cycle length of \py{f'{C_opt:.0f}'} seconds with \py{f'{g_opt:.0f}'} seconds green time, reducing delay to \py{f'{d_opt:.1f}'} s/veh—a \py{f'{100*(webster_delay - d_opt)/webster_delay:.1f}'}\% improvement.534535The capacity drop phenomenon demonstrates that post-breakdown flow (\py{f'{q_congested_capacity:.0f}'} veh/h) is approximately 8\% lower than pre-breakdown capacity, illustrating the hysteresis effect that makes congestion recovery challenging. Highway Capacity Manual level-of-service analysis provides a framework for evaluating roadway performance, with LOS E (density 45–70 veh/km) representing operation at or near capacity.536537These models form the quantitative basis for traffic engineering decisions including bottleneck identification, signal timing optimization, and capacity expansion planning. Future extensions should incorporate stochastic arrivals, multi-class traffic (cars, trucks, buses), and adaptive signal control algorithms to better represent real-world variability and improve urban mobility.538539\begin{thebibliography}{99}540541\bibitem{Greenshields1935}542B.D. Greenshields, ``A study of traffic capacity,'' \textit{Highway Research Board Proceedings}, vol. 14, pp. 448--477, 1935.543544\bibitem{Lighthill1955}545M.J. Lighthill and G.B. Whitham, ``On kinematic waves. II. A theory of traffic flow on long crowded roads,'' \textit{Proceedings of the Royal Society of London. Series A}, vol. 229, no. 1178, pp. 317--345, 1955.546547\bibitem{Richards1956}548P.I. Richards, ``Shock waves on the highway,'' \textit{Operations Research}, vol. 4, no. 1, pp. 42--51, 1956.549550\bibitem{Webster1958}551F.V. Webster, ``Traffic signal settings,'' Road Research Technical Paper No. 39, Road Research Laboratory, London, 1958.552553\bibitem{HCM2016}554Transportation Research Board, \textit{Highway Capacity Manual}, 6th ed. Washington, DC: National Academies Press, 2016.555556\bibitem{Daganzo1994}557C.F. Daganzo, ``The cell transmission model: A dynamic representation of highway traffic consistent with the hydrodynamic theory,'' \textit{Transportation Research Part B}, vol. 28, no. 4, pp. 269--287, 1994.558559\bibitem{Newell1993}560G.F. Newell, ``A simplified theory of kinematic waves in highway traffic, part I: General theory,'' \textit{Transportation Research Part B}, vol. 27, no. 4, pp. 281--287, 1993.561562\bibitem{Papageorgiou1991}563M. Papageorgiou, J.-M. Blosseville, and H. Hadj-Salem, ``Modelling and real-time control of traffic flow on the southern part of Boulevard Périphérique in Paris,'' \textit{Transportation Research Part A}, vol. 24, no. 5, pp. 345--359, 1990.564565\bibitem{Cassidy1999}566M.J. Cassidy and R.L. Bertini, ``Some traffic features at freeway bottlenecks,'' \textit{Transportation Research Part B}, vol. 33, no. 1, pp. 25--42, 1999.567568\bibitem{Banks1991}569J.H. Banks, ``Two-capacity phenomenon at freeway bottlenecks: A basis for ramp metering?,'' \textit{Transportation Research Record}, no. 1320, pp. 83--90, 1991.570571\bibitem{Kerner2004}572B.S. Kerner, \textit{The Physics of Traffic}. Berlin: Springer-Verlag, 2004.573574\bibitem{Treiber2013}575M. Treiber and A. Kesting, \textit{Traffic Flow Dynamics: Data, Models and Simulation}. Berlin: Springer-Verlag, 2013.576577\bibitem{Daganzo1997}578C.F. Daganzo, \textit{Fundamentals of Transportation and Traffic Operations}. Oxford: Pergamon-Elsevier, 1997.579580\bibitem{May1990}581A.D. May, \textit{Traffic Flow Fundamentals}. Englewood Cliffs, NJ: Prentice Hall, 1990.582583\bibitem{Gazis2002}584D.C. Gazis, ``Traffic theory,'' in \textit{International Series in Operations Research \& Management Science}, vol. 50. Boston: Springer, 2002.585586\bibitem{Papageorgiou2007}587M. Papageorgiou, C. Diakaki, V. Dinopoulou, A. Kotsialos, and Y. Wang, ``Review of road traffic control strategies,'' \textit{Proceedings of the IEEE}, vol. 91, no. 12, pp. 2043--2067, 2003.588589\bibitem{Hoogendoorn2001}590S.P. Hoogendoorn and P.H.L. Bovy, ``State-of-the-art of vehicular traffic flow modelling,'' \textit{Proceedings of the Institution of Mechanical Engineers, Part I: Journal of Systems and Control Engineering}, vol. 215, no. 4, pp. 283--303, 2001.591592\bibitem{Aw2000}593A. Aw and M. Rascle, ``Resurrection of `second order' models of traffic flow,'' \textit{SIAM Journal on Applied Mathematics}, vol. 60, no. 3, pp. 916--938, 2000.594595\bibitem{Helbing2001}596D. Helbing, ``Traffic and related self-driven many-particle systems,'' \textit{Reviews of Modern Physics}, vol. 73, no. 4, pp. 1067--1141, 2001.597598\end{thebibliography}599600\end{document}601602603