{ "cells": [ { "cell_type": "markdown", "id": "10e90835", "metadata": {}, "source": [ "# `node-model` — Tampere et al.'s (2011) generic first-order node model\n", "\n", "**What.** `TampereNode` resolves ANY merge/diverge junction (multiple incoming,\n", "multiple outgoing links) into per-approach transfer flows from each incoming\n", "link's sending flow, each outgoing link's receiving flow, and the mandated\n", "turning fractions — satisfying six node axioms (N1 conservation, N2\n", "non-negativity, N3 supply/demand respect, N4 turn-fraction fidelity, N5\n", "maximal transfer, N6 invariance to inflating an already-unconstrained sending\n", "flow). It generalizes the trivial 1-in/1-out series-node `min(s, r)` rule\n", "`ctm`/`ltm`/`godunov` silently use elsewhere in this track.\n", "\n", "**Why it is in the benchmark.** Every DNL link model in this benchmark shares\n", "ONE node layer — `TampereNode` is what turns single-link loading into NETWORK\n", "loading, and it is what makes `C8` (turning-fraction fidelity) a certifiable,\n", "gating property rather than a modeling assumption. See the\n", "[model compendium](../../docs/MODELS.md) (Tampere et al. 2011) and\n", "[docs/design/adr-017-node-model.md](../../docs/design/adr-017-node-model.md)\n", "(P1).\n", "\n", "**Scope.** This notebook exercises `TampereNode.transfer` directly on hand-\n", "computable merge/diverge anchors (exact fractions, axiom-checked), then loads a\n", "small diverge network end-to-end through `NetworkLoader` and certifies `C8`\n", "turn fidelity via `DNLEvaluator`.\n", "\n", "**Canon.** `[tampere2011generic]`, [docs/REFERENCES.md](../../docs/REFERENCES.md) / [docs/references.bib](../../docs/references.bib)." ] }, { "cell_type": "markdown", "id": "2b44ce96", "metadata": {}, "source": [ "## How this notebook is graded\n", "\n", "**A notebook never claims a number it does not compute in that cell.** The\n", "node-level anchors below are checked against `assert_node_axioms` (the same\n", "axiom checker the test suite uses) in the cell where they are claimed; the\n", "end-to-end network result is recomputed live by the P1 `DNLEvaluator` from the\n", "cumulative link curves the loader emitted — no self-report to diff, exactly as\n", "in `ctm`/`ltm`/`godunov`\n", "([README](../../README.md), *Certified, not self-reported*)." ] }, { "cell_type": "code", "execution_count": 1, "id": "60454743", "metadata": { "execution": { "iopub.execute_input": "2026-07-21T13:48:35.795091Z", "iopub.status.busy": "2026-07-21T13:48:35.794936Z", "iopub.status.idle": "2026-07-21T13:48:37.805884Z", "shell.execute_reply": "2026-07-21T13:48:37.804575Z" } }, "outputs": [], "source": [ "# Setup. `node-model` is core: a plain `pip install -e .` suffices — no\n", "# optional extra, so no guard cell. The inline backend is Agg-based (headless\n", "# CI renders into the notebook); NEVER matplotlib.use(\"Agg\") in-kernel — it\n", "# silently suppresses inline figure capture.\n", "%matplotlib inline\n", "import numpy as np\n", "\n", "from tabench import (\n", " CTMLink,\n", " DNLEvaluator,\n", " DynamicDemand,\n", " DynamicScenario,\n", " LinkDynamics,\n", " NetworkLoader,\n", " TampereNode,\n", " TimeGrid,\n", " TurningFractions,\n", " assert_node_axioms,\n", " viz,\n", ")\n", "from tabench.core.scenario import Network" ] }, { "cell_type": "markdown", "id": "ddbc459f", "metadata": {}, "source": [ "## Node anchors: merge and diverge, exact fractions\n", "\n", "Two hand-computable cases, each checked against the six node axioms via\n", "`assert_node_axioms` (N1 conservation, N2 non-negativity, N3 supply/demand\n", "respect, N4 turn fidelity, N5 maximal transfer): a capacity-proportional merge\n", "(two equal-sending approaches, an out-link supplying less than both want,\n", "split by out-link capacity share), and a FIFO diverge (one approach splitting\n", "0.6/0.4 into two out-links, one of which can only accept 0.4 — FIFO holds the\n", "WHOLE approach back proportionally, not just the blocked movement)." ] }, { "cell_type": "code", "execution_count": 2, "id": "6cd62bad", "metadata": { "execution": { "iopub.execute_input": "2026-07-21T13:48:37.810813Z", "iopub.status.busy": "2026-07-21T13:48:37.810433Z", "iopub.status.idle": "2026-07-21T13:48:37.818701Z", "shell.execute_reply": "2026-07-21T13:48:37.817820Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "merge transfer (2:1 capacity share) : [0.66666667 0.33333333]\n", "diverge transfer (FIFO holdback) : [0.6 0.4]\n" ] } ], "source": [ "node = TampereNode()\n", "\n", "# Merge: 2 in -> 1 out. Both approaches send 1, out-link supplies 1, capacities\n", "# [2, 1] -> capacity-proportional share (2:1).\n", "s, r, turns, caps = np.array([1.0, 1.0]), np.array([1.0]), np.array([[1.0], [1.0]]), np.array([2.0, 1.0])\n", "q_merge = node.transfer(s, r, turns, caps)\n", "assert_node_axioms(q_merge, s, r, turns, eps=1e-9)\n", "print(f\"merge transfer (2:1 capacity share) : {q_merge.ravel()}\")\n", "np.testing.assert_allclose(q_merge, [[2 / 3], [1 / 3]], atol=1e-12)\n", "\n", "# Diverge: 1 in -> 2 out. Approach wants to split 0.6/0.4; out-link 2 supplies\n", "# only 0.4 -> FIFO throttles the WHOLE approach: only 1 of the 2 units the\n", "# approach is sending transfer, split in the SAME 0.6/0.4 ratio.\n", "s, r, turns, caps = np.array([2.0]), np.array([1e6, 0.4]), np.array([[0.6, 0.4]]), np.array([1.0])\n", "q_div = node.transfer(s, r, turns, caps)\n", "assert_node_axioms(q_div, s, r, turns, eps=1e-9)\n", "print(f\"diverge transfer (FIFO holdback) : {q_div.ravel()}\")\n", "np.testing.assert_allclose(q_div, [[0.6, 0.4]], atol=1e-12)" ] }, { "cell_type": "markdown", "id": "ca333f16", "metadata": {}, "source": [ "## End-to-end: a diverge network through the loader\n", "\n", "A small network — origin zone 1 -> interior node 4 -> two destinations (zone 2\n", "direct, zone 3 via node 4) — with a mandated 0.6/0.4 turning split at node 4.\n", "`NetworkLoader` defaults interior >1-out-link nodes to `TampereNode`\n", "automatically (no explicit `node_models` argument needed)." ] }, { "cell_type": "code", "execution_count": 3, "id": "cbcdda43", "metadata": { "execution": { "iopub.execute_input": "2026-07-21T13:48:37.822719Z", "iopub.status.busy": "2026-07-21T13:48:37.822395Z", "iopub.status.idle": "2026-07-21T13:48:37.835013Z", "shell.execute_reply": "2026-07-21T13:48:37.834128Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "scenario : node-model-diverge\n", "content hash : 7b4bf0afdd3362fc…\n", "links : 3 (tail→head: 1->4, 4->2, 4->3)\n", "task : deterministic DNL loading (feasibility + conservation + turn fidelity)\n", "storage at t=16 : [0. 1.8 1.2] (per link)\n" ] } ], "source": [ "net = Network(\n", " name=\"node-model-diverge\", n_nodes=4, n_zones=3, first_thru_node=4,\n", " init_node=np.array([1, 4, 4]), term_node=np.array([4, 2, 3]),\n", " capacity=np.ones(3), length=np.zeros(3), free_flow_time=np.ones(3),\n", " b=np.zeros(3), power=np.ones(3), toll=np.zeros(3), link_type=np.ones(3, dtype=np.int64),\n", ")\n", "rates = np.zeros((1, 3, 3))\n", "rates[0, 0, 1] = 0.9 # zone 1 -> zone 2\n", "rates[0, 0, 2] = 0.6 # zone 1 -> zone 3\n", "scenario = DynamicScenario(\n", " name=\"node-model-diverge\", network=net,\n", " dynamics=LinkDynamics(\n", " length=np.full(3, 4.0), free_speed=np.full(3, 1.0), wave_speed=np.full(3, 1.0),\n", " jam_density=np.full(3, 4.0), capacity=np.full(3, 2.0),\n", " ),\n", " demand=DynamicDemand(breakpoints=np.array([0.0, 10.0]), rates=rates),\n", " grid=TimeGrid(dt=1.0, n_steps=16),\n", " turns=TurningFractions(frac=((4, np.array([[0.6, 0.4]])),)),\n", ")\n", "print(f\"scenario : {scenario.name}\")\n", "print(f\"content hash : {scenario.content_hash()[:16]}…\")\n", "print(f\"links : {net.n_links} (tail→head: \"\n", " + \", \".join(f\"{i}->{j}\" for i, j in zip(net.init_node, net.term_node)) + \")\")\n", "print(\"task : deterministic DNL loading (feasibility + conservation + turn fidelity)\")\n", "\n", "out = NetworkLoader(scenario, CTMLink).run()\n", "print(f\"storage at t={scenario.grid.edges[-1]:.0f} : \"\n", " f\"{(out.n_in[:, -1] - out.n_out[:, -1]).round(3)} (per link)\")" ] }, { "cell_type": "markdown", "id": "0c7a5612", "metadata": {}, "source": [ "## Certify (P1) — feasibility, conservation, and turn fidelity (C8)\n", "\n", "`C8` recovers the mandated 0.6/0.4 split exactly from the emitted per-link\n", "outflow curves alone (`d_in[out_j] == sum_i frac[i, j] * d_out[in_i]`) — a\n", "necessary condition on aggregate counts, gating here." ] }, { "cell_type": "code", "execution_count": 4, "id": "dd17b4b9", "metadata": { "execution": { "iopub.execute_input": "2026-07-21T13:48:37.839070Z", "iopub.status.busy": "2026-07-21T13:48:37.838380Z", "iopub.status.idle": "2026-07-21T13:48:37.845592Z", "shell.execute_reply": "2026-07-21T13:48:37.844741Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "dnl_feasible : 1\n", "conservation_residual : 1.776e-15\n", "turn_residual : 4.441e-16\n", "emitted per-step split matches the mandated 0.6/0.4 turning fractions exactly\n" ] } ], "source": [ "metrics = DNLEvaluator(scenario).evaluate(out)\n", "print(f\"dnl_feasible : {metrics['dnl_feasible']:.0f}\")\n", "print(f\"conservation_residual : {metrics['conservation_residual']:.3e}\")\n", "print(f\"turn_residual : {metrics['turn_residual']:.3e}\")\n", "assert metrics[\"dnl_feasible\"] == 1.0\n", "assert metrics[\"conservation_residual\"] <= 1e-9\n", "assert metrics[\"turn_residual\"] <= 1e-9\n", "\n", "# Recompute the mandated split directly from the emitted outflow curves — not\n", "# quoting DNLEvaluator's internal check, redoing it here.\n", "d_out_in = np.diff(out.n_out[0]) # per-step outflow of the approach (link 0)\n", "d_in_a = np.diff(out.n_in[1]) # per-step inflow of out-link A (link 1, -> zone 2)\n", "d_in_b = np.diff(out.n_in[2]) # per-step inflow of out-link B (link 2, -> zone 3)\n", "mandated_a, mandated_b = 0.6 * d_out_in, 0.4 * d_out_in\n", "np.testing.assert_allclose(d_in_a, mandated_a, atol=1e-9)\n", "np.testing.assert_allclose(d_in_b, mandated_b, atol=1e-9)\n", "print(\"emitted per-step split matches the mandated 0.6/0.4 turning fractions exactly\")" ] }, { "cell_type": "markdown", "id": "82d6f730", "metadata": {}, "source": [ "## Visualize\n", "\n", "Both figures come from `tabench.viz`, the house visualizer. Left/top: the\n", "certified diverge network coloured by each link's time-averaged flow. Right/\n", "bottom: the loaded average flow against the mandated 0.6/0.4 split applied to\n", "the approach's own average flow — the recomputed anchor above, restated as a\n", "flow vector." ] }, { "cell_type": "code", "execution_count": 5, "id": "dfa9575b", "metadata": { "execution": { "iopub.execute_input": "2026-07-21T13:48:37.848856Z", "iopub.status.busy": "2026-07-21T13:48:37.848682Z", "iopub.status.idle": "2026-07-21T13:48:38.100466Z", "shell.execute_reply": "2026-07-21T13:48:38.099107Z" } }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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PPEE9u7di9On/1djTVarFX//+yP45z9fqbV2AFi7di2uvvoaJCYm4corr8Lzzz8PoDS4U1JSsGLFCnTocAXat++AhQsXVvi/K69sybO2ca9N+RnxokWLMH78eDz00DykpKSgU6fO+OSTDdV+ndPpxIwZMzBixEhYrdYKjx06dAg9e14HoPT60t26da/2HGvWrEHPntchJSUFN9wwFAcPHgQAfP/99+jQ4QrPcY8++iiMRpNnJWHFihUYP378Zf9t5H8YmtSkNm7cgFWrPsCvv/6Cc+fOITU1FYMHD8Lp06cxduytmDt3rufY2NhYrFr1Ac6eTcdHH32Id999D+vWrat0vo3YvPkzHD16BOfOnceyZcsAALm5eZg4cSKmTJmCtLQzuO22yVi7dm2Frx00aCD++98DOH36FMaMGYM77rgTVqsV3bp1wyuvvIxOnTri/PlzOH/+HJKTk7F9+3Y8/vjjWLZsGf73v//hwQfnYvz4CcjJyQEAPPzww7BYLDh8+DA2b/4MH330ca1j8fPPP6NLly6ej7t27YKioiL8/vvv1R6/d+9elJSUoH///mjTpi1Gjx6DEydOVDhm69atuOmmG6s9f3x8PBISEnDsWM37f0899TQmTBiPtm3b1lp7YWEhZsyYiSVL/oVz585i//59+MtfUj2PW60FOHToEA4e/An//vfnWLVqNT766KNaz1nTuPvq66//g759++L06dN47LFHMWvWrCqhWFhYiAkTJsJuL8L69esQERFRpZb9+/cBAI4d+xmHDh2s8jx79+7Fgw/+Ff/85ys4efIkRo4cgTFjboXFYkH37t1hs9lw/PhxAMDOnbuQnJyMfftKz7lr1y4MHDjQ538byY+hSU3qnnvuRVJSEqKiojBkyBDExsZixIgRUCqVGD16NI4d+wUlJSUAgCFDhqBdu3aQJAldu3bFrbeOwe7deyqcb86c2YiLi0N0dDRGjBjh+Ut/27ataNasOe65526oVCrceOONVX5J3XbbbYiKioJarcbs2bPgdrtrbSh54403MWvW/6F79+5QKBQYMWIEOnTogO3bt8PlcmHDho14/PHHEB0djebNm2PWrFm1jkVBQQGiyt3uS61WQ6/X17ivmZubiw0bNmDlypX45Zdj6Ny5MyZOnASn0wmgtPFIq9Wiffv2f5y/sML5gdJbR9V0/gMHDmDPnj2Y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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "T = float(scenario.grid.edges[-1])\n", "avg_flow = out.n_out[:, -1] / T\n", "ref_avg_flow = np.array([avg_flow[0], 0.6 * avg_flow[0], 0.4 * avg_flow[0]])\n", "\n", "display(viz.plot_network_flows(net, avg_flow))\n", "display(viz.plot_flow_scatter((\"mandated 0.6/0.4 split\", ref_avg_flow), {\"node-model\": avg_flow}))" ] }, { "cell_type": "markdown", "id": "bead4701", "metadata": {}, "source": [ "## Takeaways & pointers\n", "\n", "- **Certified, not self-reported.** DNL link/node models have nothing to\n", " self-report — the emitted curves ARE the output, recertified from scratch by\n", " `DNLEvaluator`.\n", "- **One node layer, every link model.** `TampereNode` is what `ctm`, `ltm`, and\n", " `godunov` all delegate junction physics to; none of them contain merge/diverge\n", " logic themselves.\n", "- **Where next.** the link models it serves:\n", " [`ctm`](01-ctm.ipynb) · [`ltm`](02-ltm.ipynb) · [`godunov`](03-godunov.ipynb);\n", " the lineage in the [model compendium](../../docs/MODELS.md)." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.12" }, "tabench": { "covers": [], "requires_extra": null, "track": "dnl", "unit": "node-model" } }, "nbformat": 4, "nbformat_minor": 5 }