LP Formulation
Purpose
Section titled “Purpose”This chapter presents the complete stage subproblem LP for the Novomodelo SDDP solver: the objective function with its cost taxonomy, all constraint families, slack/penalty variables, and the Benders cut interface to the future cost function. It uses the parallel blocks formulation by default.
Reading order: System Element Modeling Overview → Equipment-Specific Formulations → this chapter → State Augmentation
For what each physical element represents and its decision variables, see System Element Modeling Overview. For variable naming conventions and index sets, see Notation Conventions.
Stage LP at a Glance
Section titled “Stage LP at a Glance”Given its incoming state, the stage LP minimizes the objective below subject to the rows of every family it carries, each written in its parallel-stage form with the symbols of its owning section, standing for terms that section writes in full; the in-transit bucket and commitment-ring families are named in one line.
The table lists the families in the order of the stage LP’s rows, with hydros and blocks at the stage.
| No. | Row family | Rows per stage | Section |
|---|---|---|---|
| 1 | Realized-inflow definition | , one per hydro | §5 |
| 2 | Water balance | on a parallel stage, on a chronological stage | §4 |
| 3 | In-transit bucket definition | one per receiving plant and maturity lag reached at the stage | State Augmentation — Bucket definition rows |
| 4 | Load balance | , one per bus and block | §3 |
| 5 | FPHA planes | one per plane, (hydro, bus) cell and block of each FPHA hydro; none while the hydro is PreFilling or in its filling window | §6 |
| 6 | Evaporation | one per evaporating hydro on a parallel stage, one per evaporating hydro and block on a chronological stage; none while the hydro is PreFilling | §4 Evaporation Row |
| 7 | Minimum outflow | , one per hydro and block | §7 |
| 8 | Maximum outflow | , one per hydro and block | §7 |
| 9 | Minimum turbined flow | one per (hydro, bus) cell and block | §8 |
| 10 | Minimum generation | one per (hydro, bus) cell and block | §6 |
| 11 | Filling floor | one per filling hydro at each stage of its filling window | §8 |
| 12 | Soft dead-volume floor | one per filling hydro at each stage from its entry stage on | §8 |
| 13 | Commitment fish | one per anticipated thermal whose delivery at the stage was decided at an earlier stage or before the study | State Augmentation — Ring Rows |
| 14 | Commitment deposit | one per anticipated thermal that decides at the stage a commitment for a delivery inside the study or the declared post-study calendar at which the plant is commissioned | State Augmentation — Ring Rows |
| 15 | Commitment carry | one per ring slot holding a later delivery, decided at an earlier stage or before the study, inside the study or the declared post-study calendar | State Augmentation — Ring Rows |
| 16 | Generic constraints | one per active bound and block it covers, or one stage-level row for a block-independent bound | §10 |
| 17 | Benders cuts | one per active cut; one per resident cut under Dynamic Cut Selection | §11 |
Incoming-state pinning and the lifecycle pins are column bounds, not rows: each incoming-state column is fixed at its trial value by equal bounds (State Augmentation §2), and each column a lifecycle phase freezes is fixed by its bounds (§8).
1. Cost and Penalty Taxonomy
Section titled “1. Cost and Penalty Taxonomy”Penalty System owns the cost categories, their units, their priority ordering, the ordering checks and the resolution cascade; the table lists the cost symbols of each category as this page writes them.
| Category | Cost symbols |
|---|---|
| Thermal and contract costs | , |
| Recourse slacks | , , |
| Constraint violation penalties | , , , , , , , , , |
| Regularization costs | , , , , |
Pumping carries no cost term; the power a pumping station draws enters the load balance of its bus (§3, Equipment-Specific Formulations §4).
1.1 Objective Function Structure
Section titled “1.1 Objective Function Structure”The complete stage objective is:
where the per-block terms are weighted by the block duration and the stage-level terms, namely the storage-violation slacks on end-of-stage storage, the inflow non-negativity and withdrawal slacks, the evaporation slacks of a parallel stage, the slacks of a stage-level generic constraint (§10) and the commitment cost of an anticipated thermal, apply once per stage (§2); the per-block part of each component is:
The coefficient of is the one-step discount factor of Discount Rate Formulation, equal to 1 at a zero rate.
2. Objective Function
Section titled “2. Objective Function”Wherever the inflow non-negativity slack enters the water balance of (§4), it supplies water to that balance at per hm³, so on a parallel stage the value of one more hm³ of water at is at most . On a chronological stage the slack enters every block row with its , and the bound holds for the duration-weighted average, with weights , of the block values, not for each block. The bound is one-sided: it caps the value of water, not a negative value of surplus water. Penalty System — Penalty Priority Ordering converts the inflow cost to $/MWh and orders it below deficit, so that the LP takes slack water before it sheds load. On a parallel stage the storage cut coefficient read at the stage inherits the bound, , where enters only the water balance; an FPHA plane, the evaporation row or a generic constraint that reads adds its own terms.
Anticipated thermals (State Augmentation §5) add one stage-level commitment-cost term per plant deciding a commitment at the stage — not a per-block term: the commitment column priced at the plant’s unit cost and hours of the delivery stage and discounted from it (State Augmentation — Objective contributions). Their per-block generation carries no thermal cost at a stage where the plant has a fish row (State Augmentation — Ring Rows), which ties it to the committed rate; at any other stage it is priced like any thermal.
3. Load Balance Constraint
Section titled “3. Load Balance Constraint”Each hydro plant is partitioned into one or more (hydro, bus) cells — one cell per distinct bus among the plant’s declared unit groups (see System Element Modeling Overview §5). denotes the set of buses hosting one of ‘s cells; denotes the hydros with a cell at bus (i.e. ). is the generation of hydro ‘s cell at bus , block — the quantity that actually injects at . A plant whose groups share a single bus has , and collapses to the single-cell used everywhere else in this chapter.
For each bus and block :
Dual variable: (marginal cost of energy at bus , block , in $/MW; divide by for $/MWh — see Variable Units Convention)
For the physical meaning of each element in the balance, see System Element Modeling Overview.
4. Hydro Water Balance
Section titled “4. Hydro Water Balance”Every hydro has one water-balance row on a parallel stage and one per block on a chronological stage (Block Formulation Variants); every LP variable is on the left-hand side.
Parallel-Stage Row
Section titled “Parallel-Stage Row”Chronological-Stage Rows
Section titled “Chronological-Stage Rows”For each block , with and :
Row Terms
Section titled “Row Terms”- and = outgoing and incoming storage; is pinned to the trial value by its column bounds (State Augmentation §2). On a chronological stage is the storage at the end of block
- = in-transit volume maturing at this stage on the travel-time arcs into , in hm³ and therefore outside the conversion (State Augmentation §6); a chronological stage spreads it over its blocks by the arrival density , . Absent when no travel-time arc enters
- = realized incremental inflow (§5), so block of a chronological stage receives the share of the innovation
- = inflow non-negativity slack, present under the penalty-based methods, which adds water (see Inflow Non-Negativity Solution Methods)
- , , = signed stage-level withdrawal target ( adds water) and its stage-level under- and over-delivery slacks; the realized withdrawal is , with the slack caps in §9
- / = signed net evaporation of a hydro with an evaporation model (a negative value is net rainfall on the lake and adds water): one stage-level column on a parallel stage of any block count, one per block on a chronological stage, each a bounded column tied to storage by its evaporation row (see Evaporation Row)
- , , = the plant’s own turbined, spilled and diverted flow in block ; every (hydro, bus) cell’s turbined column carries the same coefficient, and spillage and diversion are single per-plant columns
- Upstream release: only the turbined and spilled flow of each reaches ; a plant’s diverted flow reaches only its diversion target (the sum)
- = same-stage share of the release of on a parallel stage, with the duration of stage and the travel time of ‘s main cascade arc ( when none is declared, so the share is ); the remaining is deposited into the in-transit buckets (State Augmentation §6)
- = within-stage routing share on a chronological stage: the fraction of ‘s block- release that reaches ‘s block- row in the same stage, . Without a travel time and for ; the rest of the release is deposited into the buckets (State Augmentation §6)
- = pumped flow of station , out of its source plant’s row and into its destination plant’s row (see Equipment-Specific Formulations); on a parallel stage every block’s pumped flow enters the single stage row
- and = stage and block flow-to-volume conversions, with the duration of block in hours and its weight, so
PreFilling Pass-Through
Section titled “PreFilling Pass-Through”A PreFilling hydro (see Lifecycle Phases for the phase) has the frozen identity row , and on a chronological stage per block, with right-hand side . Its local inflow , the releases of its upstream plants and the flows diverted into it enter the row of the first non-PreFilling plant downstream with the coefficients they would carry on the PreFilling plant’s own row ( on on a parallel stage and on each block row of a chronological stage, on every block- flow) and no travel-time share, and its withdrawal target moves to that plant’s right-hand side. Its maturing in-transit volume enters the same row, with coefficient on a parallel stage and on block ‘s row of a chronological stage, being the PreFilling plant’s own arrival density. With no such plant downstream the water leaves the system.
Summing the Block Rows
Section titled “Summing the Block Rows”Summing a chronological stage’s block rows over telescopes the storage terms to , returns (), and returns the parallel coefficients of , , , and the right-hand side (); the per-block flows keep their . The sum has the parallel row’s form with two mode differences: in place of , and each upstream block- release carrying its own same-stage share in place of , whose duration-weighted average over is : . With one block, or no travel time on the arc, the shares coincide.
Dual variable: for the parallel row; on a chronological stage each block row has its own dual (water value — captures the marginal value of incoming storage as seen through the hydro balance, but is not used directly as a cut coefficient; the cut coefficient comes from the reduced cost of the pinned incoming-storage column, see State Augmentation §2 and Cut Management)
Evaporation Row
Section titled “Evaporation Row”Every hydro with an evaporation model has an evaporation row that ties its net evaporation to storage. A parallel stage, of any block count, has one row per such hydro, on the stage’s incoming and outgoing storage:
A chronological stage has one row per block , on the block’s own storages, with and :
- and = slope and intercept, at a reference volume, of the tangent of the evaporation flux of : the evaporation coefficient of the stage’s calendar month times the reservoir surface area from its area–volume curve, converted to a monthly-average rate in m³/s. Both are recomputed at every stage; the row’s target is the tangent evaluated at the average of the two storages the row reads. The flux, and so or , can be negative (net rainfall on the lake)
- / = net evaporation (Row Terms above), bounded symmetrically about zero by a fixed safety margin times , the magnitude of the target at the maximum storage , recomputed at every stage; it is not a free column. It enters the parallel water-balance row as and the block- row of a chronological stage as
- / and / = evaporation above and below the target, priced at and : the row sets the evaporation to the target plus minus . On a parallel stage the one pair is priced over the stage hours , on a chronological stage each block’s pair over its duration (§9)
With one block the parallel and chronological forms coincide, rows and pricing alike. A PreFilling hydro has no evaporation row.
5. Realized-Inflow Definition Rows
Section titled “5. Realized-Inflow Definition Rows”For each hydro , the LP includes an auxiliary variable representing the total realized inflow (m³/s) at the current stage. These variables are defined by equality constraints that combine the deterministic base, lag contributions, and stochastic noise:
where:
- = LP variable representing the realized inflow for hydro (free column, zero cost)
- = deterministic base (precomputed from seasonal means and AR coefficients — see PAR(p) Inflow Model §2.4)
- = original-unit AR coefficients (constraint matrix entries, set once at LP construction); for a hydro with the annual component the sum runs over every lag slot () and each of these coefficients also carries the annual term (PAR(p) Inflow Model §7.4)
- = LP variables for lagged inflows (state variables, fixed by State Augmentation §4)
- = noise innovation (patched into the constraint RHS per scenario)
The z-inflow variable then enters the water balance constraint (§4) in place of the raw inflow term , and its primal value after solving gives the realized inflow for reporting and simulation extraction.
The z-inflow columns sit between the leading state columns and the incoming storage columns, and their constraint rows form the first equality block (LP Layout and Scaling §1). The RHS is patched per scenario with , where is the effective noise (possibly clamped for inflow non-negativity — see Inflow Non-Negativity Solution Methods). They are not pinned state columns and carry no cut coefficient of their own; the cut row multiplies the lag-1 coefficient by .
Constraint count: total constraints, where is the number of hydros, whatever their lifecycle phase.
6. Hydro Generation Constraints
Section titled “6. Hydro Generation Constraints”Novomodelo supports two production models, in increasing order of complexity. A third model name, linearized head, is a reserved alias that resolves to constant productivity in every phase — see Hydro Production Function Models §3. The model can vary by stage or season per hydro.
Both models are evaluated per cell (§3) rather than per plant; for a single-cell plant the per-cell constraint is the plant-level constraint.
Constant Productivity Model (for each cell of hydro , block ):
Constant-productivity hydros carry no separate generation column: is this direct multiple of the cell’s own turbined-flow column, so a cell’s generation bound is enforced by folding it into that column’s bound (§8) rather than by a bound on itself.
FPHA Model (for each plane , cell of hydro , block ):
where is the average storage during the stage, with being the incoming storage LP variable (State Augmentation §2) and the end-of-stage storage on a parallel stage; on a chronological stage the row of block reads that block’s own average (Block Formulation Variants §2.4) — a single plant-level quantity shared by every cell, since storage is not partitioned. is cell ‘s apportionment share of plant ‘s declared turbine capacity,
(the ratio of the cell’s own unit groups’ declared maximum turbined flow to the plant’s total, when the plant’s total is ), so that for every plant with positive declared turbine capacity. Only the plane’s flow-independent part — the intercept , the storage term, and the spillage term — is apportioned by ; the flow coefficient stays on the cell’s own unscaled, because it alone is homogeneous in the cell partition (summing the per-cell rows at fixed , , and recovers the plant-level bound this replaces). A single-cell plant with positive declared turbine capacity has exactly, so its row is the plant-level row.
For a plant with positive declared turbine capacity the shares sum to , so the per-cell rows of each plane sum to that plane’s plant-level row (above). A sum of minima is at most the minimum of the sums, so at the same , and total turbined flow the cap the per-cell rows put on the plant’s generation , on the left, is at most the plant-level envelope, the minimum over the planes of the plant-level rows, on the right:
Equality holds when the same plane attains the minimum in every cell, in particular when the cells turbine in proportion to their shares . For the minimum of cell is times the plant-level envelope at the flow , so when every share is positive the display is Jensen’s inequality for the concave envelope with the weights . A cell with keeps only its term, and the display still holds by the sum-of-minima argument.
Generation Bounds (per cell , block — the FPHA generation column’s own bound; a constant-productivity cell has no such column, so its generation cap is folded into the turbined-flow bound below instead):
Generation bounds are user-defined (declared per unit group, not derived from turbined flow). The lower bound is soft, with one slack per cell — priced at the plant’s own penalty at full magnitude on every cell of a split plant, never divided by cell count; a constant-productivity cell’s floor couples this same slack to rather than to a generation column. The upper bound’s plain sum over the cell’s own unit groups closes against the plant’s own resolved maximum — a bounds override may never raise a cell above it. See System Element Modeling Overview §5. Matches the per-cell defined in Notation Conventions §4.3.
For details on the FPHA construction and production function model variants, see Hydro Production Function Models.
7. Outflow Constraints
Section titled “7. Outflow Constraints”Outflow Definition (per hydro , block ):
Outflow Bounds (with slacks for soft enforcement):
8. Variable Bounds and Minimum Constraints
Section titled “8. Variable Bounds and Minimum Constraints”Storage Bounds (per hydro )
Section titled “Storage Bounds (per hydro hhh)”The dead volume is a hard lower bound for every hydro except two cases: a hydro with a filling configuration has a floor of in every phase, the per-stage filling floor below taking its place while it fills, and from its entry stage on the dead volume returns as the soft floor , the only storage-below-minimum slack of the LP, priced above deficit; a hydro without a filling configuration has a floor of while PreFilling, where its frozen identity (§4) holds the storage at its incoming value. On a chronological stage the block-end storages carry the same column bounds, and the soft floor applies to the end-of-stage storage only. The upper bound is hard; excess water leaves through spillage.
Filling floors (for filling hydros, at every filling stage , from the filling start stage up to, not including, the entry stage):
is the dead volume in force at stage (a stage may override it), is the last filling stage, the stage before the entry stage, and the minimum accumulation rate of stage , which converts into hm³. The floor at stage is the dead volume of stage minus the accumulation the schedule still owes after , never above the dead volume of stage itself; it reaches at . Every filling stage carries its floor. The slack is priced at , which Novomodelo expects below deficit (Penalty System — Penalty Ordering Validation checks it as given). See Penalty System §6.
Turbined Flow Bounds (per cell , block )
Section titled “Turbined Flow Bounds (per cell (h,b)(h, b)(h,b), block kkk)”The lower bound is soft, with one slack per cell, priced at the plant’s own penalty at full magnitude on every cell — never divided by cell count; it is the plain sum of the cell’s own unit groups’ resolved minimum turbined flow, . The upper bound is hard and closes against the plant’s own resolved maximum, never raised above it:
where for an FPHA hydro (turbined flow and generation are independent columns there) and for a constant-productivity hydro — each group’s own flow cap and MW-implied flow cap must be folded before summing across the cell, since does not distribute over a sum of groups that bind on different sides. This is the mechanism that enforces a constant-productivity cell’s generation cap (§6): there is no separate generation column to bound directly. Matches the per-cell defined in Notation Conventions §4.3.
Diversion Flow Bounds (per hydro , block )
Section titled “Diversion Flow Bounds (per hydro hhh, block kkk)”The lower bound is unless a minimum diversion flow is set for the stage or for the block, which replaces it. Both bounds are hard. Diversion cost is a regularization term (see §1), not a violation penalty.
Spillage Bounds (per hydro , block )
Section titled “Spillage Bounds (per hydro hhh, block kkk)”Spillage is bounded below by and above by unless a minimum or maximum spillage is set for the stage or for the block, which replaces the bound. Both bounds are hard. While the hydro is PreFilling, spillage is fixed at (Lifecycle Phases).
Pumping Flow Bounds (per station , block )
Section titled “Pumping Flow Bounds (per station yyy, block kkk)”Both bounds are hard.
Lifecycle Phases
Section titled “Lifecycle Phases”At each stage a hydro is in exactly one lifecycle phase, set by its commissioning window and, for a filling hydro (a hydro with a filling configuration), by its filling start; every other entity is either in service (inside its commissioning window) or out of service.
| Phase | Applies at | Storage row and floor | Turbined flow and generation | Spillage | Diversion | Inflow, upstream releases and withdrawal | Operational floors |
|---|---|---|---|---|---|---|---|
| PreFilling | A hydro without a filling configuration: every stage outside its commissioning window, before its entry stage or from its exit stage on. A filling hydro: every stage before its filling start | Frozen identity , per block on a chronological stage, with right-hand side (§4); floor ; no evaporation row | fixed at on every cell; no FPHA rows and no generation column | fixed at , whatever its bounds | fixed at | The local inflow, the releases of the upstream plants, the flows diverted in and the in-transit volume maturing into the plant enter the row of the first non-PreFilling plant downstream, and the withdrawal target moves to that plant’s right-hand side; with no such plant the water leaves the system | The minimum-outflow, minimum-turbined-flow and minimum-generation rows are present; with turbined flow, spillage and generation at , a positive minimum falls wholly on its slack, at its penalty (§9) |
| Filling | A filling hydro: every stage from its filling start up to, but not including, its entry stage | Water balance of §4, with the evaporation row of an evaporating hydro; floor and the per-stage filling floor of §8 Storage Bounds | fixed at on every cell; no FPHA rows and no generation column | Within its bounds | fixed at | On the plant’s own row (§4) | The same rows are present; a positive minimum turbined flow or minimum generation falls wholly on its slack, and spillage can meet a positive minimum outflow |
| Operating | A hydro without a filling configuration: every stage inside its commissioning window, so every stage when it declares none. A filling hydro: every stage from its entry stage on; it has no exit stage | Water balance of §4, with the evaporation row of an evaporating hydro; the hard dead-volume floor for a hydro without a filling configuration, and for a filling hydro floor with the soft dead-volume floor | Turbined flow within the Turbined Flow Bounds above; generation by the production model of §6 | Within its bounds | Within the Diversion Flow Bounds above for a hydro without a filling configuration; fixed at for a filling hydro | On the plant’s own row (§4) | The same rows are present; the minimum turbined flow is met by the cell’s turbined flow, the minimum generation by its generation, and the minimum outflow by turbined flow plus spillage, with the slack covering any shortfall at its penalty (§9) |
Outside its commissioning window a thermal’s generation, a line’s flow in each direction, a non-controllable source’s generation, a pumping station’s pumped flow and a contract’s power are fixed at in every block; an anticipated thermal’s commitment is gated by its delivery stage in addition, and is opened only when the plant is in service at that delivery stage, whatever its status at the decision stage (State Augmentation §5).
9. Constraint Violation Penalty Terms
Section titled “9. Constraint Violation Penalty Terms”The per-block constraint violation penalties in the objective (referenced from §2) are:
The turbined- and generation-minimum slacks are per cell — each of a split plant’s cells carries its own slack column and its own row, priced at the plant’s penalty at full magnitude, never divided across cells. The outflow slacks stay per plant: outflow has no per-cell column to attribute a floor to. The evaporation slacks are per plant too, stage-level on a parallel stage and per block on a chronological stage (Evaporation Row).
where is the total stage duration in hours, and the evaporation sums run over the hydros that model evaporation. Withdrawal violation slacks (, ) are stage-level (not per-block) and bidirectional: penalizes under-delivery (the realized withdrawal falls short of the target), and penalizes over-delivery. The withdrawal target is signed (§4), and the slack bounds ensure the realized withdrawal cannot flip sign relative to the target:
- (scheduled removal): (under-delivery slack capped at the target magnitude; floors ), unbounded.
- (scheduled inter-basin return/addition): (over-delivery slack capped at ; caps ), unbounded.
- : both slacks are pinned to zero.
This cap guards a degenerate case: an unbounded under-delivery slack would let a run-of-river plant “un-withdraw” past its target and inject phantom water into the reservoir.
10. Generic Constraints
Section titled “10. Generic Constraints”User-defined linear constraints (per constraint ) take a two-sided interval form:
where is a quantity of the stage LP that the generic-constraint variable catalog exposes — a column such as storage, a flow, a generation or a deficit, or a fixed combination of columns such as the inflow of a hydro (below).
A term on the turbined flow or the generation of a plant split across buses may address one (hydro, bus) cell or all of the plant’s cells at once (§3).
A term may also address a plant’s useful volume — its storage above the physical minimum . It is realised on the storage variable itself by shifting both endpoints by the same amount,
so it adds no LP variable; an absent endpoint stays absent, and a negative lowers both endpoints.
Either endpoint, or , may be absent — never both — with an absent side read as the corresponding infinity. This single interval subsumes every shape a constraint can take: a present alone is a floor, a present alone is a cap, is an equality, and both present together bound a two-sided band. A constraint’s shape — floor, cap, equality or band — follows from which endpoints are present and, when both are, whether they coincide.
Coefficients and Endpoints
Section titled “Coefficients and Endpoints”The coefficients may be either literal numeric values or named scalar parameters, exactly as for any other coefficient in the LP.
Each endpoint composes independently from up to two pieces, summed together: a numeric base that may itself vary by stage (and, for the finest-grained parameter kind below, by block within the stage), plus an optional affine remainder layered on top of it — a constant plus a weighted sum of named scalar parameters. An endpoint carrying neither piece is simply absent; a base alone, a remainder alone, or their sum are all valid, so a single endpoint can combine a scheduled floor or cap that already varies by stage with a further parameter-driven adjustment on top.
A named scalar parameter takes one of five kinds: one value for every stage; one per stage; one per season; a quantity computed from a plant’s geometry and energy conversion, §5 of Hydro Production Function Models; or one per stage and block.
Resolution happens once at LP-build time, so the LP coefficients and endpoints are still numeric at solve time — the parameter mechanism does not introduce LP-variable coupling between constraints. Methodology relevance: it lets the corpus express ramping limits, capacity caps, and operator-imposed quotas that vary by stage, season, or block without authoring a separate constraint per stage. Coefficient and endpoint values can therefore be stage- and block-varying constants, not just literal numbers.
Two-Sided Slack
Section titled “Two-Sided Slack”A constraint may optionally carry a slack, penalized per unit of violation, so the row relaxes at a cost instead of forcing infeasibility. A one-sided row — only or only present — carries a single slack column relaxing that one endpoint. A two-sided row — both and present — carries two independent slack columns, relaxing the floor upward and relaxing the cap downward: a single column cannot represent both “how far below the floor” and “how far above the cap” without conflating the two directions.
The reported violation is the signed net : positive when the row sits below its floor, negative when it sits above its cap, matching the sign of the underlying deviation rather than reading as an unsigned magnitude. The objective charges both columns, , which coincides with the net’s magnitude whenever only one direction is active — the case at any optimum, since paying for both directions on the same row at once is strictly dominated by paying for neither of the excess.
Row materialization: a constraint bound declared for every block of the stage over a block-independent expression — one whose every term references a stock variable (incoming storage , outgoing storage , evaporation (the stage-level on a parallel stage, a named block’s on a chronological stage), or an anticipated-thermal commitment) — is materialized as a single stage-level row priced by the total stage hours , since per-block rows would be identical, provided its coefficients and endpoints are block-independent too: a coefficient or an endpoint drawn from the per-(stage, block) parameter kind above varies within the stage, which forces the per-block row set even when the expression alone would otherwise qualify for the collapse. A bound declared for every block on a block-level expression, or a bound declared for one block, still produces one row per relevant block. This is an LP row-count optimization that is cost- and parity-neutral.
See Generic Constraints for the authoring grammar, the activation grid, and the per-file field tables this formulation implements.
Hydro Inflow
Section titled “Hydro Inflow”A hydro-inflow term reads the inflow of hydro in block , a rate in m³/s built from LP columns:
Each upstream release is credited to block by the travel time of its arc:
- = turbined plus spilled outflow of (§7), credited with the same-stage share or the within-stage shares of §4
- = arrival density of State Augmentation §6 on a chronological stage and on a parallel stage: the share of the maturing in-transit volume that arrives in block , which the division by turns into a rate; the maturing term is absent when no travel-time arc enters
- = PreFilling plants at stage whose first non-PreFilling downstream plant is (see PreFilling Pass-Through); the local inflow of each, the flows diverted into it and the releases of its upstream plants enter whole, with no travel-time share, and its maturing in-transit volume enters as the rate , by its own arrival density
The term excludes pumping, the inflow non-negativity slack, the plant’s own outflows, evaporation and withdrawal.
For a hydro that is not PreFilling at stage , the term mirrors the inflow terms of its water balance (§4) listed below. On a chronological stage equals the inflow terms of block ‘s water-balance row: the local inflow, the flows diverted in, the credited releases, the maturing transit volume and the PreFilling pass-through. On a parallel stage equals the same terms of the stage row, and only the duration-weighted stage total matches the balance; the split across blocks is a convention.
For a PreFilling hydro the term reads the same columns, with empty, and they match no row of , whose row is the frozen identity (PreFilling Pass-Through): its local inflow, the flows diverted into it, the releases of its upstream plants and its maturing transit volume enter the row of the first non-PreFilling plant downstream, or leave the system when there is none (Delayed-arrival water-balance entry).
reads per-block columns, so a bound without a block expands to one row per block (see row materialization in §10).
11. Benders Cuts
Section titled “11. Benders Cuts”For each cut in the stage LP, that is each active cut or, under Dynamic Cut Selection, each cut resident in the solve (Cut Management §8):
where:
- = cut intercept (RHS)
- = coefficient for storage state variable, present when the cut keeps the storage dimensions
- = coefficient for the inflow lag of the next stage’s incoming state, multiplied by the realized inflow for and by the incoming lag for ; present when the cut keeps the inflow-lag dimensions
When anticipated thermals are present, the cut carries one coefficient per commitment-ring slot (State Augmentation §5), read from the same reduced-cost mechanism; when travel-time arcs are present, it likewise carries one coefficient per in-transit bucket dimension (State Augmentation §6). Unlike the storage and lag coefficients, the ring-slot and bucket coefficients are always part of the cut projection (State Augmentation §7).
The future-cost variable has lower bound at every stage, which presumes . Stage objectives can be negative: export contracts earn revenue (§2), and the curtailment term of §2 is a reward: it is never positive, and it is constant for a must-run source. Where is negative the bound lies above it, so the cut approximation need not lie below and the lower bound is not guaranteed. At the last stage of the finite horizon, with no terminal boundary loaded, is (); with a terminal boundary loaded, keeps the floor and the imported cuts bound it from below, so the terminal function is the larger of and the imported cuts.
Cuts live in an append-only pool at stable slot indices: every cut ever generated is retained for the lifetime of the run, and only the active subset is baked into each iteration’s stage template. Deactivation excludes a cut from each iteration’s stage-template rebake rather than mutating any row; the persistent lower-bound LP is append-only (its rows are never removed, so the lower bound stays monotone). Slot indices stay stable, so reactivation — re-baking the cut into the template at the same slot — is exact. Dynamic Cut Selection deactivates no cut itself: each solve loads a resident subset of the active cuts and grows it with the omitted candidate cuts its solution violates. A per-stage cap on the number of active cuts, when set, deactivates cuts once it is exceeded, under every selection method.
For cut coefficient derivation, aggregation, and selection strategies, see Cut Management.
Cross-References
Section titled “Cross-References”- Notation Conventions — index sets, parameters, decision variable naming
- System Element Modeling Overview — physical meaning of each element, decision variables, Variable Units Convention
- Penalty System — three-category taxonomy, penalty names, priority ordering, cascade resolution
- SDDP Algorithm — iterative structure that solves this LP at each stage
- State Augmentation — the state vector, its pinning by column bounds, the outgoing state and the cut row, and the inflow-lag, commitment-ring and in-transit state families
- LP Layout and Scaling — the column and row layout of this LP, its cost scaling and prescaling, and the unscaling of its duals and reduced costs
- PAR(p) Inflow Model — complete AR inflow model specification
- Hydro Production Function Models — constant, linearized head, and FPHA model details
- Cut Management — dual extraction, cut coefficients, aggregation, and selection
- Equipment-Specific Formulations — per-equipment constraint derivations, pumping details