Dynamical systems modeling of transportation systems and their impacts on urban air pollution. Case of interest: New Delhi, India.
The latest version of the model (as of November 13, 2024) is travel_4_1021.ode in XPPAUT and travel_4.ipynb in Julia. It involves two patches connected by two (bidirectional) corridors.
The transportation system in the National Capital Territory (NCT) of Delhi, India is a complex network of vehicles, transit lines, and users of multiple types. Rising air pollution associated with this transportation system is a major public health challenge, and recent studies have estimated that poor air quality in Delhi reduces residents’ life expectancy by about 6 years \citep{ghude2016premature}. This system is bounded by the municipal boundaries of NCT, but the boundaries are permeable to the movement of air, vehicles, and people across political boundaries. We conceptualize the transportation system as consisting of vehicles (e.g. cars, trains, motorcycles, auto-rickshaws, pedestrians) which travel between patches (e.g. residential areas, business districts) along corridors (e.g. highways, train lines) and emit pollutants at a certain rate depending on their travel speed and congestion levels. To conceptualize the wider social-ecological context, we can use the Coupled-Infrastructure Systems (CIS) framework shown in \autoref{fig:CIS_framework} \citep[][]{anderies2015understanding}.
Our objective is to build a general model of urban mobility systems, with NCT New Delhi as a prototyping case, to gain insight into the relationship between mobility infrastructure configurations, governance policies, and air quality. Specific research questions include:
- How does the overall pollution level compare for a small mobility infrastructure system (few patches, few corridors) vs a large mobility infrastructure system (many patches, many corridors)?
- What is the impact on air pollution of increasing capacity of existing roads (decrease the parameter
$kc_{jam}^k$ , defined below)? - What is the impact on air pollution of increasing road connectivity by adding new corridors while keeping the same number of patches (increase parameter
$K$ , defined below)? - (Future work) How does information flow along links in the CIS to inform infrastructure investment decisions by PIP?
The concept for this model is shown in \autoref{fig:conceptual_diagram} for a case with two patches and two connective corridors.

In general, suppose there are
-
$kp[i]$ : population density in patch$i$ (units: vehicles) -
$kc[i,j,k]$ : population density in corridor$k$ , heading from patch$i$ to patch$j$ (units: vehicles)
These state variables are countable populations which could in theory be measured at a point in time.
-
$kc_{jam}[i,j,k]$ : Road congestion factor (inverse road capacity) for corridor$k$ heading from patch$i$ to patch$j$ . Analogous to ``resistance'' in an electrical wire. Think of congestion as the ratio of vehicles on the road to the jam capacity of that road:$kc[i,j,k] / kc_{jam}[i,j,k]$ . Therefore,$kc_{jam}[i,j,k] = 1 / kc_{jam}[i,j,k]$ , and$kc_{jam}[i,j,k]=0$ would imply infinite road capacity. (units: 1/vehicles) -
$\alpha^i$ : aversion to congestion for travelers from patch$i$ . Given$kc_{jam}_k kc[i,j,k]$ ,$\uparrow \alpha \Rightarrow \downarrow$ new travelers. (unitless) -
$γ[i]$ : Percentage of population in patch$i$ who want to travel. (unitless) \end{itemize}
These parameters describe infrastructure capacity (such as the width of a highway) and social behavior of travelers. These quantities are likely to change on a time scale of months to years, whereas our model is focused on traffic flows on a time scale of minutes and hours, so we can treat the above quantities as parameters.
Here the total number of vehicles is conserved.
Because of the conservation law, the change in number of vehicles in any node (a patch, corridor, urban sponge, etc.) is determined by flow-in minus flow-out. The speed of fluxes into and out of corridors is density dependent.
-
$F^{\rightarrow k}[i,j]$ : flux from patch$i$ into corridor$k$ , with an ultimate destination of patch$j$ . -
$F^{k\rightarrow}[i,j]$ : flux from corridor$k$ into patch$j$ , where the origin was$i$ .
For a general system of
The number of vehicles in each patch
Number of vehicles in a corridor
If
For fluxes from patches into corridors, we also need a matrix with three dimensions
Meanwhile,
The system of differential equations governing this system can be written:
with the conservation law:
The equations for fluxes into and out of corridors are as follows.
This equation states that the number of vehicles which flow from patch
This equation says that number of vehicles flowing out of corridor
Up to now, we have assumed that demand
Thus, we re-define
The equations describing the dynamical clock are as follows: $$ \begin{align} \frac{du}{dt} &= u (1 - u^2 - v^2) - (2 pi / \textrm{period}) v \ \frac{dv}{dt} &= v (1 - u^2 - v^2) + (2 pi / \textrm{period}) u \end{align} $$
Where do these equations come from? They come from the Hopf oscillator (a well-known example of a system that behaves like a limit cycle). In polar coordinates, the Hopf oscillator is described by this system:
$$
\begin{align}
\frac{dr}{dt} &= r (1-r^2) \
\frac{d\theta}{dt} &= w
\end{align}
$$
where
To transform this system from polar to Cartesian coordinates, let
By building our dynamical system with the equations for period so that one cycle of the system matches a 24 hour period. Then, we can build our demand function in a number of ways. For example, suppose I want
theta = atan(v, u)
d_eqs = [
d[1] ~ max(0, cos(theta - (3pi / 4))),
d[2] ~ max(0, cos(theta - (5pi / 4)))
]
Why does this work? Since max() function ensures that the value of the demand function will never be negative.
In the context of the package ModelingToolkit.jl, the variable
eqs = [
D(u) ~ u * (1 - u^2 - v^2) - (2 * pi / period) * (v),
D(v) ~ v * (1 - u^2 - v^2) + (2 * pi / period) * (u),
D.(p) ~ [sum(ExFlx(c, β)[:, i, :]) for i in 1:Np] .- [sum(EnFlx(p, c, d, α[1], β)[i, :, :]) for i in 1:Np],
D.(c) ~ collect(-ExFlx(c, β) + EnFlx(p, c, d, α[1], β)),
d_eqs... # <-- include the triple dots to splice the equations into the list
]
Given a traffic density
First, to compute average vehicle speeds, we will use an alternative to Greenshield's law. The typical Greenshield's model states:
where
A more realistic version of this model would show nearly free flow speeds for a range of traffic density, followed by a sharp drop in average speeds at a certain congestion threshold
where
Therefore, the road congestion parameter can now be written
With average vehicle speeds in hand, we can estimate emission rates using the U-shaped curve. This empirical function depends on particular vehicle types, engine and fuel types, and location, and it relates CO2 emission rates (grams / unit distance) with average vehicle speeds (unit distance / time). We assume that very low average speeds (e.g. 5mph) are associated with stop-and-go traffic, and therefore high emission rates. Meanwhile, very high average speeds (e.g.
Given an array for the U-shaped curve
For the simple system with two patches and two corridors shown in \autoref{fig:conceptual_diagram}, the system of equations is as follows:
Conservation law:
Fluxes from patches to corridors depend on 1) population of patch
Fluxes from corridors to patches depends on the current population in a patch
Average speeds are then calculated as follows:
using Interpolations
# Calculate speeds from densities
v_f = 90 # free-flow velocity, 90 km/hr
k_jam_C1 = 1 / β₁
k_jam_C2 = 1 / β₂
k_half_C1 = k_jam_C1 / 2
k_half_C2 = k_jam_C2 / 2
# Function to calculate average speeds using alternative Greenshield's model
function calc_space_mean_speed_alternative(v_f, k, k_half; a=1)
u_s = - (v_f / pi) * atan(a*(k - k_half)) + (v_f / 2)
return u_s > 0 ? u_s : 0
end
# Calculate average vehicle speeds for C1 and C2
C1_speeds = calc_space_mean_speed_alternative.(v_f, pop_C1, k_half_C1)
C2_speeds = calc_space_mean_speed_alternative.(v_f, pop_C2, k_half_C2)
And finally, emission rates are calculated:
# Make a U-shaped curve
start = 5 # speeds in mph, from California paper
my_step = 5
stop = 100
mph_to_kmh = 1.60934
speed_arr = collect(start:my_step:stop) * mph_to_kmh # convert mph to kmh
emissions_arr = [1200, 950, 700, 500, 425, 350, 325, 310, 309, 308, 308, 308, 309, 320, 330, 350, 375, 400, 450, 550] * mph_to_kmh
plot(speed_arr, emissions_arr)
# Define an interpolation function to get emission rate (g / distance) for particular average speeds
interp_fn = linear_interpolation(speed_arr, emissions_arr, extrapolation_bc=Line())
# Function to calculate emission rate (g / hour) for given average speeds
function calc_emissions_from_speed(vehicle_pop_arr, my_speed_arr, interp_fn)
interpolated_emission_per_vehicle = interp_fn(my_speed_arr)
emissions = interpolated_emission_per_vehicle .* my_speed_arr .* vehicle_pop_arr
return emissions
end
# Calculate emissions for C1 and C2
C1_emissions = calc_emissions_from_speed(pop_C1, C1_speeds, interp_fn)
C2_emissions = calc_emissions_from_speed(pop_C2, C2_speeds, interp_fn)
For the demo case, we find traffic flows and resulting emissions for 100 times steps with parameters
The associated emissions over time for each corridor is shown in \autoref{fig:emissions}. We notice the curve for emissions rates for each corridor is almost identical to its associated population curve, with a bit of discretization. The final step (not shown) to calculate total emissions for a given part of the day is the integrate the area under the emissions curve for time
This exercise showed me the importance of dimensional analysis to developing a realistic model. At multiple phases of this project, I found myself questioning the realism of the model, or struggling to connect my first principles model with other models (such as Greenshield's model). The solution always came from a careful assessment of how to interpret each variable and parameter in terms of its units.
At the moment, I am not satisfied with this model for several reasons:
- The assumption that emissions depend on average speeds according to a simple U-shaped function rests on the logic that lower average speeds indicate stop-and-go traffic conditions. This is unsatisfying because emissions really depend on how often drivers hit the accelerator. Two trips might have the same average speed but very different emission rates depending on driving patterns.
- Additionally, the current analysis pipeline of vehicle population
$\rightarrow$ average speeds$\rightarrow$ emissions implies a linear relationship between population density and emission rates at each time. This seems overly simplistic, and it doesn't suggest any interesting properties about how travel infrastructure relates to emissions.
Future versions of the model should also consider more sophisticated social-ecological interactions. For instance:
- Increasing road capacity (e.g. by widening highways) can induce additional demand (higher
$d$ ). Our model currently does not consider non-static demand. - Corridors that represent highways, smaller streets, and railways should likely be governed by different dynamical equations (e.g. trains depart in discrete increments, there is no continuous flow in and out).
- We should model heterogeneous traffic flows, such as highways used by cars, trucks, motorcycles, auto-rickshaws, cyclists, and pedestrians who may be using the same corridor simultaneously.
Eventually, we hope to flesh out the links in the CIS model that connect this formal model of hard urban infrastructure to policy decisions. It would be particularly useful to identify how information about road conditions and emissions flow between nodes and influence the infrastructure investment decisions of PIPs.



