System Element Modeling Overview
Purpose
Section titled “Purpose”This spec describes the physical components of a hydrothermal power system as modeled by Cobre: what each element represents, its decision variables, how it connects to other elements, and its role in the optimization objective. It serves as the conceptual foundation between the SDDP algorithm description and the full LP formulation — the reader should understand what is being optimized before seeing how the constraints are assembled.
Reading order: SDDP algorithm → this spec → LP formulation → equipment formulations
For variable naming conventions and index sets, see notation conventions.
Variable Units Convention
Section titled “Variable Units Convention”All decision variables in Cobre 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 water balance conversion factor, but not in the variable bounds or constraint matrix.
This is a deliberate design decision with consequences across the formulation:
| Aspect | Consequence |
|---|---|
| Objective function | All cost terms are scaled by : the coefficient for a $100/MWh thermal is |
| Variable bounds | Block-invariant — a 500 MW capacity bound is the same regardless of 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 |
Why not absolute units (MWh, hm³ per block)? The alternative — internalizing into the variables — was evaluated and rejected for three reasons:
-
FPHA incompatibility: The FPHA hyperplane relates instantaneous rates to storage level. Converting to absolute units does not eliminate from the FPHA constant term, and introduces a scaling factor on flow coefficients.
-
Constraint matrix quality: With rate units, the constraint matrix (excluding the objective row) spans ~3 orders of magnitude (–, –, conversion factors ~–). Absolute units inflate this to ~5 orders via the 278 factor in FPHA rows. A tighter constraint matrix improves simplex pivot stability.
-
Block-varying bounds: Absolute units make every variable bound depend on ( instead of ), complicating LP construction and making the LP structure vary with block configuration.
The objective row does carry large coefficients — up to for deep deficit in monthly problems. Modern LP solvers handle objective scaling effectively through internal prescaling, and this is where the scaling challenge is most tractable.
1. System Architecture Overview
Section titled “1. System Architecture Overview”A hydrothermal power system in Cobre 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 stage indices, entry_stage_id and exit_stage_id. The window is half-open: the entity is active at stage when
so the entry stage is inclusive and the exit stage is exclusive — the entity is gone from its exit stage onward. A null entry_stage_id means “active from the first stage”; a null exit_stage_id means “never decommissioned”. The default for an entity that sets neither is to be 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 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 two fields.
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 falls inside the study horizon, an additional horizon predicate beyond the entry/exit window.
Operational Start Date
Section titled “Operational Start Date”Independent of the commissioning window, every entity also carries a
required operational_start_date — an ISO-8601 calendar date. This field is
provenance and the canonical ordering key only: it fixes the entity’s
position in the canonical (operational_start_date, id) order (see
Notation Conventions and
Determinism Guarantees), which every state
block, the LP column layout, and the output column order follow. It does
not compute or gate commissioning. Presence in the dispatch is decided
solely by the entry_stage_id/exit_stage_id window above: the two fields
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”- Deficit cost: Very high penalty ($1,000–10,000/MWh) representing 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 enforces:
For the assembled constraint, see LP formulation.
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 and transmission losses. Lines are bidirectional.
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 via exchange factors | |
| MW | Capacity limit (reverse direction); may vary by stage via exchange factors | |
| — | Transmission efficiency: | |
| $/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.
LP Constraint Preview
Section titled “LP Constraint Preview”Capacity bounds:
Load balance contribution at source bus:
For detailed constraints, see equipment formulations.
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). Thermal plants have fuel costs modeled with piecewise-linear cost curves.
Decision Variables
Section titled “Decision Variables”| Variable | Units | Description |
|---|---|---|
| MW | Generation at thermal plant , block , cost segment |
The total generation is .
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 for segment (fuel + O&M) | |
| MW | Segment capacity |
Role in Objective Function
Section titled “Role in Objective Function”Thermal costs represent actual operating expenses ($50–500/MWh depending on fuel type) and constitute the primary controllable cost in the objective function.
LP Constraint Preview
Section titled “LP Constraint Preview”Segment bounds (cost curve linearization): for all .
Total generation bounds:
For detailed constraints, see equipment formulations.
Anticipated Thermal Plants
Section titled “Anticipated Thermal Plants”A thermal plant may be flagged as anticipated by attaching a per-plant lead . The physical motivation is fuel-ordering lead time: LNG (originally Gás Natural Liquefeito) terminals, long-haul coal contracts and similar arrangements require the committed dispatch quantity to be locked stages before the energy is physically delivered. Anticipated thermals therefore split the per-stage thermal decision into two coupled variables — the commitment, made at the decision stage , and the delivered generation, which is forced to match the matured commitment at the delivery stage .
The lead resolves to an integer plant-specific parameter , supplied in one of two mutually exclusive forms: a stage count (lead_stages, calendar-free) or a physical duration (lead_time_hours, resolved against the stage calendar by end-anchoring the lead on the cumulative stage-hour boundaries). A plant with commits one stage ahead; a plant with commits three stages ahead. A physical lead shorter than the decision stage’s own duration resolves to , and the plant then dispatches as an ordinary thermal. Plants without the anticipation flag use the standard thermal model from the preceding subsections.
State variables and ring-buffer layout
Section titled “State variables and ring-buffer layout”Each anticipated plant carries a ring-buffer pipeline of pending commitments through the Bellman recursion alongside hydro storage and inflow lags. Anticipated thermals are the only non-hydro elements with state variables in the SDDP formulation.
| State variable | Slot | Meaning at the start of stage |
|---|---|---|
| 0 | Commitment maturing this stage — sets the delivered generation at | |
| 1 | Commitment placed at , scheduled to deliver at | |
| … | ||
| Most-recent commitment, written at , scheduled to deliver at |
The state vector reserves slots per plant for layout uniformity across stages; slots beyond are padded to zero by an LP equality and carry no information.
Decision variable and fishing constraint
Section titled “Decision variable and fishing constraint”At each stage the plant exposes a commitment column on the LP. Its bounds replicate the generation bounds of the delivery stage :
The horizon predicate guarantees the commitment is only opened when there is a delivery stage inside the study horizon; commitments whose delivery would fall outside are pinned to zero.
The commitment is also commissioning-gated at its delivery stage: the delivery-stage generation bounds collapse to whenever the plant is not in service at , so a commitment can never be placed for a delivery stage the plant cannot honour — and a plant whose cap varies across stages cannot be over-committed to a value its delivery stage would reject. Two lead configurations are refused at load: a lead exceeding the study horizon (no in-horizon delivery stage exists), and a physical lead_time_hours coarse enough that one decision stage would anchor more than one delivery stage.
The fishing constraint binds the per-block generation of plant to the matured commitment in slot 0 at every stage :
where is the duration of block and is the total stage hours. The fishing row is active at every stage, including the pre-horizon stages where slot 0 is fed by the seeded past_anticipated_commitments (see below) rather than by an LP-decided .
Column bounds pin each slot to its incoming value, and a separate decoupled state-out column writes the LP commitment into the post-shift slot for the next stage. The decoupling prevents a write into slot 0 from overlapping a read in the same stage, which is what makes the fishing-at-every-stage predicate safe even at .
Pre-horizon seed
Section titled “Pre-horizon seed”Because anticipated dispatch carries state across stages, plant must be primed with pre-horizon commitments — the values that were committed at the negative stages and are scheduled to mature at stages . These live in initial_conditions.past_anticipated_commitments[i].values_mw, an array of exactly entries with values_mw[k] carrying the commitment that delivers at study stage . The values must satisfy the plant’s generation bounds; both the bounds-check and the array-length check are enforced by the semantic validator. An empty list is the default for studies with no anticipated plants.
The seed enters the LP via the slot-0 fishing constraint at stages : at the LP reads values_mw[0] out of slot 0; the ring-buffer shift then moves values_mw[1] into slot 0 for stage ; and so on. From stage onward, slot 0 carries the LP-decided commitment .
Cost discounted to the delivery stage
Section titled “Cost discounted to the delivery stage”Anticipation costs are charged at the decision stage but discounted to the delivery stage in the same way a real-world option is priced. The objective coefficient on is
where is the unit cost in $/MWh, is the total hours at the delivery stage, and is the cumulative NPV discount factor at the delivery stage. The per-block thermal column cost is zeroed at delivery stages for anticipated plants so the same energy is not double-priced once via the commitment and once via the per-block dispatch.
Cut machinery
Section titled “Cut machinery”Benders cuts propagate the marginal value of the matured commitment back through the ring buffer. The reduced cost of the pinned slot-0 column at stage is the partial and is non-zero only when the fishing constraint has bound the LP there. The cut-row builder remaps this coefficient to the predecessor’s commitment column (for ) or to the predecessor’s outgoing-state slot one step deeper into the ring buffer (for ), so the subgradient ultimately lands on the original decision regardless of how many stages have elapsed between commitment and delivery.
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.
Operating Status
Section titled “Operating Status”Cobre distinguishes two hydro plant subsets based on their operational state:
| 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.
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 (through generators), block | |
| m³/s | Spillage (released without generation), block | |
| m³/s | Diversion flow (bypassed to separate channel), block | |
| m³/s | Evaporation (see note below), block | |
| m³/s | Water withdrawal (see note below), block | |
| MW | Hydro generation, block | |
| 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 and subject to Benders cuts), 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 hydro plant connects to one bus for energy delivery
- Cascade topology: Upstream plants’ outflows () become downstream plants’ inflows, either instantaneously or, on a declared main-cascade arc, delayed by a water travel time (see Cascade Travel Time below)
- Diversion targets: Some plants can divert water to a separate downstream plant (not the immediate cascade successor), bounded by
- Pumping stations: May receive pumped water (increasing storage) or supply water to pumps (decreasing storage)
Key Parameters
Section titled “Key Parameters”| Parameter | Units | Description |
|---|---|---|
| , | hm³ | Storage bounds (useful volume) |
| , | m³/s | Turbined flow bounds (machine limits) |
| , | m³/s | Outflow bounds (environmental flow, flood control) |
| , | MW | Generation bounds (user-defined, not derived from flow) |
| m³/s | Maximum diversion flow | |
| MW/(m³/s) | Productivity (constant model) | |
| — | FPHA hyperplane coefficients for plane | |
| m³/s | Incremental inflow (stochastic, from PAR model) | |
| , | 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 | Upstream cascade outflows (with travel time delay) | |
| Inflow | Diverted water received from other plants | |
| Inflow | Pumped water received from pumping stations | |
| Outflow | Turbined + spillage + diversion (released downstream) | |
| Outflow | Evaporation (reservoir surface loss; can be negative for net precipitation) | |
| Outflow | Water withdrawal (consumptive use, removed from system) | |
| Outflow | Pumped water extracted by pumping stations |
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, and the release is then delivered to the downstream reservoir a number of stages later instead of immediately.
Cobre 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 — it changes the state vector and the Benders cuts, exactly as reservoir storage and AR lags do — it is formulated at the LP level in LP formulation §5d. 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 to downstream_id. Diversion and pumping transfers remain instantaneous. A travel time that is absent or zero is treated as an instantaneous transfer, adding no state.
Not-yet-operating downstream. A release into a downstream plant that has not yet reached operating status — still filling its dead volume, or before its commissioning entry stage — is rejected at load time: the water would arrive at a reservoir that does not yet exist in the dispatch. The receiving plant must be operating over the arrival window.
Horizon limitation. In-transit water that would mature after the study’s last stage is dropped rather than credited to terminal storage — see LP formulation §5d.
Production Function (Water to Power)
Section titled “Production Function (Water to Power)”Cobre supports three models for converting turbined flow to electrical generation, in increasing order of complexity:
-
Constant Productivity: — simple linear relationship with fixed [MW/(m³/s)], suitable for plants with stable head.
-
Linearized Head (simulation-only): Adjusts productivity based on head variation with storage level. Requires hydro geometry data (Volume-Height-Area curve). This model is excluded from training because the bilinear term () requires re-fixing between iterations, changing the LP and breaking SDDP convergence guarantees. See hydro production models §3.
-
FPHA (Função de Produção Hidrelétrica Aproximada): Piecewise-linear approximation via hyperplanes that captures head variation with storage level and accounts for tailrace effects from spillage. Each plane :
The production model can vary by stage or season per hydro.
For the complete FPHA formulation and model comparison, see hydro production models.
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 |
|---|---|---|
| Minimum storage (dead volume) | ||
| Minimum turbined flow (equipment limits) | ||
| Minimum outflow (environmental flow) | ||
| Maximum outflow (flood control) | ||
| Minimum generation (grid services) | ||
| feasible | Evaporation within physical limits | |
| met | Water withdrawal commitment | |
| (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 emergency spillage, not a slack variable. For the penalty priority ordering and cost magnitudes, see Penalty System. For the complete constraint formulations, see equipment formulations.
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 start_stage_id, or a non-filling hydro at any stage outside its commissioning window (before entry_stage_id, or from exit_stage_id 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 active downstream plant (or the network sink if none), so incremental inflow and upstream releases reach the cascade below without being lost at the un-built site.
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.
Dead-Volume Filling
Section titled “Dead-Volume Filling”Cobre models the commissioning of new hydro plants with a filling period ([start_stage_id, entry_stage_id)) 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 inactive)
- Outflow is limited to spillage (turbines not operational), with the
outflow_violation_belowslack 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
filling_min_rate_m3s. The floor ramps up to at the last filling stage; its slack is priced below deficit (a fill schedule is not defended as hard as load serving)
When the plant enters service at entry_stage_id, the ordinary soft minimum-storage floor takes over. For the per-stage floor trajectory and the penalty ordering, see Penalty System.
Role in Objective Function
Section titled “Role in Objective Function”- Spillage cost: Small regularization ($0.001–0.01 per m³/s·h) to prefer turbining over spilling
- FPHA turbined cost: Regularization applied only to hydros using the FPHA production model. Must be >
spillage_costfor the same plant to prevent interior FPHA solutions. See Penalty System. - Diversion cost: Small regularization, typically higher than spillage (water leaves main cascade)
- Slack penalties: High costs for constraint violations — storage below dead volume, outflow violations, generation violations, evaporation violations, water withdrawal shortfall. 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”Water balance (reservoir dynamics):
where includes all inflow and outflow terms listed above.
AR lag pinning (inflow history): for all , enforced by equal column bounds (not a constraint row)
Outflow definition:
Generation constraint (depends on production model):
- Constant productivity:
- FPHA: for each plane
For the fully assembled constraints, see LP formulation.
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 a stochastic availability value per scenario from the scenario pipeline, 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 spillage_cost for hydros — 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
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. The curtailment penalty is unused because the curtailment slack is zero by construction. 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.
The pin is applied per scenario by overwriting the upper and lower bounds on the NCS column with before each stage solve. The availability ratio and the per-(stage, block) shape factor multiply the installed capacity exactly as in the curtailable case — only the lower bound differs.
Operative States
Section titled “Operative States”Non-controllable sources follow the generic commissioning window (§1, Entity Commissioning Windows), controlled by entry_stage_id and exit_stage_id:
| State | Condition | LP Variables |
|---|---|---|
non_existing | Before entry_stage_id | Pinned to zero |
operating | generation, curtailment (derived) | |
decommissioned | At or after exit_stage_id | Pinned to zero |
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 , where is the stochastic available generation for the current (stage, scenario). The implementation may equivalently formulate curtailment as a reward for dispatching (negative cost on ) rather than a penalty on ; either is valid. For must-run sources, by construction (the lower bound on the generation column equals ), so the regularisation term contributes zero to the objective regardless of how it is signed.
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 (hard physical upper bound) | |
| MW | Available generation for current (stage, scenario), from scenario pipeline. Bounded by | |
| $/MWh | Curtailment cost (regularization penalty) |
Role in Objective Function
Section titled “Role in Objective Function”The curtailment cost is a small regularization term ($0.001–0.01/MWh) that incentivizes the solver to use all available generation before curtailing.
LP Constraint Preview
Section titled “LP Constraint Preview”Generation bounds (hard constraints, no slack variables):
Load balance contribution at connected bus: (generation injected).
For detailed constraints, see equipment formulations.
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”LP Constraint Preview
Section titled “LP Constraint Preview”Flow bounds:
Water balance impact: Source hydro: (water removed); Destination hydro: (water added).
Load balance impact at connected bus: (power consumed).
For detailed constraints, see equipment formulations.
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, identified by a type field.
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”Because import prices are positive and export prices are negative, this single summation naturally adds import costs and subtracts export revenue.
LP Constraint Preview
Section titled “LP Constraint Preview”Capacity bounds: . A non-zero lower bound acts as a hard take-or-pay floor — the LP must dispatch at least that quantity at the contract price. Contracts are stateless and honor the generic commissioning window (§1).
For detailed constraints, see equipment formulations.
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, Segment limits | Fuel cost | |
| Thermal (anticipated) | , | Ring-buffer slot pinning + fishing equality | Commitment cost discounted to delivery stage | |
| Hydro Plant | , | , , , | Water balance, Generation function | Spillage/diversion cost (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 variables , the AR lag variables , and the anticipated-thermal ring-buffer slots are the state variables that link stages through the Bellman recursion — joined, when a cascade arc declares a water travel time, by the in-transit buckets carrying released water toward its downstream plant (see LP formulation §5d). 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 Cobre
Section titled “Implementation in Cobre”The methodology above defines every system element; the tabs below cover how Cobre’s software surface configures and reports the network layer — buses and transmission lines. The remaining elements (thermals, hydros, non-controllable sources, pumping stations, contracts) are covered by their own chapters’ Implementation tabs (hydro production models, equipment formulations).
Cobre’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 and is documented in the
Penalty System Configure tab
— this chapter does not repeat that field table.
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. See the Penalty System Configure tab for the segment field table and the two-tier resolution order. |
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 differ from source_bus_id (no self-loop lines). |
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. Defaults to 0.0 (lossless). Sets the transmission efficiency used in body §3 (efficiency = 1 - losses_percent/100). |
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. |
Per-stage refinements of both capacity bounds and exchange_cost are
supplied by separate files — 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.
This is a topic-scoped index of the files the network layer 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 Directory 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/exchange_factors.json | Optional per-(line_id, stage_id, block_id) capacity de-rating multipliers for capacity.direct_mw / capacity.reverse_mw — planned outages, seasonal de-rating, or time-of-day transfer limits. Absent entries default to a factor of 1.0. |
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 Directory 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. |
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
- Equipment formulations — detailed per-equipment constraint derivations
- Hydro production models — FPHA and linearized head alternatives for the hydro production function
- Penalty System — penalty costs, priority ordering, and the full penalty taxonomy