Skip to content

System Entity Files

The system/ directory holds one registry file for each entity type. This page documents the six registries other than the hydro plants: buses, lines, thermal plants, non-controllable sources, pumping stations and energy contracts. system/buses.json, system/lines.json and system/thermals.json are required; the other three files are optional. The hydro plant registry is on Hydro Plant Files. Every entity carries a required operational_start_date, described once under Shared entity fields.


Methodology: System Element Modeling Overview

Electrical bus registry. Buses are the nodes of the transmission network.

NameTypeRequiredDefaultUnitsDescription
buses[].idintegerYes——Bus identifier (integer, unique)
buses[].namestringYes——Human-readable bus name (string)
buses[].operational_start_datestringYes——Required on every entity; see Shared entity fields.
buses[].deficit_segmentsarray | nullNo——Entity-level deficit cost tiers; when present they replace bus.deficit_segments in penalties.json for this bus and follow the same rules (non-empty, costs strictly increasing, last depth_mw null)
buses[].deficit_segments[].depth_mwnumber | nullNo—MWSegment depth (MW); the last segment’s depth_mw must be null (unbounded)
buses[].deficit_segments[].costnumberYes—USD/MWhCost per MWh of deficit in this tier (USD/MWh); > 0

Methodology: System Element Modeling Overview · Equipment-Specific Formulations

Transmission line registry. Lines connect buses and carry power flows.

NameTypeRequiredDefaultUnitsDescription
lines[].idintegerYes——Line identifier (integer, unique)
lines[].namestringYes——Human-readable line name (string)
lines[].source_bus_idintegerYes——Sending-end bus ID
lines[].target_bus_idintegerYes——Receiving-end bus ID
lines[].operational_start_datestringYes——Required on every entity; see Shared entity fields.
lines[].entry_stage_idinteger | nullNonull—Stage when line enters service; null = always exists
lines[].exit_stage_idinteger | nullNonull—Stage when line is decommissioned; null = never
lines[].capacity.direct_mwnumberYes—MWMaximum power flow in the direct direction (MW)
lines[].capacity.reverse_mwnumberYes—MWMaximum power flow in the reverse direction (MW)
lines[].exchange_costnumber | nullNonullUSD/MWhEntity-level exchange cost override (USD/MWh); absent = line.exchange_cost in penalties.json
lines[].losses_percentnumberNo0.0%Transmission losses as percentage (default: 0.0)

Validation:

  • entry_stage_id must be less than exit_stage_id when both are set.
  • capacity.direct_mw, capacity.reverse_mw and losses_percent must be >= 0.

Methodology: Equipment-Specific Formulations · State Augmentation

Thermal plant registry. Each entry defines a dispatchable generation unit.

NameTypeRequiredDefaultUnitsDescription
thermals[].idintegerYes——Plant identifier (integer, unique)
thermals[].namestringYes——Human-readable plant name
thermals[].bus_idintegerYes——Bus where generation is injected
thermals[].generationobjectYes——Dispatch-bounds object with min_mw and max_mw
thermals[].generation.min_mwnumberYes—MWMinimum dispatch level (MW)
thermals[].generation.max_mwnumberYes—MWMaximum dispatch level (MW)
thermals[].cost_per_mwhnumberYes—USD/MWhLinear generation cost (USD/MWh)
thermals[].operational_start_datestringYes——Required on every entity; see Shared entity fields.
thermals[].entry_stage_idinteger | nullNonull—Stage when the unit enters service (null = present from stage 0)
thermals[].exit_stage_idinteger | nullNonull—Stage when the unit is decommissioned (null = never)
thermals[].anticipated_configobject | nullNo——Anticipated-dispatch lead: an object with exactly one of lead_stages (integer >= 1) or lead_time_hours (finite and > 0); both or neither is rejected at load. See the Equipment-Specific Formulations Configure tab
thermals[].anticipated_config.lead_stagesintegerConditional——Anticipated-dispatch lead in stages (integer >= 1). Exactly one of lead_stages or lead_time_hours is set; both or neither is rejected at load.
thermals[].anticipated_config.lead_time_hoursnumberConditional—hAnticipated-dispatch lead in hours (finite and > 0). Exactly one of lead_stages or lead_time_hours is set; both or neither is rejected at load.

Validation:

  • entry_stage_id must be less than exit_stage_id when both are set.
  • generation.min_mw and generation.max_mw must be >= 0, with max_mw >= min_mw; cost_per_mwh must be >= 0.

Methodology: Equipment-Specific Formulations

Non-controllable source (NCS) registry. Each entry defines an intermittent or aggregate generator — wind, solar, small hydro, biomass, distributed generation — whose available output is a scenario input rather than a free LP decision. The file is optional; when absent, no non-controllable sources are modeled. Per-scenario availability is supplied by the scenarios/non_controllable_factors.json and scenarios/non_controllable_stats.parquet inputs.

NameTypeRequiredDefaultUnitsDescription
non_controllable_sources[].idintegerYes——Source identifier (integer, unique within the file)
non_controllable_sources[].namestringYes——Human-readable source name (string)
non_controllable_sources[].bus_idintegerYes——Bus into which the source’s generation is injected
non_controllable_sources[].operational_start_datestringYes——Required on every entity; see Shared entity fields.
non_controllable_sources[].max_generation_mwnumberYes—MWInstalled capacity [MW]; it scales the stochastic availability and does not cap the available generation
non_controllable_sources[].allow_curtailmentbooleanNotrue—Whether the LP may curtail this source. true (default) — dispatch within [0, max_generation_mw × availability] at the curtailment cost; false — must-run, dispatch pinned to the realized availability every scenario
non_controllable_sources[].curtailment_costnumber | nullNonullUSD/MWhEntity-level curtailment cost override [USD/MWh]; falls back to non_controllable_source.curtailment_cost in penalties.json when absent
non_controllable_sources[].entry_stage_idinteger | nullNonull—Stage when the source enters service; null or absent = present from stage 0
non_controllable_sources[].exit_stage_idinteger | nullNonull—Stage when the source is decommissioned; null or absent = never

Minimal valid example:

{
"$schema": "https://docs.novomodelo.invalid/schemas/non_controllable_sources.schema.json",
"non_controllable_sources": [
{
"id": 0,
"name": "Complexo Eólico Nordeste",
"bus_id": 4,
"operational_start_date": "2015-06-01",
"max_generation_mw": 1200.0
}
]
}

Validation:

  • entry_stage_id must be less than exit_stage_id when both are set.
  • max_generation_mw must be >= 0.

Methodology: Equipment-Specific Formulations

Pumping station registry. Each entry defines a pumped-storage or water-transfer installation that withdraws water from a source hydro reservoir, injects it into a destination hydro reservoir, and consumes electrical power from a bus. The file is optional; when absent, no pumping stations are modeled.

NameTypeRequiredDefaultUnitsDescription
pumping_stations[].idintegerYes——Station identifier (integer, unique)
pumping_stations[].namestringYes——Human-readable station name (string)
pumping_stations[].bus_idintegerYes——Bus from which electrical power is consumed
pumping_stations[].source_hydro_idintegerYes——Hydro plant from whose reservoir water is extracted
pumping_stations[].destination_hydro_idintegerYes——Hydro plant into whose reservoir water is injected
pumping_stations[].consumption_mw_per_m3snumberYes—MW/(m³/s)Power drawn per unit of pumped flow [MW/(m³/s)]; must be >= 0
pumping_stations[].operational_start_datestringYes——Required on every entity; see Shared entity fields.
pumping_stations[].entry_stage_idinteger | nullNonull—Stage when the station enters service; null or absent = present from stage 0
pumping_stations[].exit_stage_idinteger | nullNonull—Stage when the station is decommissioned; null or absent = never
pumping_stations[].flowobjectYes——Nested object with min_m3s and max_m3s (see below)
pumping_stations[].flow.min_m3snumberYes—m³/sMinimum pumped flow [m³/s]; must be >= 0
pumping_stations[].flow.max_m3snumberYes—m³/sMaximum pumped flow (installed pump capacity) [m³/s]; must be >= flow.min_m3s

The pumped flow variable is bounded by [flow.min_m3s, flow.max_m3s] in the LP. At each stage within [entry_stage_id, exit_stage_id), the flow appears with a negative sign in the source reservoir water-balance row and a positive sign in the destination reservoir water-balance row. Power consumed equals consumption_mw_per_m3s × flow_m3s and is charged as load on the station’s bus. Stage-varying flow bounds can be overridden via constraints/pumping_bounds.parquet.

Minimal valid example:

{
"$schema": "https://docs.novomodelo.invalid/schemas/pumping_stations.schema.json",
"pumping_stations": [
{
"id": 0,
"name": "Bombeamento Serra da Mesa",
"bus_id": 10,
"operational_start_date": "2010-09-15",
"source_hydro_id": 3,
"destination_hydro_id": 5,
"consumption_mw_per_m3s": 0.5,
"flow": { "min_m3s": 0.0, "max_m3s": 150.0 }
}
]
}

Validation:

  • entry_stage_id must be less than exit_stage_id when both are set.
  • source_hydro_id must differ from destination_hydro_id.
  • The station is in service only at stages where both its source and its destination hydro are Operating (neither PreFilling nor Filling); see Equipment-Specific Formulations for the rule.

Methodology: Equipment-Specific Formulations

Energy contract registry. Each entry defines a bilateral energy purchase or sale obligation with a counterparty outside the modeled system. The file is optional; when absent, no contracts are modeled.

NameTypeRequiredDefaultUnitsDescription
contracts[].idintegerYes——Contract identifier (integer, unique)
contracts[].namestringYes——Human-readable contract name (string)
contracts[].bus_idintegerYes——Bus where power is injected (import) or withdrawn (export)
contracts[].typestringYes——One of "import", "export". Energy flow direction.
contracts[].price_per_mwhnumberYes—USD/MWhContract price [USD/MWh]. Positive = cost (import); negative = revenue (export)
contracts[].limits.min_mwnumberYes—MWMinimum dispatch level [MW]; use 0.0 unless a take-or-pay floor applies
contracts[].limits.max_mwnumberYes—MWMaximum dispatch level [MW]; must be >= limits.min_mw
contracts[].operational_start_datestringYes——Required on every entity; see Shared entity fields.
contracts[].entry_stage_idinteger | nullNonull—Stage when the contract enters service; null or absent = present from stage 0
contracts[].exit_stage_idinteger | nullNonull—Stage when the contract is decommissioned; null or absent = never

At each active stage within [entry_stage_id, exit_stage_id), the LP adds one column per block per direction bounded by [limits.min_mw, limits.max_mw]. An import column injects +1.0 MW into the bus power-balance row; an export column withdraws −1.0 MW. At dormant stages the column bounds are pinned to [0, 0] and the output row is emitted with power_mw = 0. Stage-varying bounds and prices can be overridden via constraints/contract_bounds.parquet.

Minimal valid example:

{
"$schema": "https://docs.novomodelo.invalid/schemas/energy_contracts.schema.json",
"contracts": [
{
"id": 0,
"name": "Import base load",
"bus_id": 0,
"operational_start_date": "2018-01-01",
"type": "import",
"price_per_mwh": 200.0,
"limits": { "min_mw": 0.0, "max_mw": 50.0 }
},
{
"id": 1,
"name": "Export revenue (stage 1 only)",
"bus_id": 0,
"operational_start_date": "2019-06-01",
"type": "export",
"entry_stage_id": 1,
"exit_stage_id": 2,
"price_per_mwh": -150.0,
"limits": { "min_mw": 0.0, "max_mw": 30.0 }
}
]
}

Validation:

  • entry_stage_id must be less than exit_stage_id when both are set.
  • limits.min_mw and limits.max_mw must be >= 0.