System Element Modeling Overview
Purpose
Section titled “Purpose”This chapter describes the physical components of a hydrothermal power system as modeled by Novomodelo: what each element represents, its decision variables, how it connects to other elements, and its role in the optimization objective. It is the conceptual foundation for the equipment formulations and the stage LP — the reader should understand what is being optimized before seeing how the constraints are assembled.
Reading order: this chapter → Equipment-Specific Formulations → LP Formulation
For variable naming conventions and index sets, see Notation Conventions. For equivalent terms in other planning tools, see the Glossary.
Variable Units Convention
Section titled “Variable Units Convention”All decision variables in Novomodelo use rate units: electrical quantities in MW, hydraulic flows in m³/s. Storage (hm³) is inherently an absolute quantity. The block duration [hours] enters the LP as an external multiplier — it appears in the objective function coefficients and in the coefficients that convert a rate to a volume or an energy, such as the water balance conversion factor.
Rate units keep every variable bound and the load-balance and production-function coefficients independent of the block durations, and the FPHA hyperplanes relate these rates to storage. The convention has these consequences across the formulation:
| Aspect | Consequence |
|---|---|
| Objective function | All cost terms are scaled by : the coefficient for a thermal with marginal cost is |
| Variable bounds | Independent of the block durations — a capacity bound is the same whatever the block duration |
| Constraint matrix | Clean coefficients: load balance has ±1, production function uses [MW/(m³/s)] directly |
| Duals | Load balance dual has units $/MW. To obtain the marginal cost (CMO) in $/MWh, divide by |
| Cut coefficients | Unaffected — coupling state variables (storage in hm³, AR lags in m³/s) are independent of this choice |
The objective row can carry large coefficients: the product of a long block duration and a steep deficit penalty dwarfs the coefficients of ordinary cost terms by several orders of magnitude. This conditioning is applied offline, before the solve, so the solver receives an already-conditioned matrix — see LP Layout and Scaling for the derivation.
1. System Architecture Overview
Section titled “1. System Architecture Overview”A hydrothermal power system in Novomodelo consists of interconnected physical elements that work together to meet electricity demand at minimum cost under inflow uncertainty:
System element overview — buses, a hydro plant with its reservoir (inflow in),
a thermal plant, an NCS (wind/solar) source, a transmission line between buses, a
demand draw (D) off each bus, and a deficit slack (δ, dashed) backstopping
unserved load. Key flow variables are labelled (f line flow, q hydro
turbined, g thermal, gⁿᶜ NCS, δ deficit, D demand).
The optimizer determines generation and flow decisions at each stage to minimize total expected cost (thermal generation + deficit penalties + regularization costs) while respecting physical constraints and preparing for uncertain future inflows.
Entity Commissioning Windows
Section titled “Entity Commissioning Windows”Most entity types may enter service or be decommissioned partway through the horizon, so that planning studies can represent new plants coming online and aging units retiring. An entity carries an optional commissioning window defined by two stages, its entry stage and its exit stage. The window is half-open: the entity is active from its entry stage up to, but not including, its exit stage — the entry stage is inclusive and the exit stage is exclusive, so the entity is gone from its exit stage onward. An entity without an entry stage is active from the first stage, one without an exit stage is never decommissioned, and one that declares neither is active at every stage.
This window applies uniformly to transmission lines, thermal plants, non-controllable sources, pumping stations, and contracts (and, for generation, to hydro plants). Outside its window an entity contributes nothing to the dispatch: its decision columns are present in the LP but pinned to zero, so it injects no power, withdraws no power, and consumes no resource. A hydro plant is the exception to this simple zero-pin: outside its commissioning window a hydro without filling enters the PreFilling state (§5), which pins its turbine, spillage, and diversion to zero but freezes its storage and routes natural inflow past the not-yet-in-service site rather than trapping or injecting water. Decommissioning is symmetric to commissioning — both are expressed by the same window. The per-phase LP treatment of hydros and the out-of-window pins of the other entities are tabulated in LP Formulation — Lifecycle Phases.
Two element-specific lifecycle mechanisms layer on top of this generic window:
- Hydro dead-volume filling (§5) — a hydro plant may exist but be unable to generate while its reservoir is still filling toward the dead volume; this is a distinct commissioning state with its own per-stage storage floors, not just a presence gate.
- Anticipated thermals (§4) — a commitment column is opened only when its delivery stage lies inside the study or on a declared post-study stage and the plant is commissioned at that delivery stage, whatever its status at the decision stage.
Operational Start Date
Section titled “Operational Start Date”Independent of the commissioning window, every entity also carries a required start date, the calendar date on which it enters operation. The date is provenance and the canonical ordering key only: it fixes the entity’s position in the canonical entity order of Notation Conventions, which every state block, the LP column layout, and the output column order follow (Determinism & Provenance). It does not compute or gate commissioning. Presence in the dispatch is decided solely by the entry and exit stages of the window above: the window and the start date are independent, and neither is derived from the other.
2. Buses (Regional Subsystems)
Section titled “2. Buses (Regional Subsystems)”Physical Meaning
Section titled “Physical Meaning”A bus represents a node in the power network where electrical energy balance must be maintained. The granularity is user-defined: a bus may represent a large regional subsystem, a single substation, or any aggregation level in between. The model scales from a handful of buses to hundreds or thousands without structural changes.
Decision Variables
Section titled “Decision Variables”| Variable | Units | Description |
|---|---|---|
| MW | Load deficit (unserved energy) at bus , block , segment | |
| MW | Excess generation at bus , block |
Connections to Other Elements
Section titled “Connections to Other Elements”Each bus serves as the energy balance node where:
- Inflows: Generation from hydro plants, thermal plants, and import contracts connected to the bus
- Outflows: Demand, export contracts, pumping station consumption, and transmission to other buses
Key Parameters
Section titled “Key Parameters”| Parameter | Units | Description |
|---|---|---|
| MW | Load demand at bus , block | |
| $/MWh | Deficit cost (value of unserved energy), segment | |
| $/MWh | Excess generation penalty (regularization) | |
| MW | Deficit segment depth |
Role in Objective Function
Section titled “Role in Objective Function”Each bus contributes the cost of its deficit, piecewise over its deficit segments , and the cost of its excess generation, both weighted by the block durations (LP Formulation §2).
- Deficit cost: Very high penalty representing the value of lost load
- Excess cost: Small regularization term to eliminate spurious slack generation
LP Constraint Preview
Section titled “LP Constraint Preview”For each bus and block , the load balance constraint equates the generation injected at the bus, the power entering over lines and import contracts, and the deficit, less the power leaving over lines and export contracts, the pumping consumption and the excess, to the demand (LP Formulation §3).
3. Transmission Lines
Section titled “3. Transmission Lines”Physical Meaning
Section titled “Physical Meaning”A transmission line represents the interconnection between two buses, allowing power transfer subject to capacity limits. Lines are bidirectional and lossless in the dispatch LP — transmission losses are computed and reported as an output quantity, not modeled as a reduction of delivered power (see the Configure/I·O tabs).
Decision Variables
Section titled “Decision Variables”| Variable | Units | Description |
|---|---|---|
| MW | Direct flow on line (source → target), block | |
| MW | Reverse flow on line (target → source), block |
Connections to Other Elements
Section titled “Connections to Other Elements”Each line connects exactly two buses:
- Source bus: Exports , receives
- Target bus: Receives , exports
Key Parameters
Section titled “Key Parameters”| Parameter | Units | Description |
|---|---|---|
| MW | Capacity limit (direct direction); may vary by stage and, optionally, by block | |
| MW | Capacity limit (reverse direction); may vary by stage and, optionally, by block | |
| $/MWh | Exchange cost (regularization) |
Role in Objective Function
Section titled “Role in Objective Function”The exchange cost is a regularization term — a small per-unit cost on interchange flow — that prevents degenerate solutions with unnecessary power circulation and guides the solver toward physically meaningful flow patterns (Equipment-Specific Formulations §2).
LP Constraint Preview
Section titled “LP Constraint Preview”Each flow direction is bounded by its capacity; the direct flow leaves the source bus and enters the target bus, and the reverse flow does the opposite (Equipment-Specific Formulations §2).
4. Thermal Plants
Section titled “4. Thermal Plants”Physical Meaning
Section titled “Physical Meaning”A thermal plant represents dispatchable generation using fuel (natural gas, coal, oil, biomass, nuclear). Each plant has one marginal cost per MWh of generation.
Decision Variables
Section titled “Decision Variables”| Variable | Units | Description |
|---|---|---|
| MW | Generation at thermal plant , block |
Connections to Other Elements
Section titled “Connections to Other Elements”- Bus connection: Each thermal plant connects to exactly one bus, contributing to its energy balance
- No cascade coupling: Unlike hydro plants, thermals are independent of each other
Key Parameters
Section titled “Key Parameters”| Parameter | Units | Description |
|---|---|---|
| , | MW | Generation bounds (capacity, minimum stable load) |
| $/MWh | Marginal cost of generation (fuel + O&M) |
Role in Objective Function
Section titled “Role in Objective Function”Thermal costs represent actual operating expenses, which vary by fuel type, and constitute the primary controllable cost in the objective function (Equipment-Specific Formulations §1.1).
LP Constraint Preview
Section titled “LP Constraint Preview”The generation of each block lies between the plant’s minimum generation and its capacity (Equipment-Specific Formulations §1.1).
Anticipated Thermal Plants
Section titled “Anticipated Thermal Plants”A thermal plant may be flagged as anticipated. The physical motivation is fuel-ordering lead time: LNG terminals, long-haul coal contracts and similar arrangements require the dispatch quantity to be committed before the energy is physically delivered. An anticipated plant therefore decides the commitment of each delivery at a stage before its delivery stage , and the plant’s generation at stage must match that commitment.
The lead is a stage count or a physical lead time, and it fixes the decision stage of each delivery (see State Augmentation §5). A delivery decided within its own stage — a physical lead shorter than the duration of that delivery stage — is not anticipated, and at that stage the plant dispatches as an ordinary thermal. Plants without the anticipation flag use the standard thermal model from the preceding subsections.
Commitment ring
Section titled “Commitment ring”Every commitment the plant has decided but not yet delivered is state: the plant holds it in its commitment ring, carried through the Bellman recursion alongside hydro storage and inflow lags. A commitment keeps one slot of the ring from its decision stage to its delivery stage ; the slots and the ring depth (the lead itself under a stage-count lead) are defined in State Augmentation — Hold Ring. Anticipated thermals are the only non-hydro elements with state variables in the SDDP formulation.
The figure follows one delivery through the ring under a stage-count lead. The commitment decided at stage is deposited into the ring slot of its delivery stage , carried unchanged at stages , and delivered at stage , where the plant’s generation must match it. A delivery decided before the study seeds its slot at the first stage instead (the dashed path), and is then carried and delivered in the same way. A physical lead changes which stage decides each delivery, not how the ring holds it.
Decision and delivery
Section titled “Decision and delivery”Each stage carries a commitment column for the delivery it decides, fixed at zero when it decides none. Its bounds are the plant’s generation limits at the delivery stage , not at the decision stage, and it is zero when the plant is out of service at stage , so a commitment is never placed for a delivery the plant cannot honour. At the delivery stage, the energy of the plant’s per-block generation equals the committed rate times the stage hours (State Augmentation — Ring Rows). A physical lead coarse enough that one decision stage would decide more than one delivery is rejected when the study is set up, and a lead longer than the whole study horizon is accepted only when it reaches a declared post-study stage.
Deliveries past the horizon
Section titled “Deliveries past the horizon”A delivery past the horizon can be decided in the study only when the case declares a post-study calendar that reaches it. Its commitment is then bounded by the capability that calendar declares for the delivery stage, priced on its decision column (see the cost subsection below), carried in its slot to the terminal stage, and valued there by the terminal boundary — at zero, with a setup warning, when no boundary is loaded. See Post-Study Boundary & Chained Studies for the boundary formulation.
Commitments decided before the study
Section titled “Commitments decided before the study”Every delivery the plant decided before the study is declared with its committed rate, a zero rate included. The in-study ones seed their slots at the first stage, each matched to its delivery stage by date, and are then carried and delivered like any other commitment. Those past the horizon are fixed commitments: they hold no ring slot and are priced only through the terminal boundary (see Post-Study Boundary & Chained Studies). The declaration shape lives in the Configure tab of Equipment-Specific Formulations.
Commitment cost
Section titled “Commitment cost”A commitment is charged at its decision stage and discounted from its delivery stage . Its commitment column is priced at the plant’s unit cost in $/MWh over the hours of the delivery stage (a post-study stage’s declared cost and duration past the horizon) and discounted from the delivery stage back to the decision stage (Discount Rate Formulation §5), so that the commitment cost reaches stage 1 discounted exactly once. The plant’s per-block generation carries no cost at a stage where it delivers a commitment, so the same energy is priced once (State Augmentation — Objective contributions).
Cut machinery
Section titled “Cut machinery”Each ring slot is a state coordinate with its own cut coefficient, through which the marginal value of a commitment reaches its decision directly, whatever the lead (State Augmentation — Ring-Slot Cut Coefficient).
5. Hydro Plants
Section titled “5. Hydro Plants”Hydro plants are the central elements of the SDDP formulation because:
- Reservoir storage creates temporal coupling (water saved today is available tomorrow)
- Inflows are stochastic (uncertain future rainfall/snowmelt)
- The water value (opportunity cost of using water now vs. saving it) emerges from the optimization
Physical Meaning
Section titled “Physical Meaning”A hydro plant converts the potential energy of stored water into electricity. Each plant has a reservoir (storage), turbines (conversion), and spillways (excess water release). Hydro plants are typically arranged in cascades where upstream releases become downstream inflows.
Unit Groups and Bus-Partitioned Cells
Section titled “Unit Groups and Bus-Partitioned Cells”A hydro plant’s turbines are organized into one or more unit groups, each declaring its own bus connection and its own turbined-flow and generation bounds. Groups sharing a bus form one (hydro, bus) cell; a plant is partitioned into as many cells as it has distinct group buses, and every plant declares at least one group. Storage, spillage, diversion, and inflow remain single reservoir-level quantities tracked once per plant regardless of cell count — only turbined flow and generation are tracked per cell, and each cell injects its generation at its own bus rather than at a single plant-level bus.
A plant whose groups all share one bus has exactly one cell and reduces to the single-bus model used throughout the rest of this chapter. A plant whose groups span several buses has one turbined-flow variable and one generation variable per cell instead of per plant; see LP Formulation §3–§4 for how a cell’s generation enters the bus load balance and a plant’s cells sum into its water balance, and LP Formulation §6, §8 for how a cell’s bounds compose from its member groups.
Operating Status
Section titled “Operating Status”Novomodelo names two hydro plant subsets by their lifecycle phase at a stage; a PreFilling hydro belongs to neither:
| Subset | Symbol | Description |
|---|---|---|
| Operating | Plants that can generate electricity; subject to generation constraints | |
| Filling | New plants under commissioning, filling dead volume; no generation |
Most plants are in . Filling hydros have per-stage target-storage floors instead of generation constraints. Some plants have negligible storage capacity (run-of-river) and must pass all inflows through turbines and spillways within the same stage. At each stage a hydro is PreFilling, Filling or Operating, and LP Formulation — Lifecycle Phases tabulates what each phase fixes.
The figure traces one hydro’s phase across the study, from the first stage (the start oval). A hydro without filling is Operating inside its commissioning window and PreFilling outside it, before its entry stage and from its exit stage on, so a hydro that leaves service stays PreFilling for the rest of the study. A hydro without filling and without a window is Operating at every stage. A filling hydro is PreFilling before its filling start stage, Filling from that stage up to its entry stage, and Operating from its entry stage on. A filling hydro has no exit stage, so it never returns to PreFilling.
Decision Variables
Section titled “Decision Variables”| Variable | Units | Description |
|---|---|---|
| hm³ | End-of-stage reservoir storage (state variable) | |
| m³/s | AR lag for inflow model (state variable, see note below) | |
| m³/s | Turbined flow at cell (§ Unit Groups above), block ; the plant total is what enters the water balance | |
| m³/s | Spillage (released without generation), block | |
| m³/s | Diversion flow (bypassed to separate channel), block | |
| / | m³/s | Signed net evaporation for a plant with an evaporation model, outside PreFilling: a bounded column tied to storage by its evaporation row, one stage-level on a parallel stage and one per block on a chronological stage |
| MW | Hydro generation at cell , block ; injects at bus (§ Unit Groups above) | |
| m³/s | Total outflow: (downstream channel flow) |
State variables ( and ) link stages through the Bellman recursion. The storage tracks reservoir volume and is a true decision variable within each stage (the optimizer chooses its end-of-stage value). The AR lags carry inflow history for the PAR(p) model: they are state variables in the SDDP sense (passed between stages; whether a cut carries them is set by the cut-state projection), but are fixed at the beginning of each stage to the realized inflow values — they are not free for the optimizer to choose. All other variables are control variables determined within each stage.
Connections to Other Elements
Section titled “Connections to Other Elements”- Bus connection: Each of a plant’s cells connects to its own bus for energy delivery; a single-cell plant connects to exactly one bus (§ Unit Groups above)
- Cascade topology: Upstream plants’ turbined and spilled flow (, with the plant’s total turbined flow summed over its cells) becomes the downstream plant’s inflow, within the release stage or, on a declared travel-time arc, partly in later stages (see Cascade Travel Time below)
- Diversion targets: Some plants can divert water to a declared target plant, bounded by ; a plant’s diverted flow reaches only its diversion target and is never part of its release to the plant downstream
- Pumping stations: May receive pumped water (increasing storage) or supply water to pumps (decreasing storage)
The figure draws the water paths that meet at one plant. The incremental inflow enters the reservoir. The upstream plant’s release arrives within the release stage for the share ; the rest enters the in-transit bucket and reaches the reservoir in later stages as it matures (the dashed edge). The bucket exists only on a main cascade arc with a nonzero travel time; on any other arc the share is and the whole release arrives within the release stage. This plant releases its own to the downstream plant and diverts to its diversion target. A pumping station moves from its source reservoir to its destination; the figure draws one pumping from the downstream plant into this reservoir. This plant also receives the diversion of any plant that targets it and supplies any station that pumps from it; these are the same edges seen from the other plant. Evaporation and withdrawal leave the modeled system, each signed, so a negative value adds water. Cascade Travel Time defines the share and the bucket, and LP Formulation §4 writes the balance row that sums these paths.
Key Parameters
Section titled “Key Parameters”| Parameter | Units | Description |
|---|---|---|
| , | hm³ | Storage bounds |
| , | m³/s | Turbined flow bounds (machine limits), composed per cell from its member unit groups’ declared bounds — see LP Formulation §8 |
| , | m³/s | Outflow bounds (environmental flow, flood control) |
| , | MW | Generation bounds (user-defined per unit group, not derived from flow), composed per cell the same way — see LP Formulation §6 |
| m³/s | Maximum diversion flow | |
| MW/(m³/s) | Productivity (constant model) | |
| FPHA hyperplanes | — | The fitted plane set of the FPHA production model (Hydro Production Function Models) |
| m³/s | Incremental inflow (stochastic, from PAR model) | |
| m³/s | Signed water-withdrawal target of the stage (negative = inter-basin return), relaxed by the stage-level slacks , | |
| , | hm³, m³/s | Incoming state (from previous stage) |
Water Balance Phenomena
Section titled “Water Balance Phenomena”The reservoir dynamics account for all water flows in and out of the plant:
| Term | Direction | Description |
|---|---|---|
| Initial | Incoming storage from previous stage | |
| Inflow | Incremental inflow (lateral catchment, stochastic) | |
| Inflow | Turbined and spilled release of the upstream plants; the share (defined in Cascade Travel Time below) arrives in the release stage ( without a travel time) | |
| In-transit arrival | Inflow | Upstream release maturing at this stage after its travel time |
| Inflow | Diverted water received from other plants | |
| Inflow | Pumped water received from pumping stations | |
| Outflow | Turbined and spilled flow, released to the downstream plant | |
| Outflow | Diverted flow, sent to the diversion target | |
| Outflow | Evaporation (reservoir surface loss; can be negative for net precipitation; stage-level on a parallel stage, per block on a chronological stage) | |
| Outflow | Water withdrawal (stage-level target, relaxed by , ) | |
| Outflow | Pumped water extracted by pumping stations |
Every row except the incoming storage and the in-transit arrival, both already volumes, is a flow rate: the balance converts it to volume over the stage or block duration and adds or subtracts it as its Direction column states, pumping included. The canonical row with every term is LP Formulation §4.
Cascade Travel Time
Section titled “Cascade Travel Time”In a cascade, an upstream plant’s outflow () becomes a downstream plant’s inflow. By default this transfer is instantaneous — water released this stage reaches the downstream reservoir within the same stage. When the reach between two plants is long enough that travel is not negligible, a plant may declare a water travel time on its main cascade arc: a release made during stage delivers the share to the downstream reservoir within the stage, with the travel time and the stage duration, both in hours, and the rest reaches it in later stages.
Novomodelo carries the water in transit on such an arc as additional in-transit state through the Bellman recursion, discretized into maturity lags — one aggregated in-transit bucket per receiving plant per lag. The bucket maturing at a given stage enters the receiving plant’s water balance as a delayed inflow; the remaining in-transit volume is carried forward to later stages. Under the chronological-blocks formulation the delayed arrival is spread across the arrival stage’s blocks by a fixed density; under parallel blocks it is a single stage-level inflow. Because this is a genuine state augmentation — its in-transit buckets join the state vector and every cut — it is formulated in State Augmentation §6. Confluent arcs feeding one plant are summed into that plant’s single in-transit block.
Scope. Travel time applies to the main cascade arc only — the arc from a plant to its downstream plant. Diversion and pumping transfers are instantaneous. A travel time that is absent or zero is treated as an instantaneous transfer, adding no state.
Downstream commissioning window. A release made at a stage before the downstream plant’s commissioning entry stage — while it is PreFilling or still filling — is rejected at load. A release made while the downstream plant is in service whose arrival reaches the plant’s exit stage is accepted, and the water maturing from the exit stage on passes to the first downstream plant that is not PreFilling, leaving the modeled system only when there is none (State Augmentation).
Horizon limitation. Without a loaded terminal boundary, in-transit water that would mature after the last stage is dropped; with one, it is carried to the terminal stage and priced there (State Augmentation — Horizon limitation, Post-Study Boundary & Chained Studies).
Production Function (Water to Power)
Section titled “Production Function (Water to Power)”Novomodelo supports three production-model names for converting turbined flow to electrical generation:
-
Constant Productivity: (per cell ) — simple linear relationship with fixed [MW/(m³/s)], suitable for plants with stable head.
-
Linearized Head (reserved alias): A reserved model name that resolves to constant productivity in every phase — training and simulation alike. No distinct head-dependent model is applied; requesting it yields the constant-productivity model above. See Hydro Production Function Models §3.
-
FPHA (approximate hydroelectric production function): Piecewise-linear approximation via hyperplanes that captures head variation with storage level and accounts for tailrace effects from spillage, fitted once per plant. Each cell’s generation is bounded above by every plane of the plant’s fitted set, evaluated at the cell’s turbined flow, the plant’s spillage and the average storage (of the stage, or of each block on a chronological stage), with the plane’s flow-independent terms apportioned by the cell’s share of the plant’s declared turbine capacity — see Hydro Production Function Models.
The production model can vary by stage or season per hydro.
Operational Constraints (Soft)
Section titled “Operational Constraints (Soft)”Several hydro constraints are enforced as soft constraints with slack variables and penalties:
| Constraint | Meaning | Slack Variable |
|---|---|---|
| (filling hydro, from its entry stage) | Minimum storage once filled | |
| (per cell) | Minimum turbined flow (equipment limits) | |
| Minimum outflow (environmental flow) | ||
| Maximum outflow (flood control) | ||
| (per cell) | Minimum generation (grid services) | |
| feasible | Evaporation within physical limits | (stage-level on a parallel stage, per block on a chronological stage) |
| realized withdrawal meets | Water withdrawal commitment | , (stage-level) |
| (filling floor) | Per-stage filling target during commissioning |
Soft constraints allow the optimizer to violate bounds when physically necessary (e.g., drought conditions preventing minimum outflow), with high penalty costs signaling undesirable operation. Maximum storage () is a hard physical limit — excess water is handled by spillage, not a slack variable. The dead volume is a hard bound too, except for a filling hydro once it operates and a plant that is not in service (see LP Formulation §8). For the penalty priority ordering and cost magnitudes, see Penalty System. For the complete hydro constraint formulations, see LP Formulation.
Not-Yet-Commissioned Hydros (PreFilling)
Section titled “Not-Yet-Commissioned Hydros (PreFilling)”A hydro is PreFilling whenever it does not yet exist in the dispatch — a filling hydro before its filling start stage, or a non-filling hydro at any stage outside its commissioning window (before its entry stage, or from its exit stage onward). Unlike the other entity types, this is not a bare column zero-pin: because the physical site is absent, the plant is reformulated so the river flows past it. In this state,
- Turbine, spillage, and diversion are pinned to zero () — a dam that does not yet exist can neither generate nor spill.
- Storage is decoupled by a frozen identity : the reservoir volume is held constant, injecting no phantom storage and trapping no water.
- Natural inflow is passed through to the first downstream plant that is not PreFilling (or leaves the modeled system if none), so incremental inflow, upstream releases, the flows diverted into the plant and the in-transit water maturing into it reach the cascade below without being lost at the un-built site; the plant’s withdrawal target moves with them to that plant.
The defining contrast with the filling phase below is spillage: it is frozen to zero while PreFilling (there is no reservoir to shed from), and becomes a free decision once filling begins. LP Formulation — Lifecycle Phases gives the LP treatment of every phase.
Dead-Volume Filling
Section titled “Dead-Volume Filling”Novomodelo models the commissioning of new hydro plants with a filling period (from the plant’s filling start stage up to, not including, its entry stage) during which the reservoir accumulates water to reach the dead volume (). During this period:
- The hydro has no generation: , (hard constraint)
- Natural inflow flows freely through the ordinary water balance — there is no retention or impound cap diverting inflow to storage
- Storage is allowed below (the operating min-storage slack is absent)
- Outflow is limited to spillage (turbines not operational), with the minimum-outflow slack if environmental flow cannot be met. Spillage is a free decision during filling — a real impounding reservoir can shed inflow it cannot yet hold — in contrast to the PreFilling state, where spillage is frozen to zero
- A per-stage filling floor requires the reservoir to stay on a minimum-accumulation schedule set by its minimum filling rate. The floor reaches the dead volume exactly at the last filling stage; Novomodelo expects its slack to be priced below deficit (a fill schedule is not defended as hard as load serving)
When the plant enters service at its entry stage, its dead volume returns as a soft floor with slack . For the per-stage floor trajectory and the penalty ordering, see Penalty System.
Role in Objective Function
Section titled “Role in Objective Function”Each hydro contributes the regularization costs of its spillage, turbined flow and diversion, each weighted by its block duration, and the penalties of its slacks (LP Formulation §2).
- Spillage cost: Small regularization that makes storing water preferable to spilling it when the solver is otherwise indifferent
- Turbined cost: Small regularization on the turbined flow of every hydro; above the spillage cost, it makes spilling preferable to turbining water that produces no value (Penalty System — Category 3).
- Diversion cost: Small regularization, typically higher than spillage (water leaves main cascade)
- Slack penalties: High costs for constraint violations — storage below a filled plant’s dead volume, outflow violations, generation violations, evaporation violations, water withdrawal under- or over-delivery. See Penalty System for the full penalty taxonomy and priority ordering.
- No generation cost: Hydro generation has zero marginal fuel cost — its “cost” is the opportunity cost of depleting storage, captured through the value function
LP Constraint Preview
Section titled “LP Constraint Preview”Each hydro’s water balance carries its storage from the incoming to the outgoing value through the inflows and outflows above (LP Formulation §4). Each hydro’s inflow lags are pinned to their incoming values (State Augmentation §4). The generation constraint of each cell follows the plant’s production model (Hydro Production Function Models).
6. Non-Controllable Generation Sources
Section titled “6. Non-Controllable Generation Sources”Physical Meaning
Section titled “Physical Meaning”A non-controllable source represents intermittent generation (wind farms, solar plants, small run-of-river hydros, etc.) whose available output depends on external conditions (weather, river flow) rather than dispatch decisions. The solver receives the availability as data, a per-scenario draw of the source’s availability model (Scenario Generation §5.4) when it has one and its stage’s available generation otherwise, and can only curtail generation below that availability — it cannot dispatch upward beyond what nature provides.
Non-controllable sources have near-zero marginal cost. The cost of curtailing available generation is a regularization penalty (Category 3 in the Penalty System), analogous to the spillage cost of a hydro — curtailment discards available “free” energy.
Curtailable vs. Must-Run
Section titled “Curtailable vs. Must-Run”A per-source flag selects between two LP behaviours for the realized availability :
- Curtailable (default): the generation column has bounds , the LP is free to curtail any amount below , and curtailment is regularised by the curtailment cost . This is the standard model for stand-alone wind and solar plants where ramping down is physically feasible and economically justified by the regularisation cost.
- Must-run: the generation column is pinned to the realized availability, , by setting both lower and upper bounds to on every scenario. Nothing is curtailed, and the objective carries the constant curtailment term of Equipment-Specific Formulations §6. This model is required when the scenario pipeline feeds the LP with an aggregate that has already been pre-netted from demand by an upstream model — for example, a non-simulated-generation total (small hydro, distributed thermal, wind, solar, distributed micro-generation) that the upstream model already subtracted from the gross demand series. Allowing the LP to curtail such an aggregate double-discounts the must-run contribution and understates the hydrothermal cost; pinning it as must-run avoids the double count while keeping per-source observability in the simulation outputs.
For a source with stochastic availability, the availability ratio and the block factor multiply the installed capacity exactly as in the curtailable case, ; any other source takes its stage’s available generation in place of , times . Only the lower bound differs.
Operative States
Section titled “Operative States”Non-controllable sources follow the generic commissioning window (§1, Entity Commissioning Windows): outside it the generation column of every block is fixed at zero, must-run or not (LP Formulation — Lifecycle Phases).
Decision Variables
Section titled “Decision Variables”| Variable | Units | Description |
|---|---|---|
| MW | Generation at non-controllable source , block |
Curtailment is not a separate LP decision variable — it is derived as , with the block’s available generation for the current stage and scenario; the LP prices it through a negative cost on (Equipment-Specific Formulations §6). For a must-run source by construction and its term is the constant .
Connections to Other Elements
Section titled “Connections to Other Elements”- Bus connection: Each source connects to exactly one bus, contributing generation to its energy balance
Key Parameters
Section titled “Key Parameters”| Parameter | Units | Description |
|---|---|---|
| MW | Installed capacity; it does not cap the available generation | |
| MW | Available generation of block for the current (stage, scenario), for a source with stochastic availability | |
| — | Block factor of block ( when none is given) | |
| $/MWh | Curtailment cost (regularization penalty) |
Role in Objective Function
Section titled “Role in Objective Function”The curtailment cost is a small regularization term that rewards dispatching the available generation; Equipment-Specific Formulations §6 relates it to the curtailment penalty.
LP Constraint Preview
Section titled “LP Constraint Preview”The generation of each block lies between zero and the available generation for a curtailable source, equals for a must-run source, and is injected at the connected bus (Equipment-Specific Formulations §6).
7. Pumping Stations
Section titled “7. Pumping Stations”Physical Meaning
Section titled “Physical Meaning”A pumping station transfers water from one reservoir (source) to another (destination), consuming electrical power in the process. Pumping enables elevation transfer, basin transfer, and storage arbitrage (pumping during low-demand periods, generating during high-demand).
Decision Variables
Section titled “Decision Variables”| Variable | Units | Description |
|---|---|---|
| m³/s | Pumped water flow at station , block |
Connections to Other Elements
Section titled “Connections to Other Elements”- Source hydro: Water is withdrawn from this reservoir
- Destination hydro: Water is added to this reservoir
- Bus connection: Pumping consumes power at the connected bus
Key Parameters
Section titled “Key Parameters”| Parameter | Units | Description |
|---|---|---|
| m³/s | Minimum pumped flow | |
| m³/s | Maximum pumped flow | |
| MW/(m³/s) | Power consumption rate |
Role in Objective Function
Section titled “Role in Objective Function”Pumping stations have no cost term in the objective function: the energy they consume is load at the connected bus and is priced there (Equipment-Specific Formulations §4).
LP Constraint Preview
Section titled “LP Constraint Preview”The pumped flow of each block lies between its minimum and maximum, leaves the source plant’s water balance and enters the destination’s, and consumes power at the connected bus (Equipment-Specific Formulations §4).
8. Import/Export Contracts
Section titled “8. Import/Export Contracts”Physical Meaning
Section titled “Physical Meaning”Contracts represent agreements to buy (import) or sell (export) electricity with external systems outside the modeled region, providing flexibility during shortages and revenue opportunity for surplus.
Each contract is unidirectional: it is either an import contract or an export contract.
Decision Variables
Section titled “Decision Variables”| Variable | Units | Description |
|---|---|---|
| MW | Dispatched power for contract , block |
Connections to Other Elements
Section titled “Connections to Other Elements”Each contract connects to exactly one bus, contributing to its energy balance:
- Import contracts (): Add to the bus (power entering the system)
- Export contracts (): Remove from the bus (power leaving the system)
Key Parameters
Section titled “Key Parameters”| Parameter | Units | Description |
|---|---|---|
| , | MW | Minimum and maximum contract dispatch limits |
| $/MWh | Contract price: positive for imports (cost), negative for exports (revenue) |
Role in Objective Function
Section titled “Role in Objective Function”An import contract adds its cost to the objective and an export contract subtracts its revenue (Equipment-Specific Formulations §3).
LP Constraint Preview
Section titled “LP Constraint Preview”The dispatched power of each block lies between the contract’s minimum and maximum, a non-zero minimum being a take-or-pay floor (Equipment-Specific Formulations §3).
9. Summary: Physical Elements to LP Components
Section titled “9. Summary: Physical Elements to LP Components”The following table maps each physical system element to its LP representation:
| Physical Element | State Variables | Control Variables | Key Constraints | Objective Role |
|---|---|---|---|---|
| Bus | — | , | Load balance | Deficit penalty (high), Excess penalty (low) |
| Transmission Line | — | , | Capacity bounds | Exchange cost (regularization) |
| Thermal Plant | — | Generation bounds | Fuel cost | |
| Thermal (anticipated) | commitment-ring slots (State Augmentation §5) | , | Ring deposit, carry and delivery rows | Commitment cost at the decision stage, discounted from the delivery stage |
| Hydro Plant | , , in-transit buckets (State Augmentation §6) | , , , | Water balance, Generation function | Spillage, turbined-flow and diversion costs (regularization) |
| Non-Controllable | — | Availability bound | Curtailment penalty (regularization) | |
| Pumping Station | — | Flow bounds (min/max) | None (cost via energy consumption) | |
| Contract | — | Dispatch bounds (min/max) | Import cost or Export revenue |
Key insight: The hydro storage, the inflow lags, the in-transit buckets of the cascade arcs that declare a water travel time and the commitment-ring slots of the anticipated thermals are the four state families that link stages through the Bellman recursion (State Augmentation §1). All other elements contribute control variables that are determined within each stage. This structure enables SDDP’s decomposition: the stage subproblem optimizes all control variables given the incoming state, and Benders cuts approximate the future cost as a function of the outgoing state.
Implementation in Novomodelo
Section titled “Implementation in Novomodelo”The methodology above defines every system element; the tabs below cover how Novomodelo’s software surface configures and reports the network layer — buses and transmission lines — and how the Configure tab sets up the hydro plant registry. The remaining elements (thermals, non-controllable sources, pumping stations, contracts), the hydro files and outputs, and the hydro production-model selection are covered by their own chapters’ Implementation tabs (Equipment-Specific Formulations, Hydro Production Function Models).
Novomodelo’s electrical network is configured through two case-directory files:
system/buses.json (nodes) and system/lines.json (edges). This tab covers
their field-level configuration; the bus’s piecewise deficit cost curve is
priced through the shared penalty cascade. Its segment fields are in
System Entity Files
and its resolution order is on the
Penalty System Configure tab.
system/buses.json — Bus Registry
Section titled “system/buses.json — Bus Registry”Every generator and every load attaches to a bus (§2). A single-bus
(copper-plate) system still requires buses.json — see “Single-Bus vs
Multi-Bus” below.
{ "buses": [ { "id": 0, "name": "SIN", "operational_start_date": "1999-01-01", "deficit_segments": [{ "depth_mw": null, "cost": 1000.0 }] } ]}| Field | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | Unique non-negative bus identifier, referenced by every entity’s bus_id. |
name | string | Yes | Human-readable bus name, used in output files and validation messages. |
operational_start_date | string (ISO-8601 date) | Yes | Calendar date (YYYY-MM-DD) the bus enters the registry’s operational history. Provenance and the canonical (operational_start_date, id) ordering key (see Notation Conventions) — independent of any commissioning window. |
deficit_segments | array | No | Bus-level override of the piecewise deficit cost curve. The segment fields are in System Entity Files and the global default is in penalties.json; the two-tier resolution order is on the Penalty System Configure tab. |
excess_cost has no per-bus field at all: every bus shares the global
excess_cost default from penalties.json, optionally refined per stage —
again documented in the Penalty System chapter, not here.
system/lines.json — Transmission Line Registry
Section titled “system/lines.json — Transmission Line Registry”A single-bus system carries an empty lines array. A multi-bus system
connects buses with one or more line entries:
{ "lines": [ { "id": 0, "name": "North-South Interconnection", "source_bus_id": 0, "target_bus_id": 1, "operational_start_date": "2003-07-01", "entry_stage_id": null, "exit_stage_id": null, "capacity": { "direct_mw": 1000.0, "reverse_mw": 800.0 }, "losses_percent": 2.5, "exchange_cost": 1.0 } ]}| Field | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | Unique non-negative line identifier. |
name | string | Yes | Human-readable line name. |
source_bus_id | integer | Yes | Bus at the source end — defines the direct-flow direction (source → target). Must reference an existing buses.json id. |
target_bus_id | integer | Yes | Bus at the target end — defines the reverse-flow direction (target → source). Must reference an existing buses.json id. |
operational_start_date | string (ISO-8601 date) | Yes | Calendar date (YYYY-MM-DD) the line enters the registry’s operational history. Provenance and the canonical (operational_start_date, id) ordering key (see Notation Conventions) — independent of entry_stage_id/exit_stage_id below, which alone gate commissioning. |
entry_stage_id | integer or null | No | Commissioning window start — see Entity Commissioning Windows in the body above. null means active from stage 0. |
exit_stage_id | integer or null | No | Commissioning window end (exclusive). null means never decommissioned. |
capacity.direct_mw | number | Yes | Hard upper bound on the direct-direction flow variable, MW. |
capacity.reverse_mw | number | Yes | Hard upper bound on the reverse-direction flow variable, MW. |
losses_percent | number | No | Transmission loss as a percentage of transmitted power, used for reporting only. Defaults to 0.0. It does not enter the dispatch LP (load-balance flow coefficients are exactly ); Novomodelo computes losses_mw = (losses_percent/100)·(f⁺+f⁻) post-hoc and writes it under simulation/exchanges/ (see the I·O tab). |
exchange_cost | number or null | No | Entity-level override of the flow regularization cost. Falls back to the global penalties.json default — see the Penalty System Configure tab for the full resolution cascade. |
Stage-varying capacity is supplied via constraints/line_bounds.parquet,
which accepts sparse (line_id, stage_id) rows carrying direct_mw and/or
reverse_mw, optionally narrowed to one block via an optional block_id
column; absent rows fall back to capacity.direct_mw/capacity.reverse_mw
above. Values are absolute MW rather than a multiplier on the base capacity —
a row may set direct_mw = 0.0 to close a line in one direction for one
block, which a strictly-positive multiplicative factor could never express.
Per-stage refinement of exchange_cost is supplied by a separate file — see
the Inputs & Outputs tab.
Single-Bus vs Multi-Bus
Section titled “Single-Bus vs Multi-Bus”A single-bus (copper-plate) system aggregates all generation and load
into one node: no flow limits, no transmission losses, and no locational
price differentiation. lines.json carries an empty array, and every
entity’s bus_id points at the same bus. This is the right starting point
when isolating dispatch economics from network effects, or when the internal
transmission network is not the object of study.
A multi-bus system connects two or more buses with lines.json entries.
Once a line’s capacity binds, each bus resolves its own locational marginal
price (the load-balance dual, body §2 LP Constraint Preview), and dispatch in
one bus cannot freely substitute for a shortfall in another. Extending a
single-bus case to multi-bus is additive: add a bus entry, add a line entry
connecting it to an existing bus, and repoint the relevant entities’
bus_id — no structural change to the rest of the case is required.
Hydro Plants
Section titled “Hydro Plants”The sections below configure the hydro plants of
§5 Hydro Plants. The plant’s generation block and the
production-model selection (system/hydro_production_models.json) are on the
Hydro Production Function Models Configure tab.
system/hydros.json — Hydro Plant Registry
Section titled “system/hydros.json — Hydro Plant Registry”Hydro plants are defined in system/hydros.json. The top-level object has a
single key "hydros" containing an array of plant objects:
{ "hydros": [ { "id": 1, "name": "UHE Tucuruí", "downstream_id": null, "operational_start_date": "1984-11-22", "entry_stage_id": 60, "exit_stage_id": null, "reservoir": { "min_storage_hm3": 50.0, "max_storage_hm3": 45000.0 }, "outflow": { "min_outflow_m3s": 1000.0, "max_outflow_m3s": 100000.0 }, "generation": { "model": "constant_productivity", "min_turbined_m3s": 500.0, "max_turbined_m3s": 22500.0, "min_generation_mw": 0.0, "max_generation_mw": 8370.0 }, "unit_groups": [ { "id": 0, "name": "UG1", "bus_id": 0, "min_turbined_m3s": 500.0, "max_turbined_m3s": 22500.0, "min_generation_mw": 0.0, "max_generation_mw": 8370.0 } ], "tailrace": { "type": "polynomial", "coefficients": [5.0, 0.001] }, "hydraulic_losses": { "type": "factor", "value": 0.03 }, "efficiency": { "type": "constant", "value": 0.93 }, "evaporation": { "coefficients_mm": [ 80.0, 75.0, 70.0, 65.0, 60.0, 55.0, 60.0, 65.0, 70.0, 75.0, 80.0, 85.0 ] }, "diversion": { "downstream_id": 2, "max_flow_m3s": 200.0 }, "filling": { "start_stage_id": 48, "filling_min_rate_m3s": 100.0 }, "penalties": { "spillage_cost": 0.01, "diversion_cost": 0.1, "turbined_cost": 0.05, "storage_violation_below_cost": 10000.0, "filling_target_violation_cost": 6000.0, "turbined_violation_below_cost": 500.0, "outflow_violation_below_cost": 500.0, "outflow_violation_above_cost": 500.0, "generation_violation_below_cost": 1000.0, "evaporation_violation_cost": 5000.0, "water_withdrawal_violation_cost": 1000.0, "inflow_nonnegativity_cost": 1000.0 } } ]}Only id, name, operational_start_date, reservoir,
outflow, generation, and unit_groups are required. All other top-level
keys (tailrace, hydraulic_losses, efficiency, evaporation,
diversion, filling, penalties) are optional and default to off when
absent.
Core Fields
Section titled “Core Fields”| Field | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | Unique non-negative identifier. Must be unique across all hydro plants. Referenced by initial_conditions.json and by other plants via downstream_id. |
name | string | Yes | Human-readable plant name. Used in output files, validation messages, and log output. |
downstream_id | integer or null | No | Identifier of the plant that receives this plant’s outflow. Absent or null means the plant is at the bottom of its cascade — outflow leaves the system. |
operational_start_date | string (ISO-8601 date) | Yes | Calendar date (YYYY-MM-DD) the plant enters the registry’s operational history. Provenance and the canonical (operational_start_date, id) ordering key (see Notation Conventions) — independent of entry_stage_id/exit_stage_id below, which alone gate commissioning. |
entry_stage_id | integer or null | No | Stage index at which the plant enters service (inclusive). null means the plant is available from stage 0. |
exit_stage_id | integer or null | No | Stage index at which the plant is decommissioned. The commissioning window is half-open [entry_stage_id, exit_stage_id): the plant is active through exit_stage_id - 1, and outside the window it is not in service. For a hydro the out-of-service state is PreFilling — turbine, spillage, and diversion pinned to zero, storage frozen, and natural inflow routed past the site (see Hydro Production Function Models — Implementation in Novomodelo and Not-Yet-Commissioned Hydros (PreFilling)) — rather than a bare column zero-pin. null means the plant is never decommissioned. |
Reservoir
Section titled “Reservoir”Storage is tracked in hm³ (cubic hectometres; 1 hm³ = 10⁶ m³).
"reservoir": { "min_storage_hm3": 0.0, "max_storage_hm3": 1000.0}| Field | Type | Description |
|---|---|---|
min_storage_hm3 | number | Physical minimum storage (dead volume). Water below this level cannot reach the turbine intakes. For plants that can empty completely, use 0.0. |
max_storage_hm3 | number | Physical maximum storage. Must be greater than or equal to min_storage_hm3 (equal is allowed — a fixed-storage plant). |
This is the plant’s physical, stage-invariant range: stored-energy outputs and the
useful-range mean productivity (Hydro Production Function Models §5.3)
read it, while constraints/hydro_bounds.parquet storage overrides (for example a
flood-control ceiling) tighten only the per-stage operative bounds of the LP storage
variable.
Outflow Constraints
Section titled “Outflow Constraints”Total outflow equals turbined flow plus spillage.
"outflow": { "min_outflow_m3s": 0.0, "max_outflow_m3s": 50.0}| Field | Type | Description |
|---|---|---|
min_outflow_m3s | number | Minimum total outflow required at all times [m³/s]. Set to the ecological flow requirement or minimum riparian right. Use 0.0 if there is no minimum requirement. |
max_outflow_m3s | number or null | Maximum total outflow [m³/s]. null means no upper bound on outflow. |
When the solver cannot meet the minimum-outflow bound, a violation slack is
added at the cost of outflow_violation_below_cost in the penalties block.
Unit Groups (unit_groups)
Section titled “Unit Groups (unit_groups)”A plant’s generation envelope is split into one or more turbine groups, each
on its own bus. unit_groups is required — every hydro declares at least one
group; an absent, null, or empty array is rejected at load. There is no
top-level hydro.bus_id: a plant’s bus association lives exclusively on its
groups’ bus_id.
"unit_groups": [ { "id": 0, "name": "UG1", "bus_id": 0, "min_turbined_m3s": 500.0, "max_turbined_m3s": 22500.0, "min_generation_mw": 0.0, "max_generation_mw": 8370.0 }]| Field | Type | Description |
|---|---|---|
id | integer | Group identifier, unique within the owning plant (not globally). |
name | string | Human-readable group name. |
bus_id | integer | Bus to which this group’s generation is injected. Must match an id in buses.json. |
min_turbined_m3s | number | Minimum turbined flow for this group [m³/s]. |
max_turbined_m3s | number | Maximum turbined flow for this group [m³/s]. |
min_generation_mw | number | Minimum electrical generation for this group [MW]. |
max_generation_mw | number | Maximum electrical generation for this group [MW]. |
Bus-partitioned dispatch. A plant is partitioned into one cell per
distinct bus_id among its groups: the LP carries one turbine column and one
FPHA-generation column per cell, and each cell injects its generation at that
cell’s bus. A plant whose groups all share one bus collapses to a single
cell — the same LP shape as a plant with no groups declared beyond the
required one.
Each group’s own turbine bounds must be internally consistent
(min_turbined_m3s <= max_turbined_m3s, and likewise for generation), and
group ids are unique within the plant. Across the whole plant, the sum of
every group’s max_turbined_m3s (and, separately, max_generation_mw)
cannot exceed the plant’s own declared maximum from its generation block
— a plant’s own value is the envelope, so groups cannot raise it — and
the sum of every group’s minima must be able to reach the plant’s own
declared minimum.
Stage-varying, optionally per-block overrides of a group’s four bounds are
supplied by constraints/hydro_unit_group_bounds.parquet — see the Hydro Production Function Models Inputs & Outputs tab.
Cascade Topology (downstream_id)
Section titled “Cascade Topology (downstream_id)”The downstream_id field creates a directed chain of hydro plants: water
released from an upstream plant (turbined or spilled) enters the downstream
plant’s reservoir in the same stage. To model a three-plant cascade where
plant 0 flows into plant 1, which flows into plant 2:
{ "id": 0, "downstream_id": 1, ... }{ "id": 1, "downstream_id": 2, ... }{ "id": 2, "downstream_id": null, ... }The downstream graph is validated to be acyclic — no chain of
downstream_id references may return to a plant already in the chain. Plants
with downstream_id: null are tailwater plants; each connected component of
the cascade graph must have exactly one tailwater plant.
Water Travel Time (travel_time_hours)
Section titled “Water Travel Time (travel_time_hours)”The optional travel_time_hours field declares how long a release takes to
travel down the main cascade arc to downstream_id.
{ "id": 0, "downstream_id": 1, "travel_time_hours": 48.0 }| Field | Type | Required | Description |
|---|---|---|---|
travel_time_hours | number or null | No | Travel time on the main cascade arc, in hours. When present, strictly positive, and the plant has a downstream_id, the part of each release that the travel time carries past the end of the release stage reaches the downstream reservoir in later stages; the rest arrives within the stage (see Cascade Travel Time). Absent, null, or 0.0 means an instantaneous transfer. |
When an arc is declared, Novomodelo carries the water in transit as additional
Bellman state (see State Augmentation §6 and
Cascade Travel Time). Travel time applies to the main
cascade arc only — diversion and pumping transfers are always instantaneous.
Declaring an arc requires seeding the pre-study releases already in transit via
initial_conditions.past_defluences, and the downstream plant must have
entered service by the first study stage — see
Hydro Production Function Models — Implementation in Novomodelo.
Advanced Fields
Section titled “Advanced Fields”These fields enable more detailed physical modeling and are all optional.
Tailrace model — the tailrace block models downstream water level as a
function of total outflow; when absent, tailrace elevation is zero. Two
entity-level variants are supported:
"tailrace": { "type": "polynomial", "coefficients": [5.0, 0.001] }coefficients is an ascending-power polynomial: coefficients[0] is the
height at zero outflow (m), coefficients[1] the coefficient for Q¹, and so
on.
"tailrace": { "type": "piecewise", "points": [ { "outflow_m3s": 0.0, "height_m": 3.0 }, { "outflow_m3s": 5000.0, "height_m": 4.5 } ]}Points must be sorted in ascending outflow_m3s order; the solver
interpolates linearly between them. A third, file-level source — the optional
per-plant piecewise-quartic tailrace curves with backwater families (Hydro Production Function Models
§2.3.1) — replaces the entity-level model in the computed-FPHA fit for any plant that has rows in
that file; the equivalent-productivity derivation keeps reading the entity-level model.
Hydraulic losses — the hydraulic_losses block models head loss in the
penstock; absent means lossless.
"hydraulic_losses": { "type": "factor", "value": 0.03 }value is a dimensionless fraction (e.g. 0.03 = 3% of the gross head, the
forebay level minus the tailrace level) for "factor", or a fixed metres
value (value_m) for "constant".
Efficiency model — the efficiency block scales hydraulic power to
electrical power; absent means 100% efficiency. Only "constant" is
supported:
"efficiency": { "type": "constant", "value": 0.93 }Evaporation — the evaporation block models net water flux at the
reservoir surface; absent means no evaporation. Coefficients are signed:
positive values are net evaporative loss, negative values are net rainfall
input.
"evaporation": { "coefficients_mm": [ 80.0, 75.0, 70.0, 65.0, 60.0, 55.0, 60.0, 65.0, 70.0, 75.0, 80.0, 85.0 ], "reference_volumes_hm3": [ 15000, 12000, 10000, 8000, 6000, 5000, 5500, 7000, 9000, 11000, 13000, 14500 ]}| Field | Type | Required | Description |
|---|---|---|---|
coefficients_mm | array | Yes | Exactly 12 values, one per calendar month (index 0 = January). mm/month; may be negative. |
reference_volumes_hm3 | array | No | Exactly 12 linearization reference volumes [hm³], one per month, within [min_storage_hm3, max_storage_hm3]. Absent defaults to the storage range midpoint. |
A hydro that declares coefficients_mm but has no usable area-volume curve to
convert it into a flux — see
Hydro Production Function Models — Implementation in Novomodelo for exactly what “no usable
curve” means and what Novomodelo does about it.
Diversion channel — the diversion block models a diversion that routes
flow directly to a downstream plant’s reservoir, bypassing turbines and
spillways; absent means no diversion.
"diversion": { "downstream_id": 2, "max_flow_m3s": 200.0 }Filling configuration — the filling block enables a commissioning fill
period, during which the reservoir accumulates water toward min_storage_hm3
before the plant can generate.
"filling": { "start_stage_id": 48, "filling_min_rate_m3s": 100.0}| Field | Required | Description |
|---|---|---|
start_stage_id | Yes | Stage index at which filling begins (inclusive); filling runs through the stage before entry_stage_id. |
filling_min_rate_m3s | No | Per-stage minimum accumulation rate [m³/s], defaulting to 0.0 when omitted: anchors a per-stage minimum end-of-stage storage target that ramps to min_storage_hm3 by the last filling stage. It is not an applied inflow and not a cap — natural inflow and upstream cascade releases still flow through the ordinary water balance; there is no retention or impound mechanism that diverts inflow into storage. |
The target trajectory and its soft-floor penalty are covered in Penalty System §6; the load-time filling-sufficiency check is listed in that page’s Configure tab.
Penalties — the penalties block overrides the global defaults from
penalties.json for one plant; when absent, the plant uses the global
values.
"penalties": { "spillage_cost": 0.01, "diversion_cost": 0.1, "turbined_cost": 0.05, "storage_violation_below_cost": 10000.0, "filling_target_violation_cost": 6000.0, "turbined_violation_below_cost": 500.0, "outflow_violation_below_cost": 500.0, "outflow_violation_above_cost": 500.0, "generation_violation_below_cost": 1000.0, "evaporation_violation_cost": 5000.0, "water_withdrawal_violation_cost": 1000.0, "inflow_nonnegativity_cost": 1000.0}When present, every field is optional and independently falls back to the
global default from penalties.json; the block accepts exactly these twelve
keys and rejects any unknown field. The directional evaporation and withdrawal
costs have no key in this block; a plant takes each
from the block’s matching symmetric cost when the block sets it, else from penalties.json
(Penalty System — Directional evaporation and
withdrawal costs).
For the full field list, units, and the priority ordering across penalty
categories, see Penalty System.
Three-tier resolution cascade — penalty values are resolved from the most specific to the most general source:
- Stage-level override (stage-specific penalty files, when present)
- Entity-level override (the
penaltiesblock inside the plant’s JSON object) - Global default (the
hydrosection ofpenalties.json, which must always be present and complete)
Stage-varying operational bounds (constraints/hydro_bounds.parquet)
Section titled “Stage-varying operational bounds (constraints/hydro_bounds.parquet)”Beyond the entity-level diversion and spillage fields above,
constraints/hydro_bounds.parquet carries optional, sparse stage-varying
bound overrides for a hydro plant, optionally narrowed to one block via an
optional block_id column (null applies at the stage level). Three of its
columns set a diversion floor and the spillage band:
min_diversion_m3s— a minimum diversion-flow floor (m³/s). This is a floor that requires a declareddiversionchannel on the hydro (see Diversion channel, above): with no channel declared, the diversion column is pinned[0, 0], so a positive floor is infeasible and is rejected at load.min_spillage_m3s,max_spillage_m3s— the spillage band (m³/s);min_spillage_m3smust be<= max_spillage_m3s.
All three are non-negative — a negative value is rejected at load, as is a
spillage band with min_spillage_m3s > max_spillage_m3s. An absent row
leaves that hydro’s diversion floor and spillage band unset for the
stage/block it would have covered (no floor; spillage bounded only by the
plant’s other outflow constraints). See
Constraint Files — constraints/hydro_bounds.parquet
for the complete column table, including the turbined, storage, outflow,
generation, diversion-maximum, filling and withdrawal override columns this
file also carries.
Load-Time Validation Rules
Section titled “Load-Time Validation Rules”| Rule | Error Class | Description |
|---|---|---|
| Bus reference integrity | Reference error | Every unit_groups[].bus_id must match an id in buses.json. |
| Downstream reference integrity | Reference error | Every non-null downstream_id must match an id in hydros.json. |
| Unit group bound ordering | Physical feasibility | Each group’s own min_turbined_m3s must be <= max_turbined_m3s, and min_generation_mw must be <= max_generation_mw. |
| Unit group envelope | Physical feasibility | The sum of every group’s max_turbined_m3s (and, separately, max_generation_mw) must not exceed the plant’s own declared maximum; the sum of every group’s minima must be able to reach the plant’s own declared minimum. |
| Cascade acyclicity | Topology error | The directed graph of downstream_id links must be acyclic. |
| Storage bounds ordering | Physical feasibility | min_storage_hm3 must be less than or equal to max_storage_hm3 (equal is allowed — a fixed-storage plant). |
| Outflow bounds ordering | Physical feasibility | When max_outflow_m3s is present, it must be >= min_outflow_m3s. |
| Turbine bounds ordering | Physical feasibility | min_turbined_m3s must be <= max_turbined_m3s. |
| Generation bounds consistency | Physical feasibility | min_generation_mw must be <= max_generation_mw. |
| Initial conditions exclusivity | Schema error | A hydro appears at most once in storage, at most once in filling_storage, and never in both, in initial_conditions.json; a hydro with no entry is not rejected at load. |
| Evaporation array length | Schema error | coefficients_mm must have exactly 12 values; reference_volumes_hm3, when present, must also have exactly 12 values within [min_storage_hm3, max_storage_hm3]. |
This is a topic-scoped index of the files the network layer (System Element Modeling Overview §2–§3) touches — it names each file and its role, it does not repeat their field-by-field schemas. The exhaustive, field-by-field case-directory and output reference is owned by the Reference corpus (Case Format and Output Format pages).
Inputs
Section titled “Inputs”| File | Role |
|---|---|
system/buses.json | Bus (node) registry — id, name, and the deficit_segments override covered in the Configure tab. Required in every case. |
system/lines.json | Transmission line (edge) registry — id, name, endpoints, capacity, losses_percent, and the exchange_cost override covered in the Configure tab. Empty array for a single-bus case. |
constraints/line_bounds.parquet | Sparse per-(line_id, stage_id) overrides of direct_mw/reverse_mw, optionally narrowed to one block via an optional block_id column (see Configure tab) — planned outages, seasonal de-rating, or time-of-day transfer limits, expressed as absolute MW rather than a multiplier on capacity.direct_mw/capacity.reverse_mw. Absent rows fall back to the base entity values. |
The stage-varying penalty overrides that touch these same two files —
excess_cost on buses and exchange_cost on lines — are separate sparse
parquet inputs owned by the penalty system; see the
Penalty System Inputs & Outputs tab
for constraints/penalty_overrides_bus.parquet and
constraints/penalty_overrides_line.parquet. This chapter does not repeat
that index.
For the complete field-by-field schema of every file above, see the Case Format reference page in the Reference corpus.
Outputs
Section titled “Outputs”| File / column group | Role |
|---|---|
simulation/buses/ | Per-(stage, block, bus) load balance results: load_mw, deficit_mw, excess_mw (and their _mwh energy equivalents), and spot_price — the load-balance dual. |
simulation/exchanges/ | Per-(stage, block, line) flow results: direct_flow_mw, reverse_flow_mw, net_flow_mw (and _mwh), transmission losses_mw/losses_mwh, and the monetary exchange_cost attributed to that line’s flow. |
A generic constraint can address this same net line flow by bus pair —
line_exchange(source_bus=X, target_bus=Y) folds the orientation sign into
the term — see Generic Constraints for
the full addressing form.
For the complete output schema (columns, types, file layout), see the Output Format reference page in the Reference corpus.
Cross-References
Section titled “Cross-References”- Notation Conventions — variable naming conventions and index sets used throughout
- LP Formulation — fully assembled LP constraints combining all elements
- State Augmentation — the state the elements carry between stages: storage, inflow lags, in-transit buckets and commitment-ring slots
- Equipment-Specific Formulations — detailed per-equipment constraint derivations
- Hydro Production Function Models — FPHA and linearized head alternatives for the hydro production function
- Penalty System — penalty costs, priority ordering, and the full penalty taxonomy