Replaces the prior stub/partial wiki with a Home + Reference-{Architecture,
Contracts,Examples,Limitations} + _Sidebar structure. Topic-contract and
data-model sections wrapped in AUTOGEN markers for the future wiki-gen tool.
Source-vs-spec contradictions surfaced and flagged inline (not silently
fixed). Pending-review notes mark sections that need a full node review.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9.1 KiB
Reference — Examples
Note
Every example flow shipped under
nodes/reactor/examples/, plus how to load them, what they show, and the debug recipes that go with them. Live source:nodes/reactor/examples/.Pending full node review (2026-05). The current flows predate the standard 3-tier example-flow rework that
rotatingMachinehas completed; planned upgrade is tracked in the EVOLV superproject memory ("Example Flows" TODO).
Shipped examples
| File | Tier | Dependencies | What it shows |
|---|---|---|---|
basic.flow.json |
1 | EVOLV only | Single CSTR with one inlet. Inject data.fluent to set influent, data.clock to advance the integrator; watch Fluent effluent on Port 0 and InfluxDB scalars on Port 1. |
integration.flow.json |
2 | EVOLV only | Upstream reactor → reactor → settler chain. The downstream reactor registers the upstream via child.register positionVsParent=upstream; on each upstream stateChange the downstream pulls effluent and advances. |
edge.flow.json |
3 | EVOLV only | PFR with axial dispersion (data.dispersion) and multi-inlet (n_inlets > 1). Emits both GridProfile and Fluent per advance. |
Important
Screenshots needed. Editor capture of each example flow. Save as
wiki/_partial-screenshots/reactor/{01-basic-cstr,02-chain,03-pfr-edge}.png. Replace these callouts with image links once captured.
The legacy additional_nodes/recirculation-pump and additional_nodes/settling-basin Node-RED nodes are shipped from this repo but are not yet refactored to BaseDomain — they aren't part of these examples.
Loading a flow
Via the editor
- Open the Node-RED editor at
http://localhost:1880. - Menu → Import → drag the JSON file.
- Click Deploy.
Via the Admin API
curl -X POST -H 'Content-Type: application/json' \
--data @nodes/reactor/examples/basic.flow.json \
http://localhost:1880/flows
Example — Basic CSTR
Single-reactor flow with one inlet and the minimum set of inputs needed to drive nitrification.
What to do after deploy
- Inject
data.temperaturewithpayload: 15(or whatever process T you want). Optional — default is 20 °C. - Inject
data.fluentwith:Note{ "topic": "data.fluent", "payload": { "inlet": 0, "F": 1000, "C": [0, 30, 70, 25, 0, 0, 5, 1000, 100, 2000, 0, 200, 3500] } }C[11] = 200(X_A — autotroph biomass). If you copy the HTML default of0.001, nitrification never starts. - If
kla > 0is configured, you can skip OTR injection; the engine aerates internally. Otherwise injectdata.otrwith a positive scalar. - Inject
data.clockrepeatedly (or rely on the periodic tick —tickInterval = 1000ms wall-clock). Each advance integratesn_iter = floor(speedUpFactor · Δt / timeStep_days)internal steps. - Watch the debug tap on Port 0:
Fluentenvelopes with the 13-species effluent.S_NHshould fall,S_NOshould rise — nitrification is proceeding.
Important
GIF needed. Demo recording of
S_NH↓ /S_NO↑ over 30 simulated days. Save aswiki/_partial-gifs/reactor/01-basic-cstr.gif.
Example — Reactor chain
Upstream → downstream coupling demo. The downstream reactor registers the upstream via:
{
"topic": "child.register",
"payload": "<upstream-reactor-node-id>",
"positionVsParent": "upstream"
}
On every upstream stateChange, engine._connectReactor triggers downstream updateState. That call first reads upstream.getEffluent into the downstream's Fs[0] / Cs_in[0], then integrates. So one data.clock to the upstream advances the whole chain.
Note
Pending full node review (2026-05). The flow currently in
integration.flow.jsonmay not yet conform to the multi-tab layout standard (Process Plant / Dashboard UI / Demo Drivers / Setup) described in.claude/rules/node-red-flow-layout.md— planned upgrade tracked in the EVOLV "Example Flows" TODO.
Example — PFR edge
Plug-flow reactor with axial discretization. After deploy:
- Inject
data.dispersionwithpayload: <m²/d>to set the axial dispersion coefficientD. - Inject one or more
data.fluentmessages with distinctinletindices (0..n_inlets − 1). - Drive with
data.clockas usual. - Watch Port 0: each advance emits a
GridProfilebefore theFluent. The grid hasn_xrows, 13 columns each. - Add a
measurementchild withasset.type = 'quantity (oxygen)'and a numericpositionVsParent(e.g.5for 5 m from the inlet). On each measurement event the PFR engine writes the value into the nearest grid cell'sS_O.
Stability tips:
Pe_local = d_x · sum(Fs) / (D · A)must be< 2— if you seeLocal Peclet number ... is too high!, either increaseresolution_L(more cells, smallerd_x) or raiseD.Co_D = D · timeStep / d_x²must be< 0.5for the explicit FD scheme — if you seeCourant number ... is too high!, decreasetimeStep.
Debug recipes
| Symptom | First thing to check | Where to look |
|---|---|---|
S_NH stays at its initial value — nitrification not proceeding |
initialState.X_A is effectively zero (HTML default is 0.001 mg/L). Set to ~50 or higher to seed autotrophs. |
reactor.html ↔ generalFunctions/src/configs/reactor.json initialState.X_A |
Fluent payload F = 0 |
No data.fluent arrived, or Fs[0] is still 0 (no inlet flow). Check the message payload shape: {inlet, F, C}. |
src/commands/handlers.js dataFluent, engine setInfluent |
Fluent payload appears, but C array is all zeros / unchanged |
data.clock not arriving, or n_iter = 0 (timestamp delta too small for the configured timeStep). Bump speedUpFactor or check that clock injects are firing. |
engine.updateState in baseEngine.js |
PFR GridProfile not emitted |
reactor.reactor_type is CSTR — only PFR has a grid profile. |
nodeClass._emitOutputs, pfr.getGridProfile |
temperature ignored |
Payload is non-numeric, or wrapped as {value: ...} with value non-finite. Look for Invalid temperature input: <raw> in the log. |
baseEngine.js setTemperature setter |
| Temperature child measurement not reconciling | The child's asset.type must be exactly 'temperature' and positionVsParent = atEquipment. Anything else logs Type '<x>' not recognized for measured update. |
baseEngine.js _updateMeasurement |
Local Peclet number ... is too high! warning on every PFR updateState |
Either D is too small, or d_x is too large. Increase resolution_L or set a larger dispersion. |
pfr.updateState Peclet guard |
Courant number ... is too high! warning |
timeStep is too large for the configured D. Reduce it. |
pfr.updateState Courant guard |
| Settler downstream not updating | Settler must subscribe to the reactor's emitter, not reactor.measurements.emitter. Historical bug in settler/src/specificClass.js _connectReactor (fixed 2026-03-02). |
upstream chain wiring, settler._connectReactor |
wiki:datamodel autogen script slow / timing out |
mathjs cold-start is ~13 s. The current 60 s wrapper sometimes times out. |
known limitation; fall back to the hand-curated Concrete sample in CONTRACT.md Home.md |
reactor_type: 'pfr' (lowercase) silently runs CSTR |
Schema validator lowercases the enum; _buildEngine calls .toUpperCase() to compensate. If you stripped that guard, lowercase pfr falls through to the default branch (CSTR). |
src/specificClass.js _buildEngine |
data.otr value ignored |
reactor.kla > 0. The engine prefers internal kla · (sat − S_O) over external OTR. Set kla = NaN to enable external OTR. |
cstr.tick / pfr.tick klaIsNaN branch |
Never ship
enableLog: 'debug'in a demo — the kinetics engines log per-step on debug, which fills the container log within seconds.
Docker compose snippet
To bring up Node-RED + InfluxDB with EVOLV nodes pre-loaded:
# docker-compose.yml (extract)
services:
nodered:
build: ./docker/nodered
ports: ['1880:1880']
volumes:
- ./docker/nodered/data:/data/evolv
influxdb:
image: influxdb:2.7
ports: ['8086:8086']
Full file: EVOLV/docker-compose.yml.
Related pages
| Page | Why |
|---|---|
| Home | Intuitive overview |
| Reference — Contracts | Topic + config + child filters |
| Reference — Architecture | Code map, kinetics engines, integration sequence |
| Reference — Limitations | Known issues and open questions |
| settler — Examples | The typical downstream Unit |
| EVOLV — Topology Patterns | Where reactor fits in a larger plant |