Simulation core

Core classes of the Python-based simulation engine.

World

class unsim.World(name='', deltat=None, tmax=2000, print_mode=1, save_mode=1, show_mode=0, reaction_time=1, random_seed=None, auto_diverge=False, route_choice=None, logit_temperature=60.0, **kwargs)

Simulation world managing nodes, links, demand, and execution.

Parameters:
  • name (str, optional) – Scenario name.

  • deltat (float or None, optional) – Simulation timestep width (s). None (default) for automatic setting as min(d_l/u_l) across all links.

  • tmax (float, optional) – Total simulation duration (s).

  • print_mode (int, optional) – Print progress messages. Default 1.

  • save_mode (int, optional) – Save results. Default 1.

  • reaction_time (float, optional) – Reaction time for FD computation (s). Default 1.

  • auto_diverge (bool, optional) – If True, automatically compute diverge/absorption ratios from OD demand composition and shortest paths. If False (default), use ratios specified in addNode (diverge_ratio, absorption_ratio).

NODES

All nodes.

Type:

list[Node]

All links.

Type:

list[Link]

analyzer

Result analyzer (created after finalize_scenario).

Type:

Analyzer

Add a link to the network.

FD is triangular. By default, derived from free_flow_speed, jam_density, and reaction_time. Optionally override capacity and/or backward_wave_speed directly; jam_density is then recomputed for consistency.

Parameters:
  • name (str) – Link name.

  • start_node (Node or str) – Upstream node (or its name).

  • end_node (Node or str) – Downstream node (or its name).

  • length (float) – Link length (m).

  • free_flow_speed (float, optional) – Free flow speed u (m/s). Default 20.

  • jam_density (float, optional) – Jam density kappa (veh/m). Default 0.2.

  • merge_priority (float, optional) – Merge priority weight. Default 1.

  • capacity_out (float, optional) – Maximum outflow rate (veh/s). Default 1e10 (inactive).

  • capacity_in (float, optional) – Maximum inflow rate (veh/s). Default 1e10 (inactive).

  • capacity (float or None, optional) – Link capacity q* (veh/s). Overrides the default q*=u*w*kappa/(u+w).

  • backward_wave_speed (float or None, optional) – Congestion wave speed w (m/s). Overrides w=1/(tau*kappa).

  • congestion_pricing (callable or None, optional) – Dynamic congestion pricing function. Takes time (s) as input, returns toll value in seconds (time equivalent). Used as additional cost in DUO route choice. Default None (no toll).

Returns:

The created link.

Return type:

Link

addNode(name, x=0, y=0, flow_capacity=10000000000.0, diverge_ratio=None, absorption_ratio=None, turning_fractions=None, **kwargs)

Add a node to the network.

Parameters:
  • name (str) – Node name.

  • x (float, optional) – X coordinate for visualization.

  • y (float, optional) – Y coordinate for visualization.

  • flow_capacity (float, optional) – Maximum flow rate through this node (veh/s). Default 1e10 (inactive).

  • diverge_ratio (dict[str, float] or None, optional) – Diverge ratios {outlink_name: ratio}. Used when auto_diverge=False.

  • absorption_ratio (float or None, optional) – Fraction of inflow absorbed at this node. Used when auto_diverge=False.

  • turning_fractions (dict[str, dict[str, float]] or None, optional) – Turning fraction matrix for general nodes. Format: {inlink_name: {outlink_name: fraction}}.

Returns:

The created node.

Return type:

Node

adddemand(orig, dest, t_start, t_end, flow=-1, volume=-1, **kwargs)

Add OD traffic demand.

Parameters:
  • orig (str or Node) – Origin node (name or object).

  • dest (str or Node) – Destination node (name or object).

  • t_start (float) – Demand start time (s).

  • t_end (float) – Demand end time (s).

  • flow (float, optional) – Demand flow rate (veh/s). Specify either flow or volume.

  • volume (float, optional) – Total demand volume (veh). Converted to flow internally.

check_simulation_ongoing()

Check if there are remaining timesteps to simulate.

Returns:

True if simulation has not reached TMAX.

Return type:

bool

exec_simulation(duration_t=None)

Run the LTM simulation.

Executes the main loop: compute demand/supply, apply node models, update cumulative counts. For route_choice=”duo”, runs the DUO reactive assignment loop.

Parameters:

duration_t (float or None, optional) – Duration to simulate (s). None runs to completion.

finalize_scenario()

Finalize scenario setup before simulation.

If deltat is None, automatically sets it to min(d_l/u_l) across all links. Validates deltat constraint, initializes arrays, computes shortest paths, diverge/absorption ratios, and creates Analyzer.

Raises:

ValueError – If deltat exceeds d_l/u_l for any link.

Get a link by name.

Parameters:

name (str or Link) – Link name, or Link object (returned as-is).

Return type:

Link

get_node(name)

Get a node by name.

Parameters:

name (str or Node) – Node name, or Node object (returned as-is).

Return type:

Node

Node

class unsim.Node(W, name, x, y, flow_capacity=10000000000.0, diverge_ratio=None, absorption_ratio=None, turning_fractions=None)

Network node.

Parameters:
  • W (World) – Parent world.

  • name (str) – Node name.

  • x (float) – X coordinate for visualization.

  • y (float) – Y coordinate for visualization.

  • flow_capacity (float, optional) – Maximum flow rate through this node (veh/s). Default 1e10 (inactive).

  • diverge_ratio (dict[str, float] or None, optional) – Diverge ratios {outlink_name: ratio}. Used when auto_diverge=False. Ratios for pass-through flow should sum to 1.0. None for equal split.

  • absorption_ratio (float or None, optional) – Fraction of inflow absorbed (destined for this node). 0 for pass-through. Used when auto_diverge=False. None defaults to 0.

  • turning_fractions (dict[str, dict[str, float]] or None, optional) – Turning fraction matrix for general nodes (>=2 inlinks, >=2 outlinks). Format: {inlink_name: {outlink_name: fraction}}. Used by the INM (Incremental Node Model).

Incoming links keyed by name.

Type:

dict[str, Link]

Outgoing links keyed by name.

Type:

dict[str, Link]

demand_queue

Vertical queue length at origin nodes (veh).

Type:

float

diverge_ratios

Fraction of pass-through flow going to each outlink.

Type:

dict[str, float]

absorption_ratio

Fraction of inflow destined for this node (0 for pass-through).

Type:

float

absorbed_count

Cumulative absorbed vehicles (veh).

Type:

float

build_turning_fraction_matrix()

Build the I x J turning fraction matrix from user specification.

Called by World.finalize_scenario() for general nodes. If turning_fractions is not specified, defaults to equal split 1/J.

compute_transfer(t_index, demands, supplies)

Compute flow rates at this node for one timestep.

Dispatches to the appropriate node model based on node type.

Parameters:
  • t_index (int) – Current timestep index.

  • demands (dict[Link, float]) – Demand D_l for each link.

  • supplies (dict[Link, float]) – Supply S_l for each link.

get_demand_at(t)

Get external demand flow rate at time t.

Parameters:

t (float) – Time in seconds.

Returns:

Total demand flow rate (veh/s).

Return type:

float

node_type()

Classify node type from link topology.

Returns:

One of “origin”, “destination”, “dummy”, “merge”, “diverge”, “general”.

Return type:

str