Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Cobre

Open infrastructure for power system computation.

Cobre is an ecosystem of Rust crates for power system analysis and optimization. The name comes from the Portuguese word for copper — the metal that conducts electricity. The project is licensed under Apache-2.0.

This site is the methodology reference

This site documents the theory, design specifications, and roadmap behind Cobre. It is written for researchers, algorithm designers, and contributors who need to understand why the system works the way it does.

What you will find here:

  • Theory — The mathematical foundations: SDDP and Benders decomposition, stochastic inflow modeling with PAR(p), cut management strategies, and risk measures including CVaR.
  • Specifications archive — The design-phase artifacts that governed each implementation phase: data model schemas, architectural trait contracts, HPC communication patterns, and testing contracts.
  • Roadmap — Planned features and deferred variants, with rationale for what was prioritized in the minimal viable solver.
  • Reference — Glossary of domain terms, notation conventions, and bibliography.

Software Book

For installation instructions, tutorials, user guides, CLI reference, and per-crate API documentation, see the Software Book.

The software book describes what the software does today. This site describes the theory and design decisions behind it.

Go to the Software Book >>

Go to the Software Book >>

SDDP Theory

Stochastic Dual Dynamic Programming (SDDP) is the core optimization algorithm behind Cobre’s hydrothermal dispatch solver. This page provides a practical overview of how the algorithm works. For the complete formal specification, see SDDP Algorithm (spec).

What problem does SDDP solve?

Power system operators must decide how much water to release from reservoirs and how much thermal generation to dispatch at each time step over a multi-month or multi-year horizon. The challenge is uncertainty: future river inflows are unknown, and using too much water now risks expensive thermal generation later, while hoarding water risks spilling it.

SDDP finds the least-cost generation schedule that accounts for this uncertainty across all stages simultaneously. The decision at each stage depends on the current reservoir levels, recent inflow history, and a probabilistic model of future inflows.

How SDDP works: forward and backward passes

SDDP is an iterative algorithm. Each iteration has two phases:

Forward pass. The algorithm simulates the system forward in time, from stage 1 to stage . At each stage it samples a random inflow scenario, solves a linear program (LP) to determine optimal generation and reservoir operations, and records the resulting reservoir levels. These recorded states are called trial points. Multiple independent trajectories are simulated in parallel.

Backward pass. Walking backward from stage to stage 1, the algorithm re-solves each stage LP at the trial points collected during the forward pass – but now for every inflow scenario in the scenario set. From each solve it extracts dual variables (shadow prices) that measure how sensitive the future cost is to changes in reservoir levels. These sensitivities are assembled into Benders cuts: linear constraints that approximate the future cost function.

Each iteration adds new cuts, progressively tightening the approximation of future costs. The forward pass uses the latest cuts to make better decisions; the backward pass generates cuts at the states actually visited.

Lower and upper bounds

SDDP produces two bounds that bracket the true optimal cost:

Lower bound. The first-stage LP objective (including the cut-based future cost approximation) provides a deterministic lower bound . Because cuts can only tighten the approximation, this bound increases monotonically across iterations.

Upper bound. The average total cost across all forward pass trajectories provides a statistical upper bound . This estimate has sampling noise, so it is typically reported with a confidence interval.

Convergence

The algorithm monitors the optimality gap between the bounds:

When the gap falls below a threshold, or the lower bound stalls, the algorithm terminates. The resulting set of cuts defines the operational policy: at any future state, solving the LP with these cuts yields the recommended dispatch.

For detailed stopping criteria, see Convergence and Stopping Rules (spec).

Policy graphs

SDDP organizes stages into a policy graph – a directed graph where nodes are decision stages and arcs represent transitions.

Finite horizon. The standard setup is a linear chain of stages (e.g., 60 monthly stages for a 5-year study). The terminal stage has zero future cost.

Infinite horizon. For long-term planning, the last stage can loop back to the first, creating a cyclic graph. A discount factor on the cycle arc ensures convergence. Cuts at equivalent positions in the cycle are shared.

See SDDP Algorithm (spec) – Policy Graph Structure for details.

State variables

The state at each stage captures everything the future cost depends on. In Cobre, state variables are:

  • Reservoir storage volumes (): one per hydro plant, representing end-of-stage water levels
  • Autoregressive inflow lags (): past inflow values needed by the PAR(p) stochastic model to generate current-stage inflows

Together, these can reach approximately 2000 dimensions for a system with 160+ hydro plants and multi-lag inflow models.

The Markov property – future costs depend only on the current state, not on the path that led to it – is what makes cut generation mathematically valid. The AR lags are included as state variables precisely to preserve this property.

Single-cut formulation

Cobre uses the single-cut formulation by default: at each iteration, the per-scenario cut coefficients are averaged into one aggregated cut per stage. This keeps the LP small and solve times fast, at the cost of potentially needing more iterations. A multi-cut variant (one cut per scenario) is planned for future releases.

Further reading


See also: For implementation details and usage, see the SDDP crate documentation in the software book.

Benders Decomposition

Overview

Stochastic Dual Dynamic Programming (SDDP) solves large multistage stochastic optimization problems by decomposing them into smaller single-stage subproblems. This decomposition is rooted in Benders decomposition (also known as the L-shaped method), which splits a monolithic problem into a master problem and subproblems connected through linear inequalities called cuts.

In the hydrothermal dispatch context, a direct formulation over all stages, scenarios, and equipment would produce an LP with millions of variables and constraints. Benders decomposition breaks this into stage subproblems, each solved independently for a given incoming state and scenario realization.

The Stage Subproblem

Each stage solves an LP of the form:

where is the incoming state (reservoir volumes, AR inflow lags) fixed from the previous stage, captures the immediate cost (thermal generation, penalties, regularization), and approximates the expected future cost from stages through .

The full LP structure — objective terms, constraint families, slack variables, and variable bounds — is described in LP Formulation.

How Cuts Approximate Future Cost

The true future cost function is convex but unknown. SDDP builds a piecewise-linear lower approximation through iterative cut generation:

Each cut is a supporting hyperplane derived from dual variables of the backward pass. When the stage subproblem is solved at a trial state under scenario , the optimal dual multipliers of the state-linking constraints yield:

  • Slope: (sensitivity of future cost to incoming state)
  • Intercept:

Notation note: The matrix form above is the standard Benders decomposition notation from the stochastic programming literature. In Cobre’s formal specs, the cut coefficients are expressed directly in terms of LP dual variables: (the storage fixing constraint dual) and (the lag-fixing constraint dual), without explicit technology matrices. Both conventions are mathematically equivalent — the matrix form is compact for general derivations, while the direct-dual form is more practical for implementation. See Cut Coefficient Derivation below.

In the hydrothermal problem, the state variables are reservoir storage volumes and AR inflow lags , so the cut coefficients come from the storage fixing dual and the lag-fixing constraint dual .

Cut Coefficient Derivation

The key insight is how dual variables map to cut coefficients. Cobre introduces an explicit incoming-state LP variable for each state dimension, fixed to the trial value via an equality constraint:

By the LP envelope theorem, the dual of each fixing constraint equals the total derivative of the optimal objective with respect to the fixed value, accounting for all downstream effects:

Fixing constraintDualCut coefficient

For storage, the dual captures contributions from the water balance, FPHA hyperplane constraints, and any generic constraints that reference incoming storage — all aggregated automatically by the LP solver through the single incoming-storage variable. No manual dual combination is required.

The cut intercept ensures the cut passes exactly through the trial point:

where is the optimal stage objective value.

Single-Cut Aggregation

In the backward pass, each trial state is evaluated against all scenario realizations. The resulting per-scenario cuts are aggregated into one cut per trial point using probability-weighted expectation:

where is the probability of scenario (uniform for the fixed opening tree: ). The aggregated cut is added to stage ’s cut pool. This single-cut formulation keeps the LP compact: after iterations the LP has cuts, regardless of the number of scenarios per iteration.

The Forward-Backward Iteration

SDDP alternates between two passes:

  1. Forward pass: Simulate scenario paths from stage 1 to , solving each stage LP with the current cut approximation. This produces trial states and a statistical upper bound on optimal cost.

  2. Backward pass: Traverse from stage back to stage 1. At each stage, solve subproblems for all scenario realizations at each trial state, extract dual multipliers, aggregate them into new cuts, and add each cut to the stage’s cut pool. The first-stage objective (including ) provides a deterministic lower bound.

Cuts accumulate over iterations, progressively tightening toward the true . The algorithm converges when the gap between lower and upper bounds falls below a tolerance.

Why the LP Formulation Matters

The quality of Benders cuts depends directly on the LP formulation:

  • Recourse slacks (deficit, excess) guarantee feasibility for every scenario, ensuring duals always exist. Without relatively complete recourse, the backward pass would encounter infeasible subproblems.
  • Penalty magnitudes shape the value function. Correct priority ordering ensures that cuts propagate economically meaningful signals across stages.
  • State variable identification determines which dual multipliers contribute to cut coefficients. Every constraint linking the current stage to the incoming state produces a component of .
  • LP Formulation — complete stage subproblem: objective, constraints, penalties, and Benders cut interface
  • Cut Management — cut selection, deletion, and storage strategies
  • SDDP Theory — the iterative algorithm structure
  • Forward-Backward Pass — detailed mechanics of the forward simulation and backward cut generation passes

Further Reading

  • Pereira, M. V. F. and Pinto, L. M. V. G. (1991). “Multi-stage stochastic optimization applied to energy planning.” Mathematical Programming, 52(1-3), 359-375.
  • Benders, J. F. (1962). “Partitioning procedures for solving mixed-variables programming problems.” Numerische Mathematik, 4(1), 238-252.
  • Birge, J. R. and Louveaux, F. V. (2011). Introduction to Stochastic Programming. Springer, 2nd edition.
  • SDDP.jl documentation: https://sddp.dev/stable/
  • Cut Management (spec): ../specs/math/cut-management.md

Forward and Backward Passes

SDDP iterates between two complementary phases: a forward pass that simulates the system under the current policy, and a backward pass that improves the policy by generating new Benders cuts. This page summarizes how the two passes work together. For the complete specification, see SDDP Algorithm (spec).

Forward pass

The forward pass simulates the system from stage 1 to stage , producing trial points – the reservoir states that the backward pass will use to build cuts.

For each of independent trajectories:

  1. Start from the known initial state (reservoir volumes and inflow history).
  2. At each stage , sample an inflow scenario from the opening tree and solve the stage LP with the incoming state and the sampled scenario. The LP includes all Benders cuts accumulated so far, so the future cost variable reflects the best available approximation of costs from stage onward.
  3. Record the optimal outgoing state (end-of-stage storage volumes and updated autoregressive lags) as the trial point for stage .
  4. Pass as the incoming state to stage and repeat.

The forward pass also records each trajectory’s total cost, which feeds the statistical upper bound estimate (see Convergence).

Backward pass

The backward pass walks stages in reverse order, from down to 1, generating new cuts that tighten the future cost approximation.

At each stage , for each trial point collected during the forward pass:

  1. Solve the stage LP for every scenario in the opening tree, using as the incoming state. This is called backward branching: unlike the forward pass which samples one scenario per stage, the backward pass evaluates all of them.
  2. From each LP solution, extract the optimal objective value and the dual multipliers of the state-linking constraints (water balance, autoregressive lag fixing). These duals measure how sensitive the future cost is to small changes in the incoming state.
  3. Compute per-scenario cut coefficients from the duals and trial point.
  4. Aggregate the per-scenario coefficients into a single cut via probability-weighted averaging (the single-cut formulation).
  5. Add the new cut to stage ’s problem.

Each iteration adds one cut per stage per trial point, progressively tightening the piecewise-linear lower approximation of the true cost-to-go function.

How the passes work together

The two passes form a feedback loop:

  • The forward pass uses the current cut set to make decisions. Better cuts lead to better trial points.
  • The backward pass generates cuts at the states actually visited. More representative trial points lead to more useful cuts.

Over iterations, the cuts converge toward the true value function, and the forward pass policy converges toward the optimal dispatch schedule.

Parallelization

Both passes offer natural parallelism:

  • Forward pass: The trajectories are independent. Cobre distributes them across MPI ranks and OpenMP threads.
  • Backward pass: Within each stage, the branching solves across scenarios can run in parallel. However, there is a synchronization barrier at each stage boundary – all threads must finish generating cuts at stage before any thread moves to stage , because the newly generated cuts must be available when solving stage .

The forward pass LP solution at each stage also provides a warm-start basis for the corresponding backward pass solves, significantly reducing solver time.

For the full specification of the forward and backward pass mechanics, including scenario sampling schemes, feasibility guarantees, and the thread-trajectory affinity model, see SDDP Algorithm (spec).


See also: For implementation details and usage, see the SDDP crate documentation in the software book.

Convergence

SDDP is an iterative algorithm, so it needs well-defined criteria for when to stop. This page explains how convergence is monitored through bounds, what the five available stopping rules are and how their formulas work, and how to obtain a deterministic upper bound independent of the risk measure.

Lower Bound

The first-stage LP objective — immediate cost plus the cut-based approximation of future cost — provides a deterministic lower bound at iteration :

Because each iteration adds new cuts that can only tighten the approximation, the lower bound increases monotonically. It never decreases, making it a reliable progress indicator.

Statistical Upper Bound

The average total cost across all forward pass trajectories provides a statistical upper bound :

This is a Monte Carlo estimate of the true policy cost, so it carries sampling noise. It is typically reported with a confidence interval based on the sample standard deviation across trajectories.

For risk-averse problems (e.g., CVaR objectives), the statistical upper bound is not valid in the classical sense — the sample average is not a valid upper bound on a risk measure. In such cases, the deterministic upper bound described below is necessary.

Deterministic Upper Bound via Inner Approximation

For a convergence certificate valid under any risk measure, Cobre supports a deterministic upper bound through inner approximation (SIDP). The idea is to build a concave piecewise-linear overestimate of the value function from the inside, complementing the convex piecewise-linear underestimate built by cuts from the outside.

The inner approximation stores vertices — visited state-value pairs collected during forward passes. At any query state , the upper bound is interpolated via the Lipschitz condition:

where is the Lipschitz constant for stage , computed backward from the maximum penalty coefficient:

This formula uses the largest penalty cost (the dominant term in the objective) as a bound on how fast the value function can change per unit change in state. The upper bound at stage 1 then gives:

As iterations proceed, more vertices are collected and the inner approximation tightens. Both bounds converge to the same value, and the gap goes to zero.

Optimality Gap

The gap between the bounds measures how far the current policy may be from optimal:

A small gap means the cut approximation is close to the true value function and the policy is near-optimal. In practice, the gap is monitored over iterations and used by the stopping rules described below.

Stopping Rules

Cobre supports five stopping criteria, evaluated at the end of each iteration. Multiple rules can be combined with OR logic (stop when any rule triggers) or AND logic (stop when all rules trigger simultaneously).

Iteration Limit

A hard cap on the number of iterations. This rule must always be present as a safety bound:

Time Limit

A wall-clock time budget. Checked at the end of each iteration:

Bound Stalling

Detects when the lower bound has plateaued. The rule computes the relative improvement of over a sliding window of iterations:

If falls below the tolerance, further iterations are unlikely to improve the policy significantly.

Gap Convergence

Stops when the optimality gap falls below a threshold:

Requires an upper bound to be available (statistical or deterministic).

The most robust criterion combines bound stability with policy stability. Periodically (e.g., every 20 iterations), the rule:

  1. Checks bound stability:

  2. If stable, runs a batch of Monte Carlo simulations and computes the normalized distance between the per-stage cost profiles of consecutive simulation batches:

  3. Stops when both converge:

This avoids premature termination from statistical noise and ensures the policy is genuinely stable, not just the bound.

Termination Output

When the algorithm stops, the output reports which rule triggered, the final iteration count, the lower and upper bounds, and the optimality gap. This information supports post-hoc analysis of whether the policy is sufficiently converged or whether additional iterations would be beneficial.

Stopping Rules

Overview

SDDP is an iterative algorithm with no fixed termination point: it can always run another iteration and tighten the future cost approximation. Stopping rules provide the criteria for deciding when the current policy is good enough to stop.

Good stopping criteria balance two risks. Stopping too early leaves a suboptimal policy; stopping too late wastes computation on marginal improvements. Because the lower bound and the upper bound (statistical or deterministic) approach the true optimum from opposite sides, monitoring both gives a robust termination signal.

The Five Available Rules

Cobre provides five stopping criteria. Multiple rules can be combined: "any" mode (default) stops when the first rule triggers; "all" mode requires every rule to trigger simultaneously.

1. Iteration Limit (Mandatory)

A hard cap on the number of iterations:

where is the current iteration count and is the configured limit.

This rule must always be present. It acts as a safety bound preventing runaway computation if other rules fail to trigger. For production studies, is typically set high enough that convergence rules trigger first, but not so high that a non-converging run consumes unbounded resources.

2. Time Limit

A wall-clock budget:

Checked at the end of each iteration. Useful in operational contexts where results must be available within a fixed window, regardless of convergence status.

3. Bound Stalling

Detects when the lower bound has plateaued — the outer approximation is no longer improving despite additional iterations. The rule computes the relative improvement of the deterministic lower bound over a sliding window of iterations:

where is the relative tolerance (typically 0.01%). The window size controls sensitivity: a small window detects stalling faster but is more susceptible to transient plateaus; a larger window is more robust.

The intuition: if the LP approximation of future costs has not improved appreciably over the last iterations, the current cuts already provide a tight lower bound and further iteration is unlikely to change the dispatch policy.

4. Gap Convergence

When both a lower bound and an upper bound are available, their gap directly measures how far the current policy may be from optimal:

The upper bound can be the Monte Carlo average of forward pass costs (statistical, valid for risk-neutral problems) or the inner approximation via Lipschitz interpolation (deterministic, valid for all risk measures). A tight gap provides a verifiable certificate of near-optimality.

The most robust criterion combines two convergence indicators: stability of the outer approximation (bound) and stability of the policy itself (simulated cost profile). The rule executes in two steps, checked every period iterations:

Step 1 — Bound stability check:

where is the bound window (number of past iterations to compare against).

Step 2 — Policy stability check (only if bound is stable): Run replications Monte Carlo forward simulations under the current policy. Compute the mean per-stage cost across replications and compare to the previous simulation batch:

Stopping condition:

This criterion requires both the bound and the simulated policy costs to have converged. The two-step design avoids premature termination: a temporarily stable bound might coincide with a policy that still changes significantly across iterations, and vice versa.

Why this rule is recommended: The bound monitors convergence of the mathematical approximation; the simulation monitors convergence of the economic dispatch decisions. Requiring both to stabilize ensures the solution is practically meaningful, not just numerically tight.

Combining Rules

A typical conservative setup uses an iteration limit as a hard cap with simulation-based stopping as the primary convergence criterion:

  • Iteration limit: 500 (hard safety cap)
  • Simulation-based stopping: every 20 iterations, 100 replications, 1% policy tolerance
  • Mode: "any" (stop when either triggers)

The iteration limit ensures termination even if the simulation criterion never triggers (e.g., due to high variance). In practice, well-tuned simulation criteria typically trigger well before the iteration limit.

Termination Output

When any stopping rule triggers, the solver records which rule terminated the run, the final iteration count, the lower bound, the upper bound (if evaluated), and the optimality gap. This information is important for post-hoc analysis: a run terminated by the iteration limit before the simulation criterion converged may warrant rerunning with a higher limit.

Further Reading

Stage Subproblem LP Formulation

Overview

At each stage of the SDDP algorithm, the dispatcher solves a linear program (LP) that models the power system for that time period. This LP is the fundamental computational unit of the solver: the forward pass executes it once per stage to simulate the policy, and the backward pass executes it once per stage per scenario to generate Benders cuts.

Understanding the LP structure is important because it directly shapes the quality of the cuts and the economic signals propagated across stages. A well-structured LP ensures that cuts carry meaningful marginal water values and that every scenario is feasible.

Cost and Penalty Taxonomy

The objective function combines four types of costs. The distinction matters because each type serves a different algorithmic role.

Resource Costs

Resource costs represent actual operating expenditures with economic meaning:

CostSymbolUnitsRole
Thermal generation$/MWhFuel cost, typically 50–500
Contract dispatch$/MWhPositive for imports, negative for exports

Category 1: Recourse Slacks

These penalty terms guarantee that every LP is feasible regardless of the inflow scenario. Without them, the backward pass could encounter infeasible subproblems, making cut generation impossible.

PenaltySymbolUnitsPurpose
Load deficit$/MWhUnserved energy (piecewise, 1,000–10,000)
Excess generation$/MWhAbsorbs uncontrollable surplus (0.001–0.1)

Category 2: Constraint Violation Penalties

These provide soft enforcement of physical constraints that may be impossible to satisfy under extreme conditions. They must be high enough to propagate penalty signals into the future cost function and influence reservoir decisions multiple stages ahead.

PenaltySymbolViolated Constraint
Storage below minimum
Filling target shortfall (terminal)
Turbined flow minimum
Outflow minimum/maximum
Generation minimum

Category 3: Regularization Costs

Very small costs (2–3 orders of magnitude below economic costs) that break degeneracy and guide the solver toward physically preferred solutions when the LP is otherwise indifferent:

CostSymbolPurpose
SpillagePrefer turbining over spilling
FPHA turbined flowPrevent degenerate FPHA solutions
ExchangePrevent unnecessary power flows

Priority Ordering

The ordering must be maintained to ensure correct economic signals:

Filling a dead reservoir (dam safety) has the highest priority; load shedding ranks above generation costs; regularization terms are negligible compared to any economic quantity.

The Stage Subproblem LP

The complete objective minimizes total cost over all load blocks :

Storage violation penalties (, ) appear outside the block sum because they apply to end-of-stage storage (hm³), not per-block flow rates.

Key Constraint Families

Load Balance

For each bus and block , supply must meet demand. Hydro generation, thermal dispatch, imports, and transmission flows contribute to supply; deficit and excess slack variables ensure feasibility:

Hydro Water Balance

End-of-stage storage equals incoming storage plus net inflows and minus all outflows, scaled by the time conversion factor :

where is the incremental inflow from the PAR(p) model and is the incoming storage.

State-Fixing Constraints and the Benders Interface

A critical design choice is the introduction of explicit incoming-state LP variables and , each fixed to the trial value via an equality constraint:

The dual of each fixing constraint is the cut coefficient for that state dimension. This “fishing constraint” technique collects all sensitivity information into a single dual value per state variable — the LP solver automatically propagates contributions from all downstream constraints (water balance, FPHA, generic constraints) through the incoming-state variable. The result appears in the stage LP as:

where is the dual of the storage fixing constraint and is the dual of the lag fixing constraint. Each new Benders cut is derived from these duals after each backward-pass solve.

Hydro Production Models

Two production models are available during training:

Constant productivity: A linear equality linking generation to turbined flow:

where (MW per m³/s) depends on turbine efficiency and reference head. Simple and fast.

FPHA (piecewise-linear): A set of linear hyperplanes forming a concave upper bound on generation as a function of storage and flow:

where is average stage storage. FPHA captures head variation and the effect of spillage on tailrace level, at the cost of more constraints per hydro.

Further Reading

Hydro Production Models

Overview

The amount of electrical power a hydroelectric plant produces depends on two physical quantities: how much water flows through the turbines and the pressure difference (net head) driving that flow. Net head is the difference between the upstream reservoir level and the downstream tailrace level, minus hydraulic losses in the penstock.

This nonlinear relationship creates a modeling challenge for LP-based optimization: the exact production function is a bilinear function of storage and flow, incompatible with linear programming. Cobre uses two linearization strategies during training (policy construction) that preserve LP tractability while capturing different levels of head-variation accuracy.

Constant Productivity Model

The simplest model assumes productivity is constant — independent of how full the reservoir is. Generation is a linear function of turbined flow:

where is the productivity coefficient (MW per m³/s), computed from the turbine efficiency and a reference net head:

with the turbine-generator efficiency (typically 0.85–0.92) and the net head at a representative operating point (typically 65% full storage).

This is an equality constraint: for each hydro and each load block , generation is fully determined by turbined flow. The LP does not treat generation as a free variable — it is substituted out. The simplicity makes this model fast and numerically well-conditioned, which is valuable for long planning horizons where head variation is secondary to reservoir management.

When to use: Run-of-river plants, far-future stages, and initial algorithm development where computational speed matters more than fine-grained head variation.

FPHA: Piecewise-Linear Head Approximation

The exact hydroelectric production function is:

where the net head captures the full hydraulic chain:

  • : forebay (reservoir surface) level, a nonlinear function of storage
  • : tailrace level, a function of total outflow
  • : hydraulic losses in the penstock and turbines

Because is a product of and , it is nonlinear in the LP variables. FPHA (Função de Produção Hidrelétrica Aproximada) replaces this nonlinear surface with a concave piecewise-linear envelope: a set of hyperplanes that together bound generation from above everywhere in the operating region:

where is the average storage over the stage.

Physical Meaning of Coefficients

Each hyperplane coefficient has a clear hydraulic interpretation:

CoefficientSignInterpretation
Generation at zero storage and zero flow
Higher reservoir level raises forebay, increasing net head
More turbined flow produces more power
More spillage raises tailrace, reducing net head

The negative sign on reflects a real hydraulic effect: water released as spillage raises the downstream level, which partially cancels the head driving power generation. In systems with strong tailrace backwater effects, this is an important operational consideration.

Concave Envelope and Conservative Bias

The LP optimizer maximizes hydro generation subject to the FPHA constraints (since hydro has zero fuel cost). At the optimum, generation lies on one of the hyperplane faces. Because the envelope is a concave upper bound on the exact nonlinear surface, the FPHA model may overestimate generation compared to the physical plant.

To prevent this, a correction factor scales the hyperplane intercepts:

The default approach sets as the worst-case ratio between the exact production function and the FPHA approximation across the operating grid, guaranteeing that FPHA never overestimates. For plants with modest head variation, typical values are .

Impact on Water Values

Because the average storage appears in the FPHA constraint, the incoming storage variable is linked to the generation upper bound. The dual of the incoming storage fixing constraint therefore captures both the water balance sensitivity and the FPHA generation sensitivity — all through a single LP variable. This is what makes the “fishing constraint” technique (see LP Formulation) particularly powerful: the FPHA contribution to cut coefficients is automatic.

FPHA vs. Constant Productivity: Trade-offs

CriterionConstant ProductivityFPHA
LP constraints per hydro1 equality per block inequalities per block
Head variation capturedNoYes
Data requiredProductivity coefficientTopology functions + hyperplanes
Training speedFastSlower (more constraints)
Cut qualityConservativeMore accurate water values

In practice, many systems use FPHA for near-term stages (where head variation significantly affects near-term dispatch) and constant productivity for far-future stages (where approximation accuracy matters less than speed).

Further Reading

  • LP Formulation — how production constraints fit into the assembled stage LP
  • Benders Decomposition — how FPHA affects cut coefficient computation
  • Hydro Production Models (spec) — complete formal specification including topology function interpolation, correction factor computation methods, and the simulation-only linearized head model

Stochastic Modeling

Why Inflows Are Uncertain

Hydrothermal dispatch optimizes the operation of interconnected hydroelectric and thermal power plants over a multi-year horizon. The dominant source of uncertainty is river inflow – the volume of water arriving at each reservoir in each time period. Inflows depend on rainfall, snowmelt, and upstream conditions that cannot be predicted with precision months or years ahead. Because water stored today displaces expensive thermal generation tomorrow (and vice versa), the dispatch decision at every stage depends critically on the distribution of future inflows, not just a single forecast.

Role of Autoregressive Models

SDDP requires a probabilistic model of inflows that captures two key properties:

  1. Seasonal patterns: Inflows are strongly periodic – wet and dry seasons drive large swings in mean and variance across the year.
  2. Temporal correlation: A wet month is more likely to be followed by another wet month than by a dry one. Ignoring this correlation would underestimate hydrological risk.

The Periodic Autoregressive model of order p (PAR(p)) addresses both properties. It fits separate autoregressive parameters for each season (month or week), allowing the mean, variance, and lag structure to vary across the hydrological cycle. At each stage, the model expresses the current inflow as a linear function of recent past inflows plus a random innovation term:

The lagged inflows become state variables in the SDDP subproblem, linking stages through the Bellman recursion.

Spatial Correlation

In systems with many river basins, inflows at different plants are correlated – a drought typically affects an entire region, not a single plant. Cobre handles spatial correlation by sampling the innovation vector from a multivariate distribution that preserves the observed cross-plant correlation structure. The PAR(p) model captures temporal dependence per plant, while the joint sampling of innovations captures spatial dependence across plants. See Spatial Correlation for details on the correlation modeling approach.

Integration with SDDP

During the forward pass, inflow scenarios are sampled from the PAR(p) model (or from external scenario files). During the backward pass, the opening tree of inflow realizations at each stage is generated from the same model, ensuring consistency between the policy being evaluated and the uncertainty it was trained against. When external scenarios are provided for training, a PAR(p) model is fitted to those scenarios so that the backward pass opening tree remains well-defined.

Further Reading


See also: For implementation details and usage, see the Stochastic Modeling guide in the software book.

PAR(p) Autoregressive Models

What Is a PAR(p) Model?

A Periodic Autoregressive model of order p (PAR(p)) is a time series model designed for data with strong seasonal patterns. It extends the classical autoregressive (AR) model by allowing every parameter to vary by season — the coefficients that govern January inflows are different from those that govern July inflows.

The “order p” indicates how many past time steps the model looks back. A PAR(3) model for a given month predicts the current inflow using the inflows from the previous three months. The order can differ by season: January might need only one lag while April might need four, reflecting different hydrological dynamics across the year.

The PAR(p) Equation

For hydro plant at stage falling in season , the PAR(p) model is:

In words: the inflow at stage equals the seasonal mean, plus a weighted combination of how much recent inflows deviated from their seasonal means, plus a random shock.

Parameters by Season

Each season has its own set of parameters:

ParameterSymbolRole
Seasonal meanExpected inflow for season
AR coefficientsWeights on past deviations from the mean
Residual stdScale of the random innovation
InnovationStandardized random shock

The seasonal mean and sample standard deviation are estimated from historical data. The AR coefficients are fitted using the Yule-Walker equations (see below). The residual standard deviation is derived at runtime from the other parameters (it is not stored independently).

How Lags Become State Variables

In the SDDP framework, decisions at each stage depend on a set of state variables that summarize everything the optimizer needs to know from the past. For the PAR(p) model, the state variables are the lagged inflows:

where is the reservoir volume and are the lagged inflows needed by the autoregressive equation. Each lag adds one state variable per hydro plant to the SDDP subproblem.

This is significant for problem size: a system with 150 hydro plants and a maximum PAR order of 6 adds up to state variables beyond the reservoir volumes. The LP formulation includes constraints that “shift” lagged inflows forward from one stage to the next, ensuring the autoregressive structure is respected across the Bellman recursion.

Stored vs. Computed Quantities

Cobre stores the natural outputs of the fitting process:

  • Stored: seasonal means (), seasonal sample standard deviations (), AR order (), and AR coefficients in original units ()
  • Computed at runtime: the residual standard deviation , derived from the stored quantities to guarantee consistency

This design avoids redundancy — is fully determined by the other parameters and recomputing it is inexpensive.

Yule-Walker Fitting Procedure

When fitting PAR(p) parameters from historical inflow data, the AR coefficients are estimated by solving the Yule-Walker equations — a linear system that relates the autocorrelations of the data to the model coefficients. The procedure has five steps.

Step 1 — Seasonal Statistics

For each season , compute the sample mean and standard deviation from historical observations :

where is the number of historical observations for season .

Step 2 — Seasonal Autocorrelations

Compute the cross-seasonal autocorrelation at lag for season . The cross-seasonal structure arises because lag at season reaches back to season (cyclically):

Note that is the standard deviation of season , not of season . This is the defining feature of a periodic (as opposed to stationary) autoregressive model.

Step 3 — Yule-Walker System

For each season , the coefficients in standardized form satisfy:

where:

The solution is:

The matrix is not a standard Toeplitz matrix (because consecutive rows use different seasons’ correlations), but it has a similar structure. The correlation matrix must be positive definite for the solution to exist; if not, the historical record may be too short for the requested order.

Step 4 — Residual Standard Deviation

After solving the Yule-Walker system, the residual standard deviation for season is:

This equals times the square root of the unexplained variance fraction. If , the model overfits — it explains all historical variance, leaving no room for the noise term.

Step 5 — Convert to Original Units

The Yule-Walker solution yields coefficients in standardized form (dimensionless, relating standardized deviations). The LP requires original-unit coefficients:

These are computed once at initialization and used directly as LP constraint matrix entries.

Key Properties

  • Periodicity: All parameters vary by season, matching the strong seasonality of hydrological data.
  • Parsimony: The model order is selected per season using AIC, BIC, or coefficient significance tests, avoiding unnecessary lags.
  • Stationarity: Fitted models are validated to ensure the AR process does not diverge — the characteristic polynomial roots must lie outside the unit circle.
  • Positive residual variance: After fitting, must hold for all seasons. A zero or negative residual variance indicates overfitting.

Further Reading


See also: For implementation details and usage, see the Stochastic Modeling guide in the software book.

Inflow Non-Negativity

Overview

The PAR(p) autoregressive model generates inflow realizations by adding a random innovation to a weighted combination of past inflows. Because the innovation term can be arbitrarily negative in the Gaussian model, the total inflow can sometimes be negative — which is physically impossible. Negative inflows would cause the water balance to add water to the reservoir rather than drain it, producing absurd dispatch decisions.

Handling this situation correctly is important for both LP feasibility and for maintaining the statistical properties of the inflow model. Three strategies are available, with different trade-offs between model fidelity, LP complexity, and computational cost.

How Negative Inflows Arise

The PAR(p) model at stage for hydro generates:

When the noise realization is sufficiently negative (e.g., ), the total can become negative. For systems with low seasonal mean flows and high variability, this can occur with non-negligible probability in dry seasons.

If enters the water balance constraint uncorrected, the LP solver treats it as a negative inflow (water added to the river system), which has no physical meaning and will cause the optimizer to mismanage reservoir storage.

The recommended approach introduces a non-negative slack variable that absorbs any negative inflow, keeping the effective inflow non-negative while preserving the LP formulation and the AR model structure for positive realizations.

Modified AR constraint:

with . When is mild, the optimizer sets and takes its natural value. When is extreme, absorbs the excess, so the effective inflow:

The violation is penalized in the objective outside the block summation:

where is the total stage duration in hours. The factor converts the slack rate (m³/s) to an equivalent energy dimension over the full stage, making the penalty dimensionally consistent with storage violation penalties that appear in the same part of the objective.

The penalty is a Category 2 constraint violation penalty — it sits above generation costs in the penalty hierarchy, ensuring the optimizer “pays” for negative inflow events in the value function and propagates this signal back through the Benders cuts.

Properties

  • LP always feasible: the slack prevents infeasibility for any noise realization
  • AR dynamics preserved for positive realizations: when , the model is unchanged
  • Clear cost signal: the penalty magnitude tracks how frequently and severely the threshold is violated

Truncation (Simple Alternative)

The simplest method truncates negative inflows to zero before they enter the LP:

No additional LP variables or constraints are needed. However, truncation has two statistical drawbacks: it shifts the mean inflow upward (positive bias) and disrupts temporal correlation at truncation events, because the extreme noise that triggered truncation is discarded rather than tracked.

For quick studies or debugging, truncation is acceptable. For production use, the bias can distort long-run cost estimates in drought scenarios.

Deferred: Truncation with Penalty

A more sophisticated hybrid approach (deferred to post-v0.1.0) combines truncation with explicit noise adjustment tracking. It introduces a dimensionless slack that adjusts the noise term rather than the inflow directly:

The penalty is proportional to the actual inflow correction , which is larger in high-variability seasons. This approach preserves AR model structure better than pure truncation and provides a more precise signal of how much the noise realization was adjusted. It is deferred because the interaction with the noise generation pipeline adds complexity that is not needed for the minimal viable solver.

Summary

MethodLP SizeBiasAR PreservationRecommended
No handlingBaseNoneFullDebugging only
Penalty+1 var/constraint per hydroMinimalFullProduction
TruncationBaseUpwardPartialQuick studies
Truncation with penalty+varsMinimalFullPost-v0.1.0

Further Reading

Spatial Correlation

Hydro plants in the same river basin or geographic region tend to experience similar hydrological conditions – when one plant receives high inflows, nearby plants often do too. Capturing this spatial correlation is essential for realistic scenario generation. This page summarizes how Cobre handles it. For the full autoregressive model specification, see PAR Inflow Model (spec).

Temporal correlation: the PAR(p) model

Each hydro plant’s inflow series is modeled independently by a Periodic Autoregressive model of order (PAR(p)). This model captures temporal correlation – the tendency for high-inflow months to follow high-inflow months – through autoregressive coefficients that link the current inflow to past values:

The parameters (seasonal means , AR coefficients , residual standard deviations ) vary by season, reflecting the strong seasonality of hydrological processes.

Spatial correlation: correlated noise terms

The PAR(p) model for each plant produces a residual (innovation term) that represents the unexplained randomness after accounting for the autoregressive structure. Spatial correlation is introduced by making these residuals correlated across plants.

Instead of drawing independent noise for each plant, the scenario generator samples a vector of correlated noise terms. Plants in the same river basin share a large portion of their randomness, while plants in distant basins are less correlated. The correlation structure is typically estimated from the historical residuals of the fitted PAR(p) models.

Effect on scenario generation

Correlated noise means that the scenarios used in the forward and backward passes reflect realistic joint behavior across plants:

  • In a wet scenario, most plants in a basin receive above-average inflows simultaneously, leading to system-wide surplus.
  • In a dry scenario, most plants are deficient together, stressing the thermal fleet.

Without spatial correlation, the scenario generator would produce unrealistic combinations – some plants wet while their upstream neighbors are dry – leading to policies that underestimate system-level risk.

Implementation notes

The spatial correlation structure is encoded in the noise vectors stored in the opening tree. Each noise vector contains entries for all hydro plants, and the cross-plant correlations are baked into the vector generation process. The PAR(p) model then transforms these correlated noise vectors into inflow realizations that respect both the temporal dynamics (autoregressive lags) and the spatial structure (correlated residuals).

  • PAR Inflow Model (spec) – Full specification of the autoregressive model, fitting procedure, and validation
  • Scenario Generation – How scenarios incorporating spatial correlation are used in the SDDP passes
  • SDDP Theory – The broader algorithmic context in which inflow modeling operates

Scenario Generation

SDDP requires scenarios – discrete realizations of uncertain quantities (primarily inflows) – at multiple points in the algorithm. This page provides an overview of how scenarios are generated and used. For the underlying stochastic model, see PAR Inflow Model (spec). For the forward/backward pass mechanics that consume these scenarios, see SDDP Algorithm (spec).

The opening tree

Before the SDDP iteration loop begins, Cobre generates a fixed opening tree: a set of pre-sampled noise vectors for each stage. Each noise vector contains correlated random draws for all hydro plants, reflecting the spatial correlation structure estimated from historical data (see Spatial Correlation).

The opening tree is generated once and remains fixed throughout training. This ensures that every iteration’s backward pass evaluates the same set of realizations, which is important for cut validity – cuts are valid lower bounds on the expected cost-to-go computed over a specific discrete distribution.

The number of openings per stage is a key configuration parameter. More openings give a finer approximation of the continuous inflow distribution but increase the computational cost of each backward pass proportionally.

Forward pass sampling

During the forward pass, each trajectory needs one scenario realization per stage. The default scheme (InSample) draws uniformly at random from the opening tree – the same set used by the backward pass. This means the forward pass explores states that are consistent with the distribution the cuts were built for.

Alternative sampling schemes are available:

  • External: Draws from user-provided scenario data, allowing the forward pass to explore states driven by historical or synthetically generated inflow sequences.
  • Historical: Uses actual historical inflow records as forward pass scenarios, useful for validating the policy against observed conditions.

Regardless of the sampling scheme, the backward pass always uses the complete opening tree.

Backward pass branching

The backward pass evaluates all openings in the tree at each visited trial point. This complete enumeration is what makes the resulting Benders cut a valid expected-value inequality: the cut coefficients are computed as probability-weighted averages over the full discrete distribution.

For each trial point at stage :

  1. Solve the stage LP once per opening , using as the incoming state and as the inflow realization.
  2. Extract dual multipliers and objective values from each solve.
  3. Aggregate into a single cut (probability-weighted average of per-scenario coefficients).

The uniform probability applies when all openings are equally likely, which is the default.

From noise to inflows

The opening tree stores noise vectors (standardized innovations), not inflows directly. At each stage, the PAR(p) model transforms these noise vectors into physical inflow values using the autoregressive equation:

where is the noise draw from the opening tree. The deterministic base and lag contribution depend on the incoming state (autoregressive lags), so the same noise vector produces different inflows depending on the system’s history. This is how the Markov property is maintained – the state carries enough information to reconstruct the inflow dynamics.

Scenario count and computational cost

The number of openings directly affects the backward pass cost: each backward stage solve requires LP solves per trial point. Typical configurations use 20 to 200 openings per stage, balancing approximation quality against runtime.

The forward pass cost is independent of the opening count – each trajectory samples exactly one realization per stage.

Cut Management

Cut management controls the lifecycle of Benders cuts in the SDDP algorithm: how cuts are generated, aggregated, stored, and selectively pruned. Effective cut management is essential for solver performance – without it, the number of constraints in each stage LP grows unboundedly, slowing every forward and backward pass solve.

What is a Benders cut?

A Benders cut is a linear inequality added to a stage’s LP that approximates the cost of future decisions. Each cut encodes information learned during a backward pass solve: how sensitive the total future cost is to changes in reservoir storage volumes and inflow history at that stage.

Mathematically, a cut takes the form:

where is the future cost variable, is the intercept, captures the marginal value of water in reservoir , and captures the marginal value of inflow history. The collection of all cuts at a stage forms a piecewise-linear lower approximation of the true future cost function.

How cuts are generated

During the backward pass, the algorithm solves each stage’s LP at trial states collected in the forward pass, for every scenario in the opening tree. The LP dual variables (shadow prices) from the water balance and AR lag-fixing constraints provide the cut coefficients. The intercept is computed so that the cut passes exactly through the trial point.

Because multiple scenarios are evaluated, the per-scenario coefficients are aggregated into a single cut per trial point using probability-weighted averaging. This is the single-cut formulation used by Cobre.

Why cut management matters

Each SDDP iteration adds new cuts, so after hundreds of iterations the cut pool can contain thousands of constraints per stage. Most older cuts become redundant as newer, tighter cuts supersede them. Without pruning:

  • LP solve time increases linearly with the number of active cuts
  • Memory consumption grows proportionally
  • Numerical conditioning degrades as near-parallel cuts accumulate

Cut selection strategies identify and deactivate redundant cuts, keeping the LP compact while preserving the quality of the future cost approximation. The available strategies (Level-1, LML1, dominated cut detection) offer different trade-offs between aggressiveness and safety. See Cut Selection for a summary of each strategy.

Importantly, deactivated cuts are not deleted from memory – they are relaxed to so their indices remain stable. This preserves reproducibility across checkpoint/resume cycles and allows reactivation if needed.

Further reading

Single-Cut vs Multi-Cut

In SDDP, the backward pass evaluates multiple inflow scenarios at each trial state and must combine the resulting information into cuts for the previous stage. There are two approaches: the single-cut formulation (used by Cobre) and the multi-cut formulation (deferred to a future release).

Single-cut formulation

The single-cut approach aggregates per-scenario cut coefficients into one cut per trial point by computing the probability-weighted average:

This produces a single constraint added to the stage LP:

Advantages:

  • Each iteration adds exactly one cut per stage per trial point, keeping the LP small
  • LP solve times remain fast, especially important for systems with many stages
  • Simpler implementation and lower memory footprint

Trade-off:

  • Each cut carries averaged information, so more iterations may be needed to achieve the same approximation quality

Multi-cut formulation

The multi-cut approach keeps one cut per scenario, introducing scenario-specific future cost variables :

with the linking constraint .

Advantages:

  • Preserves more information per iteration – each scenario’s sensitivity is represented individually
  • Can converge in fewer iterations for problems with high scenario variability

Trade-off:

  • Each iteration adds cuts per stage per trial point, leading to larger LPs
  • LP solve time per iteration is higher

Which does Cobre use?

Cobre implements the single-cut formulation. For the system sizes typical of Brazilian hydrothermal dispatch (160+ hydro plants, hundreds of scenarios), the single-cut approach provides the best balance between iteration count and per-iteration solve time.

The multi-cut formulation is planned for a future release. See Deferred Features for status.

Further reading

Cut Selection

As SDDP iterates, the number of Benders cuts grows with each backward pass. Many older cuts become redundant once newer, tighter cuts are generated at nearby states. Cut selection strategies identify and deactivate these redundant cuts, keeping the stage LPs compact without sacrificing approximation quality.

Cobre supports three selection strategies, listed from least to most aggressive.

Cut activity

All three strategies rely on the concept of cut activity. A cut is active at a given state if it is binding (or nearly binding) at the LP optimum – meaning it is actually shaping the future cost approximation at that point. Inactive cuts sit below the current approximation surface and contribute nothing to the solution.

Activity is determined by checking whether the gap between the future cost variable and the cut’s value is below a configurable threshold :

A threshold of zero means only strictly binding cuts count; a small positive value (e.g., 1e-6) accounts for numerical tolerance.

Level-1

The simplest strategy. A cut is retained if it was active at least once during the entire algorithm execution. Periodically, cuts that have never been active are deactivated.

  • Retention policy: ever-active
  • Aggressiveness: low – keeps cuts that were useful at any point in training
  • Risk: may retain cuts that were active early but are now permanently dominated by newer cuts

Limited Memory Level-1 (LML1)

A refinement of Level-1 that adds a time horizon. Each cut is timestamped with the most recent iteration at which it was active. Cuts whose timestamp is older than a configurable memory window (in iterations) are deactivated.

  • Retention policy: active within the last iterations
  • Aggressiveness: moderate – controlled by the window size
  • Risk: a very small window may prematurely remove cuts that are infrequently but meaningfully active

Dominated cut detection

The most aggressive strategy. A cut is dominated if, at every visited state, some other cut in the pool achieves an equal or higher value. Dominated cuts provide no value at any known operating point and can be safely deactivated.

Since verifying domination over the entire state space is intractable, Cobre checks domination only at the states visited during recent forward passes. As the set of visited states grows denser over iterations, the domination check becomes more reliable.

  • Retention policy: not dominated at any visited state
  • Aggressiveness: high – directly targets cuts that contribute nothing
  • Cost: per stage per check

Convergence guarantees

Level-1 and LML1 both preserve the finite convergence guarantee of SDDP: removing cuts that are never active at visited states does not affect the outer approximation quality at those states. This result is established in Bandarra and Guigues (2021).

Configuration

Cut selection is controlled by four parameters: the strategy (level1, lml1, or domination), the activity threshold, the frequency of selection checks (in iterations), and the memory window (for LML1). See Cut Management (spec) – section 9 for the parameter table.

Further reading

  • Cut Management (spec) – formal definitions of cut activity, all three selection strategies, convergence theorem, and configuration parameters
  • Cut Management – overview of the full cut lifecycle
  • Convergence – how cut quality affects stopping criteria and bound computation

Risk Measures

Why risk matters in power system planning

Standard SDDP minimizes the expected total cost across all scenarios. This produces policies that perform well on average but can lead to extremely high costs in adverse scenarios – for example, a prolonged drought that depletes reservoirs and forces expensive thermal generation or load shedding.

Risk-averse SDDP addresses this by incorporating a risk measure into the optimization objective. Instead of minimizing only the average cost, the algorithm also penalizes outcomes in the tail of the cost distribution. The result is a policy that sacrifices a small amount of average-case performance for substantially better worst-case behavior.

Risk-neutral vs risk-averse

In risk-neutral SDDP, each backward pass aggregates per-scenario cut coefficients using the scenario probabilities . All scenarios contribute equally (weighted by probability) to the cut that approximates the future cost function.

In risk-averse SDDP, the scenario probabilities are replaced by risk-adjusted weights that place more emphasis on expensive (adverse) scenarios. The cut generation mechanics are otherwise identical – only the aggregation weights change.

The convex combination risk measure

Cobre uses a convex combination of expectation and Conditional Value-at-Risk (CVaR):

This formulation has two parameters:

  • (risk aversion weight): Controls the blend between expected value and CVaR. Setting recovers risk-neutral SDDP; setting uses pure CVaR.
  • (confidence level): Controls how deep into the tail CVaR looks. Smaller means focusing on more extreme adverse scenarios.

Both parameters can vary by stage, allowing operators to apply stronger risk aversion to near-term decisions (where consequences are immediate) and weaker risk aversion to distant stages.

Implications for convergence monitoring

A critical subtlety of risk-averse SDDP is that the first-stage LP objective is not a valid lower bound on the true risk-averse optimal cost. It remains a useful convergence indicator (it increases monotonically and plateaus), but it cannot be interpreted as a bound in the same way as in risk-neutral SDDP. Valid upper bounds require the inner approximation (SIDP) method.

Further reading

  • CVaR – Intuitive explanation of Conditional Value-at-Risk
  • Risk Measures (spec) – Complete formal specification: dual representations, subgradient theorem, risk-averse Bellman equation, cut generation algorithm, and lower bound validity warning
  • Cut Management – How risk-adjusted weights integrate into cut aggregation
  • Convergence – Bound computation and stopping criteria

Conditional Value at Risk (CVaR)

What is CVaR?

Conditional Value-at-Risk (CVaR) is a risk measure that captures the expected cost in the worst-case tail of a probability distribution. While the ordinary expected value averages over all outcomes equally, CVaR focuses on the most adverse fraction.

Formally, for a random cost and a confidence level :

The parameter determines how deep into the tail the measure looks. Smaller means a more pessimistic assessment.

Intuitive interpretation

Imagine sorting all possible cost outcomes from lowest to highest. CVaR is the average cost among the worst -fraction of those outcomes.

  • : The “worst 100%” is the entire distribution, so CVaR equals the ordinary expected value .
  • : The average cost of the worst half of outcomes.
  • : The average cost of the worst 5% of outcomes – a strongly pessimistic measure.

Relationship to VaR

Value-at-Risk (VaR) is the threshold below which the worst -fraction of outcomes falls. CVaR goes further: it averages all costs beyond that threshold. This makes CVaR strictly more conservative than VaR and, unlike VaR, it is a coherent risk measure (satisfying monotonicity, translation equivariance, positive homogeneity, and subadditivity).

Why CVaR for hydrothermal dispatch?

In hydrothermal systems, the primary source of uncertainty is river inflows. A sequence of dry years can deplete reservoirs and force the system to rely on expensive thermal generation or, in extreme cases, impose load curtailment. The expected cost may look acceptable, but the cost in drought scenarios can be catastrophic.

By incorporating CVaR into the SDDP objective, the optimizer builds policies that maintain higher reservoir levels as a hedge against drought. The resulting policy costs slightly more on average but avoids the worst tail outcomes – a trade-off that power system operators typically prefer.

How CVaR enters the SDDP algorithm

Cobre does not use pure CVaR in isolation. Instead, it uses a convex combination of expectation and CVaR:

During the backward pass, this combination changes only the aggregation weights used to combine per-scenario cut coefficients into a single cut. Scenarios with higher costs receive proportionally more weight, while low-cost scenarios receive less. The LP formulation, dual extraction, and cut structure remain unchanged.

Further reading

  • Risk Measures – Overview of risk-averse vs risk-neutral SDDP
  • Risk Measures (spec) – Complete formal specification including the dual representation of CVaR, the sorting-based weight computation algorithm, and the critical warning about lower bound validity
  • Cut Management (spec) – How CVaR-modified aggregation weights affect cut coefficient computation
  • SDDP Theory – How the forward-backward iteration works

Roadmap

This section describes planned features for Cobre that are not yet implemented. The features listed here represent the team’s current thinking about where the solver is headed — they are directional plans, not committed timelines or version targets.

Each feature has been analyzed for feasibility and grouped by theme. The thematic pages below provide detail on motivation, prerequisites, and planned approach for each feature.

Note: Feature C.5 (Non-Controllable Sources) was originally deferred but is now fully implemented. It appears in the table below for historical reference with status “Implemented”. All other features remain planned.

Feature Index

IDFeatureThemeEffort
C.1GNL Thermal PlantsEquipment & ModelingLarge (3-4 wk)
C.2Battery Energy Storage SystemsEquipment & ModelingMedium (2-3 wk)
C.3Multi-Cut FormulationAlgorithm VariantsMedium (2-3 wk)
C.4Markovian Policy GraphsAlgorithm VariantsLarge (3-4 wk)
C.5Non-Controllable SourcesEquipment & ModelingImplemented
C.6FPHA EnhancementsEquipment & ModelingMed-Large (2-4 wk)
C.7Temporal Scope DecouplingAlgorithm VariantsLarge (4-6 wk)
C.8CEPEL PAR(p)-A VariantStochastic EnhancementsSmall-Med (1-2 wk)
C.9Policy Compatibility ValidationTooling & InterfacesMedium (2-3 wk)
C.10Fine-Grained Temporal ResolutionStochastic EnhancementsLarge (4-6 wk)
C.11User-Supplied Noise OpeningsStochastic EnhancementsSmall (1 wk)
C.12Complete Tree SolverAlgorithm VariantsMed-Large (3-4 wk)
C.13Alternative Forward PassPerformance & ParallelismMedium (2-3 wk)
C.14Monte Carlo Backward SamplingStochastic EnhancementsSmall (1 wk)
C.15Risk-Adjusted Forward SamplingStochastic EnhancementsMedium (2-3 wk)
C.16Revisiting Forward PassPerformance & ParallelismSmall-Med (1-2 wk)
C.17Forward Pass State DeduplicationPerformance & ParallelismSmall-Med (<1-3 wk)
C.18Pipelined Backward PassPerformance & ParallelismMedium (2-3 wk)
C.19Dynamic Forward-Passes SchedulerPerformance & ParallelismTBD

Each feature page below provides details on motivation, prerequisites, and planned approach.

Equipment & Modeling

This page covers planned extensions to the set of power system equipment types and production models that Cobre can simulate. These features expand the physical scope of the solver to cover generation technologies and accuracy improvements not included in the initial release.


C.1 GNL Thermal Plants

Gas Natural Liquefeito (GNL) thermal plants operate under complex fuel supply contracts with minimum take-or-pay obligations, variable spot market fuel costs, and start-up and shutdown constraints. The existing thermal model covers simple dispatchable units with fixed cost; GNL requires modeling the fuel inventory as an additional state variable and enforcing contract fulfillment constraints over time.

Why it is deferred: GNL modeling requires integer variables for unit commitment decisions. Extending SDDP to handle integer subproblems requires SDDiP infrastructure (Lagrangian relaxation or other duality handlers) — a significant architectural change that is out of scope for the initial release.

Prerequisites:

  • Duality handler infrastructure for MIP subproblems (Lagrangian relaxation or strengthened Benders cuts)
  • MIP solver integration (Gurobi, CPLEX, or an open-source alternative such as Cbc)
  • GNL-specific data model extensions (fuel inventory, contract parameters)

Estimated effort: Large (3-4 weeks). Requires SDDiP infrastructure before GNL-specific modeling can begin.

See also: Deferred Features §C.1


C.2 Battery Energy Storage Systems

Grid-scale batteries introduce a state-of-charge dimension alongside the existing reservoir storage state. Unlike hydro reservoirs, batteries have symmetric charge/discharge efficiency losses and a capacity that degrades over operational lifetime. The LP formulation is linear — no integer variables are required — making this a more tractable extension than GNL.

Why it is deferred: Batteries require a new state variable dimension (state of charge per battery), integration of charge and discharge flows into bus load balance constraints, and output schema additions for battery simulation results. The data model schemas for batteries are already fully defined, so the main effort is LP construction and testing.

Prerequisites:

  • State variable infrastructure supports a dynamic number of storage dimensions
  • Bus balance constraint generation handles battery charge and discharge contributions
  • Output schema for battery simulation results implemented in cobre-io

Estimated effort: Medium (2-3 weeks). LP formulation is straightforward; the main effort is the data pipeline and realistic test cases.

See also: Deferred Features §C.2


C.5 Non-Controllable Sources (Wind/Solar)

Status: Implemented. Non-controllable sources (wind, solar, and other variable renewable generation) are fully specified and implemented. The LP formulation — including generation bounds, curtailment variables, and bus balance participation — is in Equipment Formulations §6. The entity schema, scenario pipeline, and curtailment penalty are also fully specified. This entry is retained for completeness.

See also: Equipment Formulations §6, Deferred Features §C.5


C.6 FPHA Enhancements

The core Four-Point Head Approximation (FPHA) model for hydro generation is implemented with a constant turbine efficiency. Three accuracy extensions are deferred:

Variable efficiency curves — Replace the constant efficiency coefficient with a flow-dependent hill chart approximation. The efficiency varies with turbine load as a polynomial function of the normalized flow. This captures the operating curve of real turbines and improves generation estimates away from the nominal operating point.

Pumped hydro production function — Extend the FPHA to model reversible hydro units that can operate in both generation and pumping mode. The pumping mode uses a reversed head approximation. Mutual exclusion between generation and pumping is enforced via a high-penalty relaxation (the alternative of binary SOS1 constraints is deferred along with general MIP support).

Dynamic FPHA recomputation — Periodically refit the FPHA hyperplanes based on the observed operating region during training, narrowing the volume window to match where the algorithm actually explores. This improves approximation quality in practice but requires careful management of cut validity across refitting events.

Why it is deferred: Core FPHA is operational and validated. These extensions are accuracy improvements with problem-dependent benefit. Variable efficiency requires hill chart data infrastructure; pumped hydro requires the unified gen/pump production function; dynamic recomputation requires online hyperplane fitting with cut validity tracking.

Prerequisites:

  • Core FPHA operational and validated against reference implementations
  • Hyperplane fitting infrastructure supports refitting with a new volume window
  • Performance baseline established to measure accuracy improvements

Estimated effort: Medium-Large (2-4 weeks total across all three sub-features).

See also: Deferred Features §C.6, Hydro Production Models

Algorithm Variants

This page covers planned extensions to the core SDDP algorithm: alternative cut formulations, richer policy graph structures, and solver modes that address problem types not covered by the initial release.


C.3 Multi-Cut Formulation

The standard SDDP implementation uses a single-cut formulation: one aggregated Benders cut is added per backward pass iteration. The multi-cut formulation instead generates one cut per scenario in the opening tree. This provides more information per iteration at the cost of a larger LP at each stage.

The trade-off is well-studied: multi-cut converges in fewer iterations but each iteration is slower and uses more memory. Single-cut is better for large scenario counts and risk-averse configurations with CVaR; multi-cut is better for small scenario counts and risk-neutral settings.

Why it is deferred: Multi-cut requires the LP builder to handle a variable number of future cost variables (one per scenario instead of one aggregate), a cut pool indexed by scenario, and adapted cut selection logic. The interaction with CVaR risk measures requires careful analysis to ensure the cut validity guarantees are preserved.

Prerequisites:

  • LP builder supports a configurable number of future cost variables per stage
  • Cut pool is indexed by scenario identifier
  • Cut selection strategy is adapted for per-scenario pools

Estimated effort: Medium (2-3 weeks). The core algorithm change has wide-reaching effects on cut management.

See also: Deferred Features §C.3, Cut Management


C.4 Markovian Policy Graphs

The current SDDP implementation assumes stage-wise independence: the same scenario tree structure is used at every stage regardless of which scenario was realized in the previous stage. Markovian policy graphs relax this assumption by introducing a Markov chain over “regimes” (for example, wet/dry/normal inflow regimes), where the transition to the next regime depends on the current one.

In this extension, the policy graph has nodes indexed by (stage, regime) rather than just stage. Cuts are regime-specific — they are only shared within nodes of the same regime. The state space grows by a factor equal to the number of Markov states.

Why it is deferred: Markovian policy graphs substantially increase algorithm complexity. The forward pass must track and sample regime transitions. The backward pass generates cuts for each (stage, markov_state) node. The cut pool, binary format, and cut selection all need to be extended with regime indexing. The data model is already prepared (the stages.json schema includes optional markov_states fields), but the algorithmic work is large.

Prerequisites:

  • Policy graph supports multi-node-per-stage structure
  • Cut pool indexed by (stage, markov_state) tuples
  • Forward and backward pass logic handles Markov regime transitions
  • Scenario generation respects regime-dependent inflow distributions

Estimated effort: Large (3-4 weeks). Fundamental change to the policy graph and forward/backward pass logic.

See also: Deferred Features §C.4, Input Scenarios


C.7 Temporal Scope Decoupling

The current SDDP formulation tightly couples three temporal scopes: the SDDP decomposition stage (where Benders cuts are generated), the physical time resolution of the constraints, and the stochastic process realization period. This forces a trade-off between fine temporal resolution (accurate physics, exponential cut growth) and coarse resolution (manageable cuts, poor short-term dynamics).

Temporal scope decoupling, inspired by the SPARHTACUS framework, allows each SDDP stage to contain multiple physical decision periods. Within a single stage, the LP chains multiple sub-period problems (period 1 feeds period 2, and so on). Cuts are still generated only at stage boundaries — they reference the state at the stage boundary, not intermediate periods — so the cut pool size does not increase even as temporal resolution within each stage improves.

The key advantage is that hourly or weekly resolution can be modeled within monthly SDDP stages without multiplying the cut pool size. The LP per stage grows proportionally to the number of sub-periods, but cut growth (the usual bottleneck) is unchanged.

Why it is deferred: This requires significant architectural changes to LP construction (multi-period sub-problem chaining within a stage), modified forward and backward pass logic, data model changes (a periods array within stages), and careful interaction with chronological block formulations.

Prerequisites:

  • Core SDDP training loop validated and stable
  • Chronological block formulation operational
  • Performance profiling showing cut growth as the binding bottleneck

Estimated effort: Large (4-6 weeks). Fundamental change to LP construction, the data model, and the algorithm.

See also: Deferred Features §C.7


C.12 Complete Tree Solver

The complete tree solver replaces SDDP’s sample-based forward and backward passes with deterministic traversal of an explicit scenario tree. Instead of sampling scenarios, all nodes in the tree are enumerated and a subproblem is solved at each node. The result is an exact solution to the stochastic program (relative to the given tree discretization), matching the behavior of CEPEL’s DECOMP model.

The LP construction per node is identical to the SDDP stage subproblem — the complete tree mode reuses the existing LP builder. The difference is purely in the traversal logic (BFS/DFS enumeration of all tree nodes vs. random sampling) and cut aggregation (tree-weighted aggregation vs. sample-averaged aggregation).

Why it is deferred: Full tree traversal requires infrastructure for enumerating tree nodes, distributing them across MPI ranks, and storing results for potentially millions of nodes. The convergence criterion also changes: rather than a statistical lower bound, convergence means closing the Benders gap on the tree exactly.

Prerequisites:

  • Core SDDP training loop operational
  • Opening tree infrastructure supports variable per-stage branching counts
  • External scenario integration validated
  • Performance profiling establishes tractability bounds for target problem sizes

Estimated effort: Medium-Large (3-4 weeks). LP construction is reused; main effort is tree traversal, MPI node distribution, and result aggregation.

See also: Deferred Features §C.12, Scenario Generation §7

Stochastic Enhancements

This page covers planned improvements to the stochastic modeling and sampling layers of Cobre. These features extend the inflow model, allow finer temporal resolution, add flexibility to the noise generation pipeline, and introduce sampling variants for the backward pass and forward pass.


C.8 CEPEL PAR(p)-A Variant

The standard PAR(p) inflow model is implemented and validated. The CEPEL PAR(p)-A variant extends it with four refinements primarily relevant to basins with highly skewed inflow distributions:

  • Maximum AR order fixed at 12 to enforce an annual cycle
  • Stationarity enforcement via a coefficient constraint
  • Lognormal transformation: the model fits on log(inflow) rather than the raw inflow, which prevents synthetic inflow values from going negative
  • Regional correlation between hydro plants in the same river basin

The lognormal variant is mainly needed when inflow distributions are highly right-skewed and the standard model produces negative synthetic values with non-negligible probability. The inflow non-negativity handling strategies already mitigate this for the standard model in most basins.

Why it is deferred: The standard PAR(p) model covers most practical use cases. The PAR(p)-A variant is a refinement for specific basin characteristics. The current input format (inflow_seasonal_stats.parquet and inflow_ar_coefficients.parquet) is already compatible with PAR(p)-A — the lognormal transformation is applied during history preprocessing before computing the seasonal statistics.

Prerequisites:

  • Standard PAR(p) fitting and validation operational
  • Lognormal transformation infrastructure (log-space fitting, back-transformation)
  • Validation suite comparing PAR(p) and PAR(p)-A on representative basins

Estimated effort: Small-Medium (1-2 weeks). The mathematical extensions are straightforward; the main effort is validation and testing.

See also: Deferred Features §C.8, PAR Inflow Model


C.10 Fine-Grained Temporal Resolution (Typical Days)

The current block formulation represents each SDDP stage with a small number of load blocks (for example, peak, shoulder, and off-peak) that aggregate monthly hours by load level. This is adequate for long-term planning but cannot model daily cycling patterns — daily storage behavior for pumped hydro and batteries, hourly renewable generation profiles, time-of-use pricing, or intra-day ramp constraints.

The planned extension introduces representative typical day types (for example, weekday and weekend) within each SDDP stage, each containing a sequence of chronological hourly blocks. This enables accurate daily sub-structure without increasing the cut pool size (cuts are still generated at stage boundaries, not within day types).

Key open design questions that require research before implementation:

  • Day-type chaining: Should the end-of-day storage from one day type carry forward to the next day type within the same stage, or should each day type operate independently with a weighted average end-of-stage storage?
  • Objective scaling: Block durations are actual hours (for water balance), but the objective contribution must be scaled by how many days each day type represents.
  • Two-phase architecture: Training with aggregated blocks followed by simulation with full typical-day resolution. Cut compatibility conditions between the two phases need formal verification.

Why it is deferred: This feature requires research on the open design questions before implementation can begin. The LP size per stage grows substantially (from 3 blocks to 72 or more), and the interaction with existing block formulations is complex.

Prerequisites:

  • Core parallel and chronological block modes operational and validated
  • Simulation architecture supports variable block configurations
  • Research on day-type chaining and two-phase cut compatibility completed

Estimated effort: Large (4-6 weeks). Significant input schema design, LP construction changes, and research required.

See also: Deferred Features §C.10


C.11 User-Supplied Noise Openings

The standard noise generation pipeline samples independent Gaussian noise vectors and applies Cholesky correlation. This pipeline covers most use cases, but some workflows require direct control over the noise values:

  • Importing noise realizations from external stochastic models that use non-Gaussian distributions
  • Reproducing exact noise sequences from legacy tools for validation
  • Using domain-specific spatial correlation structures not captured by the Cholesky approach
  • Research workflows where specific noise patterns are under study

The planned mechanism is a scenarios/noise_openings.parquet file. When this file is present, the scenario generator skips internal noise sampling and Cholesky correlation entirely, loading the user-supplied values directly into the opening tree.

Open design questions to resolve before implementation: the relationship to the existing external scenario mechanism (with noise inversion), what validation checks should be applied to user-supplied noise, whether load entity noise should be included alongside inflow noise, and whether separate noise sets are needed for forward and backward passes.

Prerequisites:

  • Opening tree architecture implemented and validated
  • Forward/backward noise separation operational
  • Clear use case catalog that cannot be served by the existing external scenario mechanism

Estimated effort: Small (1 week). Input loading and validation are straightforward once the design questions are resolved.

See also: Deferred Features §C.11, Scenario Generation §2.3


C.14 Monte Carlo Backward Sampling

The standard backward pass evaluates all openings in the opening tree at each backward stage. When the opening count is large (500 or more, for high-fidelity tail representation), the backward pass dominates iteration time. Monte Carlo backward sampling replaces full enumeration with a sample of n openings drawn with replacement from the tree, reducing backward pass cost from O(N_openings) to O(n) LP solves per stage per trial point.

The resulting cut is an unbiased estimator of the full cut but with higher variance. The trade-off relative to the default full evaluation: fewer solves per iteration, but non-monotonic lower bound behavior (which complicates convergence monitoring) and slower per-iteration convergence.

Why it is deferred: The default complete evaluation is reliable and performant for typical production opening counts (50-200). Monte Carlo sampling introduces non-monotonic lower bounds, which require adaptations to convergence monitoring. The benefit depends on the chosen n relative to N_openings, which is problem-dependent.

Prerequisites:

  • Core SDDP with complete backward sampling validated
  • Convergence monitoring supports non-monotonic lower bounds
  • Empirical study of the n vs. convergence rate trade-off

Estimated effort: Small (1 week). Sampling infrastructure is trivial; the main effort is convergence monitoring adaptation.

See also: Deferred Features §C.14


C.15 Risk-Adjusted Forward Sampling

Standard forward sampling draws scenarios uniformly from the opening tree. For strongly risk-averse policies (CVaR with weight lambda close to 1.0), uniform sampling under-explores the worst-case tail scenarios that matter most for the risk measure.

Risk-adjusted forward sampling biases the forward pass toward tail scenarios by evaluating the risk measure over candidate noise terms at each forward stage and re-weighting or re-sampling the next-stage noise accordingly. A complementary importance sampling variant weights forward trajectories by their likelihood ratio under the risk-adjusted distribution, enabling tighter upper bound estimates for risk-averse settings.

Why it is deferred: Integration with the CVaR risk measure configuration is non-trivial, and importance weights must be handled carefully in upper bound estimation. Default uniform sampling is sufficient for most applications; the benefit is primarily for strongly risk-averse configurations.

Prerequisites:

  • CVaR risk measure implemented and validated
  • Forward sampling scheme abstraction supports per-stage re-weighting
  • Upper bound evaluation handles importance-weighted trajectories

Estimated effort: Medium (2-3 weeks). The algorithm is well-documented in the literature; the main effort is integration with the risk measure and convergence analysis.

See also: Deferred Features §C.15, Risk Measures

Performance & Parallelism

This page covers planned optimizations to the SDDP training loop that reduce computation time, improve state space exploration, or exploit parallel hardware more effectively. These features are motivated by profiling observations rather than new algorithmic capabilities — they make the existing algorithm faster or more thorough, without changing its fundamental behavior.


C.13 Alternative Forward Pass

The default forward pass solves the training LP, which excludes simulation-only features (linearized head, unit commitment, bottom discharge) to preserve convexity for valid cut generation. Trial points from this simplified model may not represent states that are realistic under full operational modeling, potentially slowing convergence.

The alternative forward pass maintains two LP models per stage: the training LP (convex, used for backward pass cut generation) and an alternative LP (includes simulation-only features, used for the forward pass to generate more realistic trial points). After each backward pass, new cuts are added to both models.

Cuts remain valid because they are always generated from the convex training LP. Trial points are more realistic because they come from the richer alternative LP. The trade-off: memory approximately doubles (two LP models per stage), and convergence may be slower because forward trial points are not optimal for the training model.

Why it is deferred: Maintaining two parallel LP models per stage doubles memory and complicates solver workspace management. The benefit depends on how much simulation-only features change the trial points, which is problem-dependent and requires empirical investigation.

Prerequisites:

  • Core SDDP training loop operational and validated
  • Simulation-only LP construction (linearized head, unit commitment) implemented
  • Solver workspace infrastructure supports multiple LP models per stage

Estimated effort: Medium (2-3 weeks). LP construction infrastructure is reused; the main effort is dual LP management, cut copying, and convergence testing.

See also: Deferred Features §C.13, Simulation Architecture


C.16 Revisiting Forward Pass

Standard forward passes always start from the initial state at stage 1. In problems with large state spaces, repeated iterations can visit similar states and generate cuts in the same regions, leaving parts of the state space poorly covered.

The revisiting forward pass maintains a buffer of previously visited states from past iterations. With some probability, a forward pass starts from a randomly selected historical state at a randomly selected stage instead of from stage 1. The resulting trial points generate cuts in regions that standard forward passes have not recently visited.

Why it is deferred: Starting a forward pass from an intermediate stage produces a partial trajectory that does not contribute a full-horizon cost estimate. This complicates upper bound estimation. The benefit is primarily for problems where standard forward passes provably concentrate in a narrow region of the state space.

Prerequisites:

  • Core SDDP training loop validated
  • State history buffer infrastructure
  • Convergence monitoring handles partial-trajectory iterations

Estimated effort: Small-Medium (1-2 weeks). The state buffer is straightforward; the main effort is convergence analysis for partial trajectories.

See also: Deferred Features §C.16


C.17 Forward Pass State Deduplication

When multiple forward scenarios visit identical or near-identical states at a given stage, the backward pass redundantly evaluates the cost-to-go from duplicate trial points. Identical states produce identical cuts, so the duplication adds no information.

Two approaches are planned:

  • Exact deduplication — Hash-based deduplication of state vectors with identical values. Straightforward to implement but limited in benefit, since exact duplicates are uncommon in problems with continuous state spaces.
  • Approximate deduplication — Merge states within a tolerance using spatial indexing (for example, k-d tree). Greater reduction in backward solves, but introduces approximation in cut coefficients. Requires analysis of convergence implications before deployment.

Why it is deferred: Exact duplicates are uncommon, making exact deduplication a marginal optimization. Approximate deduplication requires careful convergence analysis. This feature should be implemented only when profiling shows backward pass cost is dominated by trial point count rather than per-solve cost.

Prerequisites:

  • Core SDDP training loop validated and profiled
  • Backward pass timing data identifying trial point count as the dominant cost factor

Estimated effort: Small (less than 1 week) for exact deduplication; Medium (2-3 weeks) for approximate deduplication with convergence analysis.

See also: Deferred Features §C.17, Training Loop §5.2


C.18 Pipelined Backward Pass

The standard sequential backward pass uses the cut approximation from the current iteration at each stage. This requires a synchronization barrier between stages: stage t cannot begin its backward solve until stage t+1 has finished and broadcast its cuts.

The pipelined backward pass uses the previous iteration’s approximation instead. This eliminates per-stage barriers and allows backward stages to proceed in a pipeline — stage t begins its solve while stage t+1 is still communicating cuts via non-blocking MPI collectives (MPI_Iallgatherv). The result is overlapped communication and computation.

The trade-off: pipelined cuts are looser (older information), so more iterations are needed to converge. Whether the shorter wall-clock time per iteration outweighs the slower per-iteration convergence depends on hardware-specific communication latency, which cannot be determined without profiling production workloads.

When to consider: Profiling shows backward pass per-stage barrier synchronization accounts for more than 20% of backward pass time. Most likely with very large stage counts (more than 100 stages) and high inter-node network latency.

Why it is deferred: The sequential mode is simpler, produces tighter cuts, and is the default in SDDP.jl and most production implementations. The pipelining benefit is hardware-specific.

Prerequisites:

  • Core SDDP training loop validated and profiled
  • Backward pass timing data showing barrier synchronization as a bottleneck
  • Non-blocking MPI collective support in ferrompi (MPI_Iallgatherv)

Estimated effort: Medium (2-3 weeks). Requires async state management, non-blocking collective wrappers, and convergence regression testing.

See also: Deferred Features §C.18, Communication Patterns


C.19 Dynamic Forward-Passes Scheduler

The number of forward passes per iteration (forward_passes) is currently set statically in the configuration. A dynamic scheduler would adjust this count during training based on convergence metrics (for example, increasing forward passes when the lower bound is stagnant) or wall-clock budget (for example, maintaining a fixed seconds-per-iteration target).

Why it is deferred: The cut pool is pre-allocated using the formula warm_start_cuts + max_iterations × forward_passes with a deterministic slot assignment. A dynamic scheduler would require either a worst-case static allocation (wasteful for most runs) or dynamic reallocation (which invalidates the deterministic slot assignment and complicates reproducibility). The right approach requires profiling data from production workloads.

See also: Deferred Features §C.19, Cut Management Implementation §1.3

Tooling & Interfaces

This page covers planned additions to the tooling ecosystem around the Cobre solver: validation tooling for trained policies, and the three interface crates that expose Cobre to different consumer contexts (AI agents via MCP, Python workflows via PyO3, and interactive terminal monitoring via ratatui).


C.9 Policy Compatibility Validation

When the solver runs in simulation-only mode, warm-start mode, or resumes from a checkpoint, it must validate that the current input data is compatible with the previously trained policy. The policy (cut coefficients) encodes LP structural information: the number of state variables, the constraint topology, the block configuration, the penalty values. If any of these change between training and simulation, the cuts become invalid and produce silently incorrect results.

The planned mechanism has two components:

  1. Policy metadata record — During training, the solver persists a metadata record alongside the cut data, capturing all input properties that affect LP structure. The record is versioned for forward compatibility.
  2. Validation phase — At the start of simulation or warm-start, the current input is compared against the metadata. Any mismatch produces a hard error with a clear description of what changed.

Properties that must be validated include: block mode and block count per stage, number of hydro plants and their AR orders, cascade topology, bus and line count, thermal and contract counts, production model per hydro, and penalty configuration. Some properties may allow controlled relaxation in the future (for example, adding a new thermal plant at the end of the generator list might be compatible if the state variable dimensions are unchanged), but the initial implementation validates everything strictly.

Why it is deferred: This is a cross-cutting concern touching training, simulation, checkpointing, and input loading. All prerequisite specs are now approved, and C.9 is unblocked pending a dedicated specification that defines the complete property list, the metadata format, the validation algorithm, and the error reporting format.

Prerequisites (all now met):

Estimated effort: Medium (2-3 weeks). Primarily specification and testing; implementation is straightforward once the property list is defined.

See also: Deferred Features §C.9, Binary Formats


MCP Server (cobre-mcp)

The MCP server exposes Cobre as a first-class tool for AI coding agents via the Model Context Protocol. It runs as a standalone binary (cobre-mcp) or as a cobre serve subcommand, in single-process mode without MPI. Computation is delegated to cobre-sddp; all tool responses use the structured output envelope defined in Structured Output.

The server exposes Cobre’s run, validate, and report capabilities as MCP tools, with streaming progress updates for long-running training jobs. Multi-process execution via TCP or shared memory backends is architecturally possible but deferred pending demonstrated demand from MCP-based agent workflows.

The full specification is in MCP Server.


Python Bindings (cobre-python)

The Python bindings expose Cobre’s solver to Python workflows as the cobre module via PyO3. The module compiles to a shared library (cdylib) that is installed and imported like any other Python package.

Key design points: the GIL is released during all Rust computation; NumPy and Arrow FFI provide zero-copy data paths; MPI is prohibited from the Python interface (multi-process execution uses TCP or shared memory backends instead). The Python exception hierarchy maps to Cobre’s structured error kind registry.

The full specification is in Python Bindings.


Terminal UI (cobre-tui)

The terminal UI provides real-time monitoring of SDDP training runs in the terminal. It is built on ratatui and renders convergence plots, iteration timing breakdowns, cut statistics, resource usage, and MPI communication metrics.

The TUI operates in two modes: co-hosted within the cobre binary via an in-process broadcast channel (sharing the same process as the solver), or standalone reading JSON-lines from stdin for monitoring remote or already-running jobs. Interactive features — pause/resume, cut inspection, scenario comparison, stopping rule adjustment — all operate at iteration boundaries to preserve training loop atomicity.

The full specification is in Terminal UI.

Overview

Note: These specifications were written before implementation to define contracts and interfaces. With all 8 phases complete, the source of truth for behavior is the source code and the software book. These specs remain as reference for the design rationale behind implementation decisions.

Internal development artifacts: This section is intended for Cobre contributors and maintainers. The specs document design decisions, trait contracts, and implementation constraints that were authored before the code was written. If you are here to understand the mathematics or algorithms, the Theory section is the recommended starting point.

This section contains the foundational specifications that underpin all other sections of the Cobre documentation. It establishes the design philosophy that guides every architectural and algorithmic decision, the notation conventions that ensure consistency across all mathematical and data-model specs, and the production-scale reference dimensions that anchor performance analysis and memory budget calculations throughout the HPC specs.

These three specs are prerequisites for reading any other specification section. They are referenced pervasively – design principles inform trade-off discussions in the architecture specs, notation conventions define the symbols used in every equation, and production-scale dimensions appear whenever a spec quantifies communication volume, memory footprint, or computational cost.

Reading Order

The specs are short and self-contained; reading them in order takes under fifteen minutes:

  1. Design Principles – The 9 foundational principles guiding the Cobre solver design. These principles are cited throughout the architecture and HPC specs to justify specific design choices.
  2. Notation Conventions – Index sets, symbols, and unit conventions used throughout all mathematical formulations. Required context before reading any spec in the Mathematical Formulations section.
  3. Production Scale Reference – Representative problem dimensions for a national-scale hydrothermal system (number of plants, stages, scenarios, state dimension). Referenced by every spec that performs sizing analysis or communication volume estimation.

Spec Index

SpecDescription
Design PrinciplesFoundational design goals and trade-off principles that govern all architectural decisions
Notation ConventionsIndex sets, mathematical symbols, physical units, and naming conventions for the specification suite
Production Scale ReferenceConcrete problem dimensions for a national-scale hydrothermal dispatch system, used for sizing and performance analysis
Decision LogCentral registry of cross-cutting architectural decisions affecting two or more spec files

The Specifications section contains 7 subsections: Overview (this section), Mathematical Formulations, Data Model, Architecture, High-Performance Computing, Configuration, and Deferred Features. Readers encountering the specs for the first time should complete the three overview specs before proceeding to any other subsection.

Cross-Reference Index

This page provides a centralized navigation index for the 79 specification files in the Cobre documentation. It is designed to help implementers determine which specs to read for a given crate, in what order, and how specs relate to each other through cross-references.

The index has five components:

  1. Spec-to-Crate Mapping Table – which crate(s) each spec belongs to
  2. Per-Crate Reading Lists – ordered reading lists for each of the 11 crates
  3. Outgoing Cross-Reference Table – for each spec, which other specs it references
  4. Incoming Cross-Reference Table – for each spec, which other specs reference it
  5. Dependency Ordering – a global topological reading order for the entire corpus

Errata resolved: Seven HIGH-severity section-number errors (F-1, F-5, F-6, F-7, F-8, F-9, F-11) were identified in the Epic 03 cross-reference audit and corrected in Epic 06 remediation. All section-number references now point to the correct targets.


1. Spec-to-Crate Mapping Table

#Spec FileSectionPrimary CrateSecondary Crate(s)
1design-principles.mdoverviewcobre-core, cobre-ioAll crates (cross-cutting)
2notation-conventions.mdoverview(cross-cutting)All crates
3production-scale-reference.mdoverviewcobre-sddp, cobre-solverferrompi, cobre-io
73implementation-ordering.mdoverview(cross-cutting)All crates
74spec-gap-inventory.mdoverview(cross-cutting)All crates
4input-directory-structure.mddata-modelcobre-iocobre-core, cobre-cli
5input-system-entities.mddata-modelcobre-corecobre-io
6input-hydro-extensions.mddata-modelcobre-corecobre-io
7input-scenarios.mddata-modelcobre-io, cobre-stochasticcobre-core
8input-constraints.mddata-modelcobre-iocobre-core, cobre-sddp
9penalty-system.mddata-modelcobre-corecobre-sddp
10internal-structures.mddata-modelcobre-corecobre-sddp, cobre-stochastic
11output-schemas.mddata-modelcobre-iocobre-sddp
12output-infrastructure.mddata-modelcobre-ioferrompi, cobre-sddp
13binary-formats.mddata-modelcobre-iocobre-sddp, cobre-solver
14sddp-algorithm.mdmathcobre-sddp
15lp-formulation.mdmathcobre-sddpcobre-core, cobre-solver
16system-elements.mdmathcobre-corecobre-sddp
17block-formulations.mdmathcobre-sddp
18hydro-production-models.mdmathcobre-sddpcobre-core
19cut-management.mdmathcobre-sddp
20discount-rate.mdmathcobre-sddp
21infinite-horizon.mdmathcobre-sddp
22risk-measures.mdmathcobre-sddp
23inflow-nonnegativity.mdmathcobre-sddpcobre-stochastic
24par-inflow-model.mdmathcobre-stochasticcobre-io, cobre-core
25equipment-formulations.mdmathcobre-sddpcobre-core
26stopping-rules.mdmathcobre-sddp
27upper-bound-evaluation.mdmathcobre-sddp
28training-loop.mdarchitecturecobre-sddpcobre-solver, cobre-stochastic
29simulation-architecture.mdarchitecturecobre-sddpcobre-io, cobre-stochastic
30cli-and-lifecycle.mdarchitecturecobre-cli
31validation-architecture.mdarchitecturecobre-iocobre-cli
32input-loading-pipeline.mdarchitecturecobre-iocobre-core
33scenario-generation.mdarchitecturecobre-stochasticcobre-sddp
34solver-abstraction.mdarchitecturecobre-solver
35solver-highs-impl.mdarchitecturecobre-solver
36solver-clp-impl.mdarchitecturecobre-solver
37solver-workspaces.mdarchitecturecobre-solver
76performance-adaptation-layer.mdarchitecturecobre-sddp
38cut-management-impl.mdarchitecturecobre-sddpcobre-io
39convergence-monitoring.mdarchitecturecobre-sddp
40extension-points.mdarchitecturecobre-sddpcobre-stochastic, cobre-io
41work-distribution.mdhpccobre-sddpferrompi
42hybrid-parallelism.mdhpccobre-sddpferrompi, cobre-solver
43communication-patterns.mdhpcferrompicobre-sddp
44memory-architecture.mdhpccobre-sddpcobre-solver
45shared-memory-aggregation.mdhpccobre-sddpferrompi
46checkpointing.mdhpccobre-sddpcobre-io, cobre-cli
47slurm-deployment.mdhpccobre-cliferrompi
48synchronization.mdhpccobre-sddpferrompi
49configuration-reference.mdconfigurationcobre-clicobre-sddp, cobre-stochastic, cobre-core
50deferred.mddeferred(multi-crate)See audit report section 2.2
51structured-output.mdinterfacescobre-clicobre-mcp, cobre-python
52mcp-server.mdinterfacescobre-mcpcobre-cli
53python-bindings.mdinterfacescobre-pythoncobre-cli
54terminal-ui.mdinterfacescobre-tuicobre-cli
55communicator-trait.mdhpccobre-commcobre-sddp
56backend-selection.mdhpccobre-commcobre-sddp, cobre-cli
57backend-ferrompi.mdhpccobre-commferrompi
58backend-local.mdhpccobre-comm
59backend-tcp.mdhpccobre-comm
60backend-shm.mdhpccobre-comm
61risk-measure-trait.mdarchitecturecobre-sddp
62risk-measure-testing.mdarchitecturecobre-sddp
63horizon-mode-trait.mdarchitecturecobre-sddp
64horizon-mode-testing.mdarchitecturecobre-sddp
65sampling-scheme-trait.mdarchitecturecobre-stochasticcobre-sddp
66sampling-scheme-testing.mdarchitecturecobre-stochasticcobre-sddp
67cut-selection-trait.mdarchitecturecobre-sddp
68cut-selection-testing.mdarchitecturecobre-sddp
69stopping-rule-trait.mdarchitecturecobre-sddp
70stopping-rule-testing.mdarchitecturecobre-sddp
71solver-interface-trait.mdarchitecturecobre-solver
72solver-interface-testing.mdarchitecturecobre-solver
73backend-testing.mdhpccobre-comm
74ecosystem-guidelines.mdoverview(cross-cutting)All crates
75ecosystem-vision.mdoverview(cross-cutting)All crates
79decision-log.mdoverview(cross-cutting)All crates

2. Per-Crate Reading Lists

Specs are ordered by reading dependency: foundational specs (referenced by many others) appear first. Where no dependency exists, order follows section precedence (overview, math, data-model, architecture, hpc, configuration, deferred). Secondary specs are marked with “(secondary)”.

cobre-sddp

This crate owns the SDDP algorithm, training loop, LP construction, cut management, simulation, convergence, risk measures, work distribution, synchronization, and memory architecture. 33 primary specs, 12 secondary.

  1. LP Formulation
  2. Cut Management
  3. SDDP Algorithm
  4. Configuration Reference (secondary)
  5. Scenario Generation (secondary)
  6. Penalty System (secondary)
  7. Training Loop
  8. Risk Measures
  9. Binary Formats (secondary)
  10. Stopping Rules
  11. Input Constraints (secondary)
  12. Memory Architecture
  13. Discount Rate
  14. Hybrid Parallelism
  15. Hydro Production Models
  16. Upper Bound Evaluation
  17. System Elements (secondary)
  18. Block Formulations
  19. Infinite Horizon
  20. Internal Structures (secondary)
  21. Production Scale Reference
  22. Equipment Formulations
  23. Output Schemas (secondary)
  24. Cut Management Implementation
  25. Work Distribution
  26. Communication Patterns (secondary)
  27. Shared Memory Aggregation
  28. Checkpointing
  29. Output Infrastructure (secondary)
  30. Convergence Monitoring
  31. Synchronization
  32. Inflow Non-Negativity
  33. Simulation Architecture
  34. Extension Points
  35. Performance Adaptation Layer
  36. Risk Measure Trait
  37. Risk Measure Testing
  38. Horizon Mode Trait
  39. Horizon Mode Testing
  40. Sampling Scheme Trait (secondary)
  41. Sampling Scheme Testing (secondary)
  42. Cut Selection Strategy Trait
  43. Cut Selection Testing
  44. Stopping Rule Trait
  45. Stopping Rule Testing
  46. Communicator Trait (secondary)
  47. Backend Selection (secondary)
  48. Implementation Ordering (secondary)
  49. Spec Gap Inventory (secondary)
  50. Ecosystem Guidelines (secondary)
  51. Ecosystem Vision (secondary)
  52. Decision Log (secondary)

cobre-core

This crate owns entity types, internal structures, penalty system, and design principles. 6 primary specs, 9 secondary.

  1. LP Formulation (secondary)
  2. Configuration Reference (secondary)
  3. Penalty System
  4. Input System Entities
  5. Input Scenarios (secondary)
  6. Design Principles
  7. Input Constraints (secondary)
  8. PAR Inflow Model (secondary)
  9. Hydro Production Models (secondary)
  10. Input Directory Structure (secondary)
  11. System Elements
  12. Input Hydro Extensions
  13. Internal Structures
  14. Equipment Formulations (secondary)
  15. Input Loading Pipeline (secondary)
  16. Implementation Ordering (secondary)
  17. Spec Gap Inventory (secondary)
  18. Ecosystem Guidelines (secondary)
  19. Ecosystem Vision (secondary)
  20. Decision Log (secondary)

Phase 2 Module-to-Spec Mapping (cobre-core)

The following table maps each Rust module added in Phase 2 to the spec section(s) it implements.

ModuleRust FilePrimary Spec Section(s)
temporalsrc/temporal.rsInput Scenarios §1.1–1.10 (stages, blocks, seasons, policy graph, state variables, risk measure, noise method)
scenariosrc/scenario.rsInput Scenarios §2–5 (PAR model parameters, load statistics, correlation model, scenario source)
initial_conditionssrc/initial_conditions.rsInput Constraints §1 (initial storage and filling-storage arrays)
generic_constraintsrc/generic_constraint.rsInput Constraints §3 (generic linear constraint in-memory representation, expression grammar hook)
resolvedsrc/resolved.rsPenalty System §3 (pre-resolved O(1) penalty containers); Input Constraints §2 (pre-resolved O(1) bound containers)

cobre-io

This crate owns input parsing, output writing, validation, binary formats, and the loading pipeline. 9 primary specs, 8 secondary.

  1. Design Principles
  2. Input System Entities (secondary)
  3. Input Scenarios
  4. Binary Formats
  5. Input Constraints
  6. PAR Inflow Model (secondary)
  7. Input Directory Structure
  8. Input Hydro Extensions (secondary)
  9. Production Scale Reference (secondary)
  10. Output Schemas
  11. Cut Management Implementation (secondary)
  12. Checkpointing (secondary)
  13. Output Infrastructure
  14. Validation Architecture
  15. Input Loading Pipeline
  16. Simulation Architecture (secondary)
  17. Extension Points (secondary)
  18. Implementation Ordering (secondary)
  19. Spec Gap Inventory (secondary)
  20. Ecosystem Guidelines (secondary)
  21. Ecosystem Vision (secondary)
  22. Decision Log (secondary)

Phase 2 Module-to-Spec Mapping (cobre-io)

The following table maps each public Rust module in crates/cobre-io/src/ to the spec section(s) it implements.

ModuleRust PathPrimary Spec Section(s)
libsrc/lib.rsInput Loading Pipeline §8.1 (load_case public API, LoadError enum)
errorsrc/error.rsInput Loading Pipeline §8.1 (LoadError six-variant enum)
pipelinesrc/pipeline.rsInput Loading Pipeline §2–7 (five-layer pipeline orchestration, resolution, scenario assembly, SystemBuilder construction)
configsrc/config.rsInput Directory Structure §2 (config.json schema); Configuration Reference §3–7
stagessrc/stages.rsInput Scenarios §1 (stages.json schema, policy graph, scenario source)
initial_conditionssrc/initial_conditions.rsInput Constraints §1 (initial_conditions.json parser)
penaltiessrc/penalties.rsPenalty System §1 (penalties.json global defaults parser)
broadcastsrc/broadcast.rsBinary Formats §2 (postcard MPI broadcast, DEC-002); Input Loading Pipeline §6.1–6.4
reportsrc/report.rsValidation Architecture §5 (ValidationReport JSON serialization)
validation::modsrc/validation/mod.rsValidation Architecture §3–4 (ValidationContext, ErrorKind catalog, Severity)
validation::structuralsrc/validation/structural.rsValidation Architecture §2.1 (Layer 1: structural); Input Directory Structure §1 (FileManifest, 33-file inventory)
validation::schemasrc/validation/schema.rsValidation Architecture §2.2 (Layer 2: schema)
validation::referentialsrc/validation/referential.rsValidation Architecture §2.3 (Layer 3: referential integrity); Input Loading Pipeline §2.6 (26-rule cross-reference checklist)
validation::dimensionalsrc/validation/dimensional.rsValidation Architecture §2.4 (Layer 4: dimensional consistency)
validation::semanticsrc/validation/semantic.rsValidation Architecture §2.5 (Layer 5: semantic rules — GNL rejection, penalty ordering, PAR stationarity, acyclic cascade)
systemsrc/system/Input System Entities §1–7 (entity registry parsers for all 7 entity types); Input Hydro Extensions §1–3
extensionssrc/extensions/Input Hydro Extensions §1–3 (FPHA hyperplanes, hydro geometry, production models)
constraintssrc/constraints/Input Constraints §2–4 (bounds Parquet parsers, penalty override parsers, exchange factors, generic constraints, generic constraint bounds)
scenariossrc/scenarios/Input Scenarios §3–5 (PAR coefficients, seasonal stats, inflow history, load factors, correlation, external scenarios, assembly)
resolutionsrc/resolution/Input Loading Pipeline §5 (three-tier sparse-to-dense expansion); Penalty System §3 (penalty cascade); Input Constraints §2 (bound cascade)
outputsrc/output/Output Schemas §1–6 (stub — Phase 7 scope); Output Infrastructure §1–6 (stub — Phase 7 scope); Binary Formats §3 (FlatBuffers stub — Phase 7 scope)
parquet_helperssrc/parquet_helpers.rs(internal) Binary Formats §2.2 (Parquet column extraction helpers, Parquet input format per DEC-004)

cobre-stochastic

This crate owns the PAR model, scenario generation, noise correlation, and sampling scheme abstraction. 5 primary specs, 6 secondary.

  1. Configuration Reference (secondary)
  2. Scenario Generation
  3. Training Loop (secondary)
  4. Input Scenarios
  5. PAR Inflow Model
  6. Internal Structures (secondary)
  7. Inflow Non-Negativity (secondary)
  8. Simulation Architecture (secondary)
  9. Extension Points (secondary)
  10. Sampling Scheme Trait
  11. Sampling Scheme Testing
  12. Implementation Ordering (secondary)
  13. Spec Gap Inventory (secondary)
  14. Ecosystem Guidelines (secondary)
  15. Ecosystem Vision (secondary)
  16. Decision Log (secondary)

cobre-solver

This crate owns the solver abstraction, HiGHS and CLP implementations, workspaces, and solver interface trait. 7 primary specs, 4 secondary.

  1. LP Formulation (secondary)
  2. Binary Formats (secondary)
  3. Solver Abstraction
  4. Solver Interface Trait
  5. Solver Interface Testing
  6. Memory Architecture (secondary)
  7. Hybrid Parallelism (secondary)
  8. Solver Workspaces
  9. Production Scale Reference
  10. Solver HiGHS Implementation
  11. Solver CLP Implementation
  12. Implementation Ordering (secondary)
  13. Spec Gap Inventory (secondary)
  14. Ecosystem Guidelines (secondary)
  15. Ecosystem Vision (secondary)
  16. Decision Log (secondary)

cobre-cli

This crate owns CLI lifecycle, config parsing, and SLURM deployment. 3 primary specs, 3 secondary.

  1. Configuration Reference
  2. Input Directory Structure (secondary)
  3. CLI and Lifecycle
  4. Checkpointing (secondary)
  5. Validation Architecture (secondary)
  6. SLURM Deployment
  7. Implementation Ordering (secondary)
  8. Spec Gap Inventory (secondary)
  9. Ecosystem Guidelines (secondary)
  10. Ecosystem Vision (secondary)
  11. Decision Log (secondary)

ferrompi

This crate owns MPI communication and SharedWindow. 1 primary spec, 8 secondary.

  1. Hybrid Parallelism (secondary)
  2. Production Scale Reference (secondary)
  3. Work Distribution (secondary)
  4. Communication Patterns
  5. Shared Memory Aggregation (secondary)
  6. Output Infrastructure (secondary)
  7. Synchronization (secondary)
  8. SLURM Deployment (secondary)
  9. Backend: Ferrompi (secondary)
  10. Implementation Ordering (secondary)
  11. Spec Gap Inventory (secondary)
  12. Ecosystem Guidelines (secondary)
  13. Ecosystem Vision (secondary)
  14. Decision Log (secondary)

cobre-comm

This crate owns the communication backend abstraction: the Communicator trait, backend registration, and all four backend implementations. 7 primary specs, 4 secondary.

  1. Communicator Trait – trait definition, method contracts, SharedMemoryProvider
  2. Backend Selection – feature flags, factory pattern, runtime selection
  3. Backend: Ferrompi – MPI backend wrapping ferrompi
  4. Backend: Local – single-process no-op backend
  5. Backend: TCP – TCP socket backend for MPI-free deployments
  6. Backend: Shared Memory – POSIX shared memory backend
  7. Backend Testing – conformance test suite for all four Communicator backends
  8. Communication Patterns (secondary) – usage patterns for the trait
  9. Hybrid Parallelism (secondary) – initialization sequence
  10. Shared Memory Aggregation (secondary) – SharedMemoryProvider usage
  11. Implementation Ordering (secondary)
  12. Spec Gap Inventory (secondary)
  13. Ecosystem Guidelines (secondary)
  14. Ecosystem Vision (secondary)
  15. Decision Log (secondary)

cobre-mcp

This crate owns the MCP server specification. 1 primary spec, 5 secondary.

  1. MCP Server
  2. Structured Output (secondary)
  3. Convergence Monitoring (secondary)
  4. Validation Architecture (secondary)
  5. Output Schemas (secondary)
  6. Output Infrastructure (secondary)
  7. Implementation Ordering (secondary)
  8. Spec Gap Inventory (secondary)
  9. Ecosystem Guidelines (secondary)
  10. Ecosystem Vision (secondary)
  11. Decision Log (secondary)

cobre-python

This crate owns the Python bindings specification. 1 primary spec, 5 secondary.

  1. Python Bindings
  2. Structured Output (secondary)
  3. Hybrid Parallelism (secondary)
  4. Memory Architecture (secondary)
  5. Training Loop (secondary)
  6. Output Schemas (secondary)
  7. Implementation Ordering (secondary)
  8. Spec Gap Inventory (secondary)
  9. Ecosystem Guidelines (secondary)
  10. Ecosystem Vision (secondary)
  11. Decision Log (secondary)

cobre-tui

This crate owns the terminal UI specification. 1 primary spec, 3 secondary.

  1. Terminal UI
  2. Convergence Monitoring (secondary)
  3. Training Loop (secondary)
  4. Structured Output (secondary)
  5. Implementation Ordering (secondary)
  6. Spec Gap Inventory (secondary)
  7. Ecosystem Guidelines (secondary)
  8. Ecosystem Vision (secondary)
  9. Decision Log (secondary)

3. Outgoing Cross-Reference Table

For each spec file, this table shows which other specs it references in its ## Cross-References section. Grouped by section.

Overview

Spec FileReferences
design-principles.mdnotation-conventions.md, production-scale-reference.md, lp-formulation.md, input-directory-structure.md, validation-architecture.md, convergence-monitoring.md, training-loop.md, structured-output.md, mcp-server.md, python-bindings.md, terminal-ui.md, internal-structures.md, solver-workspaces.md, binary-formats.md, input-loading-pipeline.md, output-schemas.md, decision-log.md
notation-conventions.mddesign-principles.md, production-scale-reference.md, lp-formulation.md, sddp-algorithm.md, cut-management.md, par-inflow-model.md, hydro-production-models.md, equipment-formulations.md, solver-abstraction.md
production-scale-reference.mddesign-principles.md, notation-conventions.md, lp-formulation.md, sddp-algorithm.md, solver-abstraction.md, solver-workspaces.md, memory-architecture.md, hybrid-parallelism.md, communication-patterns.md, slurm-deployment.md , decision-log.md
implementation-ordering.mdcross-reference-index.md, training-loop.md, simulation-architecture.md, cli-and-lifecycle.md, risk-measure-trait.md, cut-selection-trait.md, horizon-mode-trait.md, sampling-scheme-trait.md, stopping-rule-trait.md, solver-interface-trait.md, communicator-trait.md, backend-selection.md, configuration-reference.md
spec-gap-inventory.mdimplementation-ordering.md, cross-reference-index.md, training-loop.md, solver-abstraction.md, solver-interface-trait.md, internal-structures.md, input-loading-pipeline.md, scenario-generation.md, cut-management-impl.md, production-scale-reference.md, configuration-reference.md, communicator-trait.md, backend-ferrompi.md, convergence-monitoring.md
ecosystem-guidelines.mdimplementation-ordering.md, spec-gap-inventory.md, communicator-trait.md, backend-testing.md, solver-interface-trait.md, solver-workspaces.md, cut-selection-trait.md, validation-architecture.md, python-bindings.md, design-principles.md
ecosystem-vision.mddesign-principles.md, ecosystem-guidelines.md, implementation-ordering.md, solver-abstraction.md, scenario-generation.md
decision-log.mdsolver-abstraction.md, binary-formats.md, input-directory-structure.md, solver-interface-trait.md, memory-architecture.md, hybrid-parallelism.md, python-bindings.md, design-principles.md, production-scale-reference.md, cut-selection-trait.md, scenario-generation.md

Math

Spec FileReferences
sddp-algorithm.mdnotation-conventions.md, lp-formulation.md, cut-management.md, par-inflow-model.md, discount-rate.md, infinite-horizon.md, upper-bound-evaluation.md, stopping-rules.md, risk-measures.md, penalty-system.md, equipment-formulations.md, scenario-generation.md, deferred.md, production-scale-reference.md
lp-formulation.mdnotation-conventions.md, system-elements.md, penalty-system.md, input-system-entities.md, sddp-algorithm.md, par-inflow-model.md, hydro-production-models.md, cut-management.md, equipment-formulations.md
system-elements.mdnotation-conventions.md, lp-formulation.md, equipment-formulations.md, hydro-production-models.md, deferred.md
block-formulations.mdnotation-conventions.md, system-elements.md, lp-formulation.md, cut-management.md, hydro-production-models.md, input-scenarios.md, training-loop.md, simulation-architecture.md, checkpointing.md, deferred.md
hydro-production-models.mdnotation-conventions.md, system-elements.md, lp-formulation.md, penalty-system.md, input-system-entities.md, input-hydro-extensions.md, cut-management.md, deferred.md, simulation-architecture.md
cut-management.mdlp-formulation.md, par-inflow-model.md, notation-conventions.md, penalty-system.md, binary-formats.md, sddp-algorithm.md, scenario-generation.md, stopping-rules.md, discount-rate.md, risk-measures.md, deferred.md, configuration-reference.md
discount-rate.mdinput-scenarios.md, sddp-algorithm.md, cut-management.md, stopping-rules.md, upper-bound-evaluation.md, infinite-horizon.md, configuration-reference.md
infinite-horizon.mddiscount-rate.md, input-scenarios.md, sddp-algorithm.md, cut-management.md, stopping-rules.md, configuration-reference.md
risk-measures.mdnotation-conventions.md, sddp-algorithm.md, cut-management.md, stopping-rules.md, discount-rate.md, infinite-horizon.md, upper-bound-evaluation.md, input-scenarios.md
inflow-nonnegativity.mdlp-formulation.md, par-inflow-model.md, penalty-system.md, scenario-generation.md, notation-conventions.md, configuration-reference.md
par-inflow-model.mdinput-scenarios.md, lp-formulation.md, inflow-nonnegativity.md, scenario-generation.md, notation-conventions.md, internal-structures.md
equipment-formulations.mdnotation-conventions.md, system-elements.md, lp-formulation.md, hydro-production-models.md, penalty-system.md, input-system-entities.md, input-constraints.md, block-formulations.md, deferred.md
stopping-rules.mdnotation-conventions.md, sddp-algorithm.md, cut-management.md, upper-bound-evaluation.md, risk-measures.md, configuration-reference.md
upper-bound-evaluation.mdsddp-algorithm.md, notation-conventions.md, discount-rate.md, infinite-horizon.md, cut-management.md, stopping-rules.md, risk-measures.md, binary-formats.md, input-directory-structure.md, configuration-reference.md

Data Model

Spec FileReferences
input-directory-structure.mddesign-principles.md, configuration-reference.md, penalty-system.md, input-system-entities.md, input-hydro-extensions.md, input-scenarios.md, input-constraints.md, internal-structures.md, binary-formats.md, scenario-generation.md, production-scale-reference.md
input-system-entities.mdinput-directory-structure.md, input-hydro-extensions.md, input-constraints.md, internal-structures.md, penalty-system.md, design-principles.md, system-elements.md, equipment-formulations.md, hydro-production-models.md, deferred.md
input-hydro-extensions.mdinput-system-entities.md, input-directory-structure.md, input-constraints.md, hydro-production-models.md, lp-formulation.md, system-elements.md, deferred.md, design-principles.md
input-scenarios.mdinput-constraints.md, input-system-entities.md, input-directory-structure.md, par-inflow-model.md, risk-measures.md, block-formulations.md, discount-rate.md, scenario-generation.md, deferred.md, design-principles.md
input-constraints.mdinput-system-entities.md, input-hydro-extensions.md, input-scenarios.md, input-directory-structure.md, binary-formats.md, lp-formulation.md, cut-management.md, sddp-algorithm.md, penalty-system.md, design-principles.md
penalty-system.mdinput-system-entities.md, input-constraints.md, input-hydro-extensions.md, internal-structures.md, lp-formulation.md, configuration-reference.md, design-principles.md
internal-structures.mdinput-system-entities.md, input-hydro-extensions.md, input-constraints.md, input-scenarios.md, penalty-system.md, binary-formats.md, scenario-generation.md, design-principles.md
output-schemas.mdoutput-infrastructure.md, input-system-entities.md, penalty-system.md, input-constraints.md, lp-formulation.md, system-elements.md, risk-measures.md, upper-bound-evaluation.md, stopping-rules.md, discount-rate.md, inflow-nonnegativity.md, deferred.md
output-infrastructure.mdoutput-schemas.md, binary-formats.md, input-system-entities.md, penalty-system.md, configuration-reference.md, input-directory-structure.md, production-scale-reference.md, stopping-rules.md, cut-management.md, risk-measures.md, upper-bound-evaluation.md, block-formulations.md, design-principles.md, input-loading-pipeline.md, simulation-architecture.md, training-loop.md
binary-formats.mdinternal-structures.md, output-schemas.md, output-infrastructure.md, penalty-system.md, input-constraints.md, sddp-algorithm.md, cut-management.md, solver-abstraction.md, input-loading-pipeline.md , decision-log.md

Architecture

Spec FileReferences
training-loop.mdsddp-algorithm.md, cut-management.md, cut-management-impl.md, cut-selection-trait.md, stopping-rules.md, risk-measures.md, work-distribution.md, convergence-monitoring.md, input-loading-pipeline.md, input-constraints.md, input-scenarios.md, scenario-generation.md, penalty-system.md, solver-abstraction.md, solver-workspaces.md, checkpointing.md, deferred.md, structured-output.md, terminal-ui.md, mcp-server.md, python-bindings.md, communicator-trait.md, backend-local.md, synchronization.md, decision-log.md
simulation-architecture.mdcli-and-lifecycle.md, scenario-generation.md, training-loop.md, solver-interface-trait.md, communicator-trait.md, internal-structures.md, binary-formats.md, block-formulations.md, risk-measures.md, discount-rate.md, lp-formulation.md, penalty-system.md, output-schemas.md, output-infrastructure.md, deferred.md
cli-and-lifecycle.mdconfiguration-reference.md, input-loading-pipeline.md, validation-architecture.md, design-principles.md, production-scale-reference.md, output-infrastructure.md, slurm-deployment.md
validation-architecture.mdcli-and-lifecycle.md, input-loading-pipeline.md, design-principles.md, input-directory-structure.md, input-system-entities.md, input-scenarios.md, input-constraints.md, input-hydro-extensions.md, penalty-system.md, stopping-rules.md, discount-rate.md, risk-measures.md, block-formulations.md, hydro-production-models.md, par-inflow-model.md, scenario-generation.md, deferred.md
input-loading-pipeline.mdinput-directory-structure.md, internal-structures.md, cli-and-lifecycle.md, validation-architecture.md, design-principles.md, configuration-reference.md, input-system-entities.md, input-scenarios.md, input-constraints.md, par-inflow-model.md, binary-formats.md, penalty-system.md
scenario-generation.mdpar-inflow-model.md, inflow-nonnegativity.md, sddp-algorithm.md, input-scenarios.md, input-system-entities.md, validation-architecture.md, input-loading-pipeline.md, cli-and-lifecycle.md, training-loop.md, deferred.md, cut-selection-trait.md, hybrid-parallelism.md, shared-memory-aggregation.md, work-distribution.md
solver-abstraction.mdsolver-workspaces.md, solver-highs-impl.md, solver-clp-impl.md, lp-formulation.md, cut-management.md, training-loop.md, binary-formats.md, internal-structures.md, hybrid-parallelism.md, memory-architecture.md, shared-memory-aggregation.md, configuration-reference.md , decision-log.md
solver-highs-impl.mdsolver-abstraction.md, solver-clp-impl.md, solver-workspaces.md, lp-formulation.md, cut-management.md, training-loop.md, binary-formats.md, hybrid-parallelism.md, memory-architecture.md, configuration-reference.md
solver-clp-impl.mdsolver-abstraction.md, solver-highs-impl.md, solver-workspaces.md, lp-formulation.md, cut-management.md, training-loop.md, binary-formats.md, hybrid-parallelism.md, memory-architecture.md, configuration-reference.md
solver-workspaces.mdsolver-abstraction.md, solver-highs-impl.md, solver-clp-impl.md, lp-formulation.md, cut-management.md, training-loop.md, hybrid-parallelism.md, memory-architecture.md, binary-formats.md, configuration-reference.md
performance-adaptation-layer.mdinternal-structures.md, binary-formats.md, solver-abstraction.md, solver-workspaces.md, training-loop.md, scenario-generation.md, cut-management-impl.md, cli-and-lifecycle.md, input-loading-pipeline.md, validation-architecture.md, solver-interface-trait.md, design-principles.md, ecosystem-guidelines.md, notation-conventions.md, memory-architecture.md, par-inflow-model.md, hydro-production-models.md
cut-management-impl.mdcut-management.md, cut-selection-trait.md, solver-abstraction.md, solver-workspaces.md, shared-memory-aggregation.md, binary-formats.md, training-loop.md, convergence-monitoring.md, risk-measures.md, lp-formulation.md, scenario-generation.md, hybrid-parallelism.md, synchronization.md, communicator-trait.md, work-distribution.md, checkpointing.md, configuration-reference.md, decision-log.md
convergence-monitoring.mdstopping-rules.md, upper-bound-evaluation.md, risk-measures.md, infinite-horizon.md, training-loop.md, configuration-reference.md
extension-points.mdtraining-loop.md, risk-measures.md, sddp-algorithm.md, infinite-horizon.md, discount-rate.md, scenario-generation.md, input-scenarios.md, configuration-reference.md, solver-abstraction.md, deferred.md
risk-measure-trait.mdrisk-measures.md, cut-management.md, cut-management-impl.md, extension-points.md, training-loop.md, input-scenarios.md, communicator-trait.md, solver-abstraction.md
risk-measure-testing.mdrisk-measure-trait.md, risk-measures.md, cut-management.md, extension-points.md, backend-testing.md
horizon-mode-trait.mdinfinite-horizon.md, discount-rate.md, sddp-algorithm.md, extension-points.md, training-loop.md, input-scenarios.md, cut-management.md, stopping-rules.md, risk-measure-trait.md, communicator-trait.md, solver-abstraction.md, configuration-reference.md
horizon-mode-testing.mdhorizon-mode-trait.md, infinite-horizon.md, discount-rate.md, extension-points.md, risk-measure-testing.md, backend-testing.md
sampling-scheme-trait.mdscenario-generation.md, extension-points.md, training-loop.md, par-inflow-model.md, input-scenarios.md, validation-architecture.md, risk-measure-trait.md, horizon-mode-trait.md, communicator-trait.md, solver-abstraction.md, deferred.md, work-distribution.md
sampling-scheme-testing.mdsampling-scheme-trait.md, scenario-generation.md, extension-points.md, par-inflow-model.md, input-scenarios.md, risk-measure-testing.md, horizon-mode-testing.md, backend-testing.md, work-distribution.md
cut-selection-trait.mdcut-management.md, cut-management-impl.md, extension-points.md, training-loop.md, solver-abstraction.md, solver-workspaces.md, configuration-reference.md, binary-formats.md, convergence-monitoring.md, risk-measure-trait.md, horizon-mode-trait.md, sampling-scheme-trait.md, communicator-trait.md, work-distribution.md, synchronization.md, shared-memory-aggregation.md, decision-log.md
cut-selection-testing.mdcut-selection-trait.md, cut-management.md, cut-management-impl.md, extension-points.md, backend-testing.md, risk-measure-testing.md, horizon-mode-testing.md, sampling-scheme-testing.md, solver-workspaces.md, training-loop.md, work-distribution.md, synchronization.md, communicator-trait.md, decision-log.md
stopping-rule-trait.mdstopping-rules.md, convergence-monitoring.md, risk-measures.md, extension-points.md, training-loop.md, configuration-reference.md, upper-bound-evaluation.md, risk-measure-trait.md, horizon-mode-trait.md, sampling-scheme-trait.md, cut-selection-trait.md, communicator-trait.md
stopping-rule-testing.mdstopping-rule-trait.md, stopping-rules.md, convergence-monitoring.md, extension-points.md, backend-testing.md, risk-measure-testing.md, horizon-mode-testing.md, sampling-scheme-testing.md, cut-selection-testing.md, training-loop.md, upper-bound-evaluation.md
solver-interface-trait.mdsolver-abstraction.md, solver-workspaces.md, solver-highs-impl.md, solver-clp-impl.md, communicator-trait.md, backend-testing.md, extension-points.md, training-loop.md, cut-management-impl.md, lp-formulation.md, binary-formats.md, internal-structures.md, hybrid-parallelism.md, memory-architecture.md , decision-log.md
solver-interface-testing.mdsolver-interface-trait.md, solver-abstraction.md, solver-highs-impl.md, solver-clp-impl.md, backend-testing.md, risk-measure-testing.md, cut-selection-testing.md, training-loop.md, cut-management-impl.md, lp-formulation.md, binary-formats.md, solver-workspaces.md

HPC

Spec FileReferences
work-distribution.mdhybrid-parallelism.md, training-loop.md, sddp-algorithm.md, solver-workspaces.md, cut-management-impl.md, scenario-generation.md, synchronization.md, communication-patterns.md, communicator-trait.md, shared-memory-aggregation.md, memory-architecture.md, deferred.md
hybrid-parallelism.mdbackend-selection.md, communicator-trait.md, backend-ferrompi.md, backend-local.md, sddp-algorithm.md, training-loop.md, cli-and-lifecycle.md, solver-abstraction.md, solver-workspaces.md, work-distribution.md, synchronization.md, communication-patterns.md, memory-architecture.md, shared-memory-aggregation.md, checkpointing.md, slurm-deployment.md, design-principles.md, python-bindings.md, mcp-server.md, scenario-generation.md
communication-patterns.mdcommunicator-trait.md, backend-selection.md, backend-ferrompi.md, backend-tcp.md, backend-shm.md, backend-local.md, synchronization.md, work-distribution.md, cut-management-impl.md, hybrid-parallelism.md, convergence-monitoring.md, training-loop.md, shared-memory-aggregation.md, memory-architecture.md, production-scale-reference.md
memory-architecture.mdsolver-workspaces.md, solver-abstraction.md, shared-memory-aggregation.md, communication-patterns.md, synchronization.md, hybrid-parallelism.md, scenario-generation.md, cut-management-impl.md, training-loop.md, internal-structures.md , decision-log.md
shared-memory-aggregation.mdcommunication-patterns.md, synchronization.md, communicator-trait.md, backend-local.md, scenario-generation.md, cut-management-impl.md, cut-selection-trait.md, work-distribution.md, solver-abstraction.md, memory-architecture.md, output-schemas.md, decision-log.md
checkpointing.mdbinary-formats.md, output-infrastructure.md, output-schemas.md, cli-and-lifecycle.md, convergence-monitoring.md, scenario-generation.md, solver-workspaces.md, training-loop.md, shared-memory-aggregation.md, memory-architecture.md, slurm-deployment.md, deferred.md
slurm-deployment.mdhybrid-parallelism.md, memory-architecture.md, checkpointing.md, cli-and-lifecycle.md, shared-memory-aggregation.md, output-schemas.md, work-distribution.md
synchronization.mdtraining-loop.md, sddp-algorithm.md, cut-selection-trait.md, cut-management-impl.md, work-distribution.md, hybrid-parallelism.md, convergence-monitoring.md, communication-patterns.md, communicator-trait.md, shared-memory-aggregation.md, memory-architecture.md, decision-log.md
communicator-trait.mdcommunication-patterns.md, shared-memory-aggregation.md, hybrid-parallelism.md, memory-architecture.md, work-distribution.md, design-principles.md, synchronization.md, solver-abstraction.md
backend-selection.mdcommunicator-trait.md, solver-abstraction.md, hybrid-parallelism.md, cli-and-lifecycle.md, design-principles.md, structured-output.md, python-bindings.md, mcp-server.md
backend-ferrompi.mdcommunicator-trait.md, communication-patterns.md, hybrid-parallelism.md, backend-selection.md, solver-abstraction.md
backend-local.mdcommunicator-trait.md, hybrid-parallelism.md, training-loop.md, backend-selection.md, shared-memory-aggregation.md, solver-abstraction.md, python-bindings.md, mcp-server.md
backend-tcp.mdcommunicator-trait.md, communication-patterns.md, backend-selection.md, solver-abstraction.md, python-bindings.md, hybrid-parallelism.md
backend-shm.mdcommunicator-trait.md, communication-patterns.md, shared-memory-aggregation.md, hybrid-parallelism.md, memory-architecture.md, backend-ferrompi.md, backend-tcp.md, backend-selection.md, solver-abstraction.md
backend-testing.mdcommunicator-trait.md, backend-ferrompi.md, backend-local.md, backend-tcp.md, backend-shm.md, shared-memory-aggregation.md, backend-selection.md, python-bindings.md

Configuration

Deferred

Interfaces


4. Incoming Cross-Reference Table

For each spec file, this table shows which other specs reference it in their ## Cross-References sections. This is the inverse of Component 3.

Overview

Spec FileReferenced By
design-principles.mdnotation-conventions.md, production-scale-reference.md, input-directory-structure.md, input-system-entities.md, input-hydro-extensions.md, input-scenarios.md, input-constraints.md, penalty-system.md, internal-structures.md, output-infrastructure.md, cli-and-lifecycle.md, validation-architecture.md, input-loading-pipeline.md, hybrid-parallelism.md, communicator-trait.md, backend-selection.md, ecosystem-guidelines.md, ecosystem-vision.md, structured-output.md, python-bindings.md, performance-adaptation-layer.md, decision-log.md
decision-log.mdsolver-abstraction.md, solver-interface-trait.md, binary-formats.md, memory-architecture.md, python-bindings.md, design-principles.md, production-scale-reference.md
notation-conventions.mddesign-principles.md, production-scale-reference.md, sddp-algorithm.md, lp-formulation.md, system-elements.md, block-formulations.md, hydro-production-models.md, cut-management.md, risk-measures.md, inflow-nonnegativity.md, par-inflow-model.md, equipment-formulations.md, stopping-rules.md, upper-bound-evaluation.md, performance-adaptation-layer.md
production-scale-reference.mddesign-principles.md, notation-conventions.md, sddp-algorithm.md, input-directory-structure.md, output-infrastructure.md, cli-and-lifecycle.md, communication-patterns.md, spec-gap-inventory.md , decision-log.md
implementation-ordering.mdspec-gap-inventory.md , ecosystem-guidelines.md, ecosystem-vision.md
spec-gap-inventory.mdecosystem-guidelines.md
ecosystem-guidelines.mdecosystem-vision.md, performance-adaptation-layer.md
ecosystem-vision.md(none – leaf spec)

Math

Spec FileReferenced By
sddp-algorithm.mdnotation-conventions.md, production-scale-reference.md, lp-formulation.md, cut-management.md, discount-rate.md, infinite-horizon.md, risk-measures.md, stopping-rules.md, upper-bound-evaluation.md, input-constraints.md, binary-formats.md, training-loop.md, scenario-generation.md, extension-points.md, work-distribution.md, hybrid-parallelism.md, synchronization.md, configuration-reference.md, deferred.md, horizon-mode-trait.md
lp-formulation.mddesign-principles.md, notation-conventions.md, production-scale-reference.md, sddp-algorithm.md, system-elements.md, block-formulations.md, hydro-production-models.md, cut-management.md, inflow-nonnegativity.md, par-inflow-model.md, equipment-formulations.md, input-hydro-extensions.md, input-constraints.md, penalty-system.md, output-schemas.md, simulation-architecture.md, solver-abstraction.md, solver-highs-impl.md, solver-clp-impl.md, solver-workspaces.md, cut-management-impl.md, configuration-reference.md, solver-interface-trait.md, solver-interface-testing.md
system-elements.mdlp-formulation.md, block-formulations.md, hydro-production-models.md, equipment-formulations.md, input-system-entities.md, input-hydro-extensions.md, output-schemas.md
block-formulations.mdequipment-formulations.md, input-scenarios.md, output-infrastructure.md, simulation-architecture.md, validation-architecture.md, configuration-reference.md, deferred.md
hydro-production-models.mdnotation-conventions.md, system-elements.md, block-formulations.md, equipment-formulations.md, input-system-entities.md, input-hydro-extensions.md, validation-architecture.md, configuration-reference.md, lp-formulation.md, deferred.md, performance-adaptation-layer.md
cut-management.mdnotation-conventions.md, sddp-algorithm.md, block-formulations.md, hydro-production-models.md, discount-rate.md, infinite-horizon.md, risk-measures.md, stopping-rules.md, upper-bound-evaluation.md, input-constraints.md, output-infrastructure.md, binary-formats.md, training-loop.md, solver-abstraction.md, solver-highs-impl.md, solver-clp-impl.md, solver-workspaces.md, cut-management-impl.md, lp-formulation.md, configuration-reference.md, deferred.md, risk-measure-trait.md, risk-measure-testing.md, horizon-mode-trait.md, cut-selection-trait.md, cut-selection-testing.md
discount-rate.mdsddp-algorithm.md, cut-management.md, risk-measures.md, infinite-horizon.md, upper-bound-evaluation.md, output-schemas.md, simulation-architecture.md, validation-architecture.md, extension-points.md, configuration-reference.md, input-scenarios.md, horizon-mode-trait.md, horizon-mode-testing.md
infinite-horizon.mdsddp-algorithm.md, discount-rate.md, risk-measures.md, upper-bound-evaluation.md, convergence-monitoring.md, extension-points.md, configuration-reference.md, horizon-mode-trait.md, horizon-mode-testing.md
risk-measures.mdsddp-algorithm.md, cut-management.md, stopping-rules.md, upper-bound-evaluation.md, input-scenarios.md, output-schemas.md, output-infrastructure.md, training-loop.md, simulation-architecture.md, validation-architecture.md, cut-management-impl.md, convergence-monitoring.md, extension-points.md, configuration-reference.md, deferred.md, risk-measure-trait.md, risk-measure-testing.md, stopping-rule-trait.md
inflow-nonnegativity.mdpar-inflow-model.md, output-schemas.md, scenario-generation.md, configuration-reference.md, sampling-scheme-trait.md, sampling-scheme-testing.md
par-inflow-model.mdnotation-conventions.md, sddp-algorithm.md, lp-formulation.md, cut-management.md, inflow-nonnegativity.md, input-scenarios.md, validation-architecture.md, input-loading-pipeline.md, scenario-generation.md, configuration-reference.md, deferred.md, performance-adaptation-layer.md
equipment-formulations.mdnotation-conventions.md, sddp-algorithm.md, lp-formulation.md, system-elements.md, input-system-entities.md, deferred.md
stopping-rules.mdsddp-algorithm.md, cut-management.md, discount-rate.md, infinite-horizon.md, risk-measures.md, upper-bound-evaluation.md, output-schemas.md, output-infrastructure.md, training-loop.md, validation-architecture.md, convergence-monitoring.md, configuration-reference.md, horizon-mode-trait.md, stopping-rule-trait.md, stopping-rule-testing.md
upper-bound-evaluation.mdsddp-algorithm.md, discount-rate.md, risk-measures.md, stopping-rules.md, output-schemas.md, output-infrastructure.md, convergence-monitoring.md, configuration-reference.md, stopping-rule-trait.md, stopping-rule-testing.md

Data Model

Spec FileReferenced By
input-directory-structure.mdinput-system-entities.md, input-hydro-extensions.md, input-scenarios.md, input-constraints.md, output-infrastructure.md, upper-bound-evaluation.md, validation-architecture.md, input-loading-pipeline.md, design-principles.md, configuration-reference.md , decision-log.md
input-system-entities.mdlp-formulation.md, hydro-production-models.md, equipment-formulations.md, input-directory-structure.md, input-constraints.md, input-scenarios.md, penalty-system.md, internal-structures.md, output-schemas.md, output-infrastructure.md, validation-architecture.md, input-loading-pipeline.md, scenario-generation.md, input-hydro-extensions.md, deferred.md , python-bindings.md
input-hydro-extensions.mdinput-directory-structure.md, input-system-entities.md, penalty-system.md, internal-structures.md, hydro-production-models.md, input-constraints.md, validation-architecture.md
input-scenarios.mdblock-formulations.md, discount-rate.md, infinite-horizon.md, risk-measures.md, par-inflow-model.md, input-directory-structure.md, input-constraints.md, internal-structures.md, training-loop.md, validation-architecture.md, input-loading-pipeline.md, scenario-generation.md, extension-points.md, configuration-reference.md, deferred.md, risk-measure-trait.md, horizon-mode-trait.md, sampling-scheme-trait.md, sampling-scheme-testing.md
input-constraints.mdequipment-formulations.md, input-directory-structure.md, input-system-entities.md, input-hydro-extensions.md, input-scenarios.md, penalty-system.md, internal-structures.md, output-schemas.md, binary-formats.md, training-loop.md, validation-architecture.md, input-loading-pipeline.md
penalty-system.mdsddp-algorithm.md, lp-formulation.md, hydro-production-models.md, cut-management.md, equipment-formulations.md, inflow-nonnegativity.md, input-directory-structure.md, input-system-entities.md, internal-structures.md, output-schemas.md, output-infrastructure.md, binary-formats.md, training-loop.md, validation-architecture.md, input-loading-pipeline.md, input-constraints.md, configuration-reference.md, simulation-architecture.md
internal-structures.mdinput-directory-structure.md, input-system-entities.md, penalty-system.md, binary-formats.md, input-loading-pipeline.md, solver-abstraction.md, memory-architecture.md, solver-interface-trait.md, spec-gap-inventory.md, simulation-architecture.md, par-inflow-model.md, design-principles.md, performance-adaptation-layer.md
output-schemas.mdoutput-infrastructure.md, binary-formats.md, simulation-architecture.md, checkpointing.md, slurm-deployment.md, shared-memory-aggregation.md, design-principles.md , mcp-server.md, python-bindings.md
output-infrastructure.mdoutput-schemas.md, cli-and-lifecycle.md, simulation-architecture.md, checkpointing.md, binary-formats.md, structured-output.md
binary-formats.mdcut-management.md, upper-bound-evaluation.md, input-directory-structure.md, input-constraints.md, internal-structures.md, output-infrastructure.md, solver-abstraction.md, solver-highs-impl.md, solver-clp-impl.md, solver-workspaces.md, cut-management-impl.md, input-loading-pipeline.md, checkpointing.md, configuration-reference.md, deferred.md, cut-selection-trait.md, solver-interface-trait.md, solver-interface-testing.md, simulation-architecture.md, design-principles.md, python-bindings.md, performance-adaptation-layer.md, decision-log.md

Architecture

Spec FileReferenced By
training-loop.mdblock-formulations.md, simulation-architecture.md, scenario-generation.md, solver-abstraction.md, solver-highs-impl.md, solver-clp-impl.md, solver-workspaces.md, cut-management-impl.md, convergence-monitoring.md, extension-points.md, work-distribution.md, hybrid-parallelism.md, communication-patterns.md, memory-architecture.md, checkpointing.md, synchronization.md, deferred.md, backend-local.md, risk-measure-trait.md, horizon-mode-trait.md, sampling-scheme-trait.md, cut-selection-trait.md, cut-selection-testing.md, stopping-rule-trait.md, stopping-rule-testing.md, solver-interface-trait.md, solver-interface-testing.md, implementation-ordering.md, spec-gap-inventory.md, output-infrastructure.md, design-principles.md, structured-output.md, mcp-server.md, terminal-ui.md, performance-adaptation-layer.md
simulation-architecture.mdblock-formulations.md, hydro-production-models.md, deferred.md, output-infrastructure.md
cli-and-lifecycle.mdsimulation-architecture.md, validation-architecture.md, input-loading-pipeline.md, scenario-generation.md, hybrid-parallelism.md, checkpointing.md, slurm-deployment.md, backend-selection.md, implementation-ordering.md , structured-output.md, performance-adaptation-layer.md
validation-architecture.mddesign-principles.md, cli-and-lifecycle.md, input-loading-pipeline.md, scenario-generation.md, sampling-scheme-trait.md , ecosystem-guidelines.md , structured-output.md, mcp-server.md, python-bindings.md, performance-adaptation-layer.md
input-loading-pipeline.mdcli-and-lifecycle.md, validation-architecture.md, training-loop.md, scenario-generation.md, internal-structures.md, output-infrastructure.md, binary-formats.md, design-principles.md, performance-adaptation-layer.md
scenario-generation.mdsddp-algorithm.md, cut-management.md, inflow-nonnegativity.md, par-inflow-model.md, input-directory-structure.md, input-scenarios.md, internal-structures.md, training-loop.md, simulation-architecture.md, validation-architecture.md, cut-management-impl.md, extension-points.md, work-distribution.md, memory-architecture.md, shared-memory-aggregation.md, checkpointing.md, configuration-reference.md, deferred.md, sampling-scheme-trait.md, sampling-scheme-testing.md, spec-gap-inventory.md, ecosystem-vision.md, performance-adaptation-layer.md, decision-log.md, hybrid-parallelism.md
solver-abstraction.mdnotation-conventions.md, production-scale-reference.md, binary-formats.md, training-loop.md, solver-highs-impl.md, solver-clp-impl.md, solver-workspaces.md, cut-management-impl.md, extension-points.md, hybrid-parallelism.md, memory-architecture.md, shared-memory-aggregation.md, communicator-trait.md, backend-selection.md, backend-ferrompi.md, backend-local.md, backend-tcp.md, backend-shm.md, risk-measure-trait.md, horizon-mode-trait.md, sampling-scheme-trait.md, cut-selection-trait.md, solver-interface-trait.md, solver-interface-testing.md, spec-gap-inventory.md, ecosystem-vision.md, performance-adaptation-layer.md , decision-log.md
solver-highs-impl.mdsolver-abstraction.md, solver-clp-impl.md, solver-workspaces.md, solver-interface-trait.md, solver-interface-testing.md
solver-clp-impl.mdsolver-abstraction.md, solver-highs-impl.md, solver-workspaces.md, solver-interface-trait.md, solver-interface-testing.md
solver-workspaces.mdproduction-scale-reference.md, training-loop.md, solver-abstraction.md, solver-highs-impl.md, solver-clp-impl.md, cut-management-impl.md, work-distribution.md, hybrid-parallelism.md, memory-architecture.md, checkpointing.md, cut-selection-trait.md, cut-selection-testing.md, solver-interface-trait.md, solver-interface-testing.md, ecosystem-guidelines.md, design-principles.md, performance-adaptation-layer.md
performance-adaptation-layer.md(none)
cut-management-impl.mdtraining-loop.md, work-distribution.md, communication-patterns.md, memory-architecture.md, shared-memory-aggregation.md, configuration-reference.md, risk-measure-trait.md, cut-selection-trait.md, cut-selection-testing.md, solver-interface-trait.md, solver-interface-testing.md, spec-gap-inventory.md, performance-adaptation-layer.md
convergence-monitoring.mdtraining-loop.md, cut-management-impl.md, communication-patterns.md, checkpointing.md, synchronization.md, cut-selection-trait.md, stopping-rule-trait.md, stopping-rule-testing.md, spec-gap-inventory.md , design-principles.md, structured-output.md, mcp-server.md, python-bindings.md, terminal-ui.md
extension-points.mdconfiguration-reference.md, risk-measure-trait.md, risk-measure-testing.md, horizon-mode-trait.md, horizon-mode-testing.md, sampling-scheme-trait.md, sampling-scheme-testing.md, cut-selection-trait.md, cut-selection-testing.md, stopping-rule-trait.md, stopping-rule-testing.md, solver-interface-trait.md
risk-measure-trait.mdrisk-measure-testing.md, horizon-mode-trait.md, sampling-scheme-trait.md, cut-selection-trait.md, stopping-rule-trait.md, implementation-ordering.md
risk-measure-testing.mdhorizon-mode-testing.md, sampling-scheme-testing.md, cut-selection-testing.md, stopping-rule-testing.md, solver-interface-testing.md
horizon-mode-trait.mdhorizon-mode-testing.md, sampling-scheme-trait.md, cut-selection-trait.md, stopping-rule-trait.md, implementation-ordering.md
horizon-mode-testing.mdsampling-scheme-testing.md, cut-selection-testing.md, stopping-rule-testing.md
sampling-scheme-trait.mdsampling-scheme-testing.md, cut-selection-trait.md, stopping-rule-trait.md, implementation-ordering.md
sampling-scheme-testing.mdcut-selection-testing.md, stopping-rule-testing.md
cut-selection-trait.mdcut-selection-testing.md, cut-management-impl.md, training-loop.md, synchronization.md, shared-memory-aggregation.md, stopping-rule-trait.md, implementation-ordering.md, ecosystem-guidelines.md, scenario-generation.md
cut-selection-testing.mdstopping-rule-testing.md, solver-interface-testing.md
stopping-rule-trait.mdstopping-rule-testing.md, implementation-ordering.md
stopping-rule-testing.md(none – leaf spec)
solver-interface-trait.mdsolver-interface-testing.md, implementation-ordering.md, spec-gap-inventory.md, ecosystem-guidelines.md, simulation-architecture.md, performance-adaptation-layer.md , decision-log.md
solver-interface-testing.md(none – leaf spec)

HPC

Spec FileReferenced By
work-distribution.mdtraining-loop.md, hybrid-parallelism.md, communication-patterns.md, synchronization.md, shared-memory-aggregation.md, slurm-deployment.md, communicator-trait.md, cut-selection-trait.md, cut-management-impl.md, cut-selection-testing.md, sampling-scheme-trait.md, sampling-scheme-testing.md, scenario-generation.md
hybrid-parallelism.mdproduction-scale-reference.md, solver-abstraction.md, solver-highs-impl.md, solver-clp-impl.md, solver-workspaces.md, cut-management-impl.md, work-distribution.md, communication-patterns.md, memory-architecture.md, synchronization.md, slurm-deployment.md, communicator-trait.md, backend-selection.md, backend-ferrompi.md, backend-local.md, backend-tcp.md, backend-shm.md, solver-interface-trait.md , python-bindings.md , decision-log.md, scenario-generation.md
communication-patterns.mdproduction-scale-reference.md, work-distribution.md, hybrid-parallelism.md, memory-architecture.md, shared-memory-aggregation.md, synchronization.md, communicator-trait.md, backend-ferrompi.md, backend-tcp.md, backend-shm.md
memory-architecture.mdproduction-scale-reference.md, solver-abstraction.md, solver-highs-impl.md, solver-clp-impl.md, solver-workspaces.md, work-distribution.md, hybrid-parallelism.md, communication-patterns.md, shared-memory-aggregation.md, checkpointing.md, slurm-deployment.md, synchronization.md, communicator-trait.md, backend-shm.md, solver-interface-trait.md , python-bindings.md, performance-adaptation-layer.md , decision-log.md
shared-memory-aggregation.mdwork-distribution.md, hybrid-parallelism.md, memory-architecture.md, checkpointing.md, slurm-deployment.md, communication-patterns.md, communicator-trait.md, backend-local.md, backend-shm.md, solver-abstraction.md, cut-selection-trait.md, synchronization.md, scenario-generation.md
checkpointing.mdblock-formulations.md, training-loop.md, cut-management-impl.md, hybrid-parallelism.md, slurm-deployment.md, deferred.md , terminal-ui.md
slurm-deployment.mdproduction-scale-reference.md, cli-and-lifecycle.md, hybrid-parallelism.md, checkpointing.md
synchronization.mdwork-distribution.md, hybrid-parallelism.md, communication-patterns.md, memory-architecture.md, shared-memory-aggregation.md, communicator-trait.md, cut-selection-trait.md, cut-management-impl.md, cut-selection-testing.md
communicator-trait.mdcommunication-patterns.md, hybrid-parallelism.md, synchronization.md, work-distribution.md, shared-memory-aggregation.md, training-loop.md, backend-selection.md, backend-ferrompi.md, backend-local.md, backend-tcp.md, backend-shm.md, risk-measure-trait.md, horizon-mode-trait.md, sampling-scheme-trait.md, cut-selection-trait.md, stopping-rule-trait.md, solver-interface-trait.md, implementation-ordering.md, spec-gap-inventory.md, ecosystem-guidelines.md, simulation-architecture.md, python-bindings.md, cut-management-impl.md, cut-selection-testing.md
backend-selection.mdhybrid-parallelism.md, communication-patterns.md, backend-ferrompi.md, backend-local.md, backend-tcp.md, backend-shm.md, implementation-ordering.md , python-bindings.md
backend-ferrompi.mdhybrid-parallelism.md, communication-patterns.md, backend-shm.md, spec-gap-inventory.md
backend-local.mdhybrid-parallelism.md, communication-patterns.md, training-loop.md, shared-memory-aggregation.md
backend-tcp.mdcommunication-patterns.md, backend-shm.md , python-bindings.md
backend-shm.mdcommunication-patterns.md , python-bindings.md
backend-testing.mdrisk-measure-testing.md, horizon-mode-testing.md, sampling-scheme-testing.md, cut-selection-testing.md, stopping-rule-testing.md, solver-interface-trait.md, solver-interface-testing.md , ecosystem-guidelines.md , python-bindings.md

Configuration

Deferred

Interfaces


5. Dependency Ordering

This is a global reading order for the entire 79-spec corpus. Specs that are referenced by the most other specs (most foundational) appear first. Within the same reference count, section order applies (overview, math, data-model, architecture, hpc, configuration, deferred, interfaces).

Note on errata: Seven section-number references were identified as incorrect in the Epic 03 audit (findings F-1, F-5, F-6, F-7, F-8, F-9, F-11) and corrected in Epic 06. All links and section numbers in this index are now accurate.

OrderSpec FileSectionIncoming References
1training-loop.mdarchitecture35
2solver-abstraction.mdarchitecture27
3configuration-reference.mdconfiguration27
4cut-management.mdmath26
5lp-formulation.mdmath24
6scenario-generation.mdarchitecture25
7binary-formats.mddata-model22
8communicator-trait.mdhpc24
9design-principles.mdoverview21
10sddp-algorithm.mdmath20
11input-scenarios.mddata-model19
12hybrid-parallelism.mdhpc20
13deferred.mddeferred19
14risk-measures.mdmath18
15penalty-system.mddata-model18
16solver-workspaces.mdarchitecture17
17memory-architecture.mdhpc17
18input-system-entities.mddata-model16
19notation-conventions.mdoverview15
20stopping-rules.mdmath15
21convergence-monitoring.mdarchitecture14
22discount-rate.mdmath13
23internal-structures.mddata-model13
24cut-management-impl.mdarchitecture13
25par-inflow-model.mdmath12
26input-constraints.mddata-model12
27extension-points.mdarchitecture12
28hydro-production-models.mdmath11
29cli-and-lifecycle.mdarchitecture11
30upper-bound-evaluation.mdmath10
31input-directory-structure.mddata-model10
32validation-architecture.mdarchitecture10
33communication-patterns.mdhpc10
34python-bindings.mdinterfaces10
35infinite-horizon.mdmath9
36output-schemas.mddata-model9
37input-loading-pipeline.mdarchitecture9
38backend-testing.mdhpc9
39shared-memory-aggregation.mdhpc13
40production-scale-reference.mdoverview8
41backend-selection.mdhpc8
42decision-log.mdoverview7
43block-formulations.mdmath7
44system-elements.mdmath7
45input-hydro-extensions.mddata-model7
46checkpointing.mdhpc7
47work-distribution.mdhpc13
48equipment-formulations.mdmath6
49inflow-nonnegativity.mdmath6
50output-infrastructure.mddata-model6
51risk-measure-trait.mdarchitecture6
52solver-interface-trait.mdarchitecture6
53synchronization.mdhpc9
54mcp-server.mdinterfaces6
55structured-output.mdinterfaces6
56horizon-mode-trait.mdarchitecture5
57risk-measure-testing.mdarchitecture5
58solver-clp-impl.mdarchitecture5
59solver-highs-impl.mdarchitecture5
60cut-selection-trait.mdarchitecture9
61sampling-scheme-trait.mdarchitecture4
62simulation-architecture.mdarchitecture4
63backend-ferrompi.mdhpc4
64backend-local.mdhpc4
65slurm-deployment.mdhpc4
66terminal-ui.mdinterfaces4
67implementation-ordering.mdoverview3
68horizon-mode-testing.mdarchitecture3
69backend-tcp.mdhpc3
70ecosystem-guidelines.mdoverview2
71cut-selection-testing.mdarchitecture2
72sampling-scheme-testing.mdarchitecture2
73stopping-rule-trait.mdarchitecture2
74backend-shm.mdhpc2
75spec-gap-inventory.mdoverview1
76ecosystem-vision.mdoverview0
77solver-interface-testing.mdarchitecture0
78stopping-rule-testing.mdarchitecture0
79performance-adaptation-layer.mdarchitecture0

Mathematical Formulations

This section contains the formal mathematical specifications that define Cobre’s optimization model. Together, these 14 specs describe the complete LP formulation solved at each stage of the SDDP algorithm, the stochastic processes that drive uncertainty, the cut management strategies that approximate the cost-to-go function, and the convergence machinery that determines when a policy is good enough.

Every constraint, variable bound, and algorithmic step that Cobre implements traces back to one of these pages. The specs are written to be precise enough to serve as a direct implementation reference: a developer should be able to read a spec and translate it into solver API calls without ambiguity. Where design choices exist (e.g., single-cut vs. multi-cut, constant vs. piecewise-linear productivity), each spec enumerates the supported variants and their configuration knobs.

The formulations assume familiarity with linear programming duality, the Bellman equation for multistage stochastic programs, and the basic SDDP decomposition scheme. Readers new to these topics should start with the Algorithm Reference section, which provides tutorial-style explanations, before diving into the specs here.

Reading Order

The specs have cross-references, so reading order matters. The following sequence builds concepts incrementally:

  1. SDDP Algorithm – Start here. Establishes the policy graph, state variables, Bellman recursion, and the single-cut vs. multi-cut distinction that the rest of the specs build on.
  2. System Elements – Defines every physical element (hydro plants, thermal units, buses, transmission lines, contracts) and its variables. Required context for reading any constraint formulation.
  3. LP Formulation – The complete stage subproblem: objective function, all constraint families, and the dual variables used for cut generation.
  4. Hydro Production Models – How water-to-energy conversion is modeled: constant productivity, FPHA hyperplanes, and linearized head.
  5. Equipment Formulations – Thermal dispatch, transmission limits, energy contracts, pumping stations, and non-controllable sources.
  6. Block Formulations – Parallel and chronological block structures, and how they affect constraint aggregation.
  7. Cut Management – Cut generation, aggregation, selection strategies (Level 1, LML1), and dominated-cut detection.
  8. PAR Inflow Model – The periodic autoregressive model for stochastic inflows: fitting, validation, and scenario generation.

The remaining specs can be read in any order after the first eight:

  • Discount Rate – Stage-dependent discount factors and their effect on the Bellman equation.
  • Infinite Horizon – Periodic policy graphs, cycle detection, and cross-cycle cut sharing.
  • Risk Measures – CVaR, convex combination with expectation, and risk-averse cut generation.
  • Inflow Non-Negativity – Strategies for handling negative synthetic inflows from the PAR model.
  • Stopping Rules – Iteration limits, time limits, bound stalling, and simulation-based gap tests.
  • Upper Bound Evaluation – Statistical upper bound computation and optimality gap estimation.

Spec Index

SpecDescriptionAlgorithm Reference
SDDP AlgorithmPolicy graph, state variables, Bellman recursion, single-cut vs. multi-cutSDDP Theory, Benders Decomposition
LP FormulationStage subproblem objective, constraints, and dual variablesForward and Backward Passes
System ElementsPhysical elements, their decision variables, and interconnections
Block FormulationsParallel and chronological blocks, policy compatibility validation
Hydro Production ModelsConstant productivity, FPHA hyperplanes, linearized head
Cut ManagementCut generation, aggregation, Level 1 / LML1 selection, dominance detectionCut Management, Cut Selection
Discount RateDiscounted Bellman equation, stage-dependent discount factors
Infinite HorizonPeriodic policy graph, cycle detection, cross-cycle cut sharingConvergence
Risk MeasuresCVaR, convex combination with expectation, risk-averse cuts, per-stage profilesRisk Measures, CVaR
Inflow Non-NegativityTruncation, penalty, and hybrid strategies for negative synthetic inflowsScenario Generation
PAR Inflow ModelPAR(p) model definition, stored vs. computed quantities, fitting, validationPAR(p) Models
Equipment FormulationsThermal, transmission, contracts, pumping, NCS, simulation-only enhancements
Stopping RulesIteration limit, time limit, bound stalling, simulation-based gap testConvergence
Upper Bound EvaluationInner approximation, Lipschitz interpolation, statistical gap computationConvergence

Conventions

All specs in this section use the notation defined in Notation Conventions. Index sets, symbol definitions, and unit conventions are established there and are not repeated in individual spec pages.

The System Elements spec extends that notation with the concrete variables and parameters for each power system component. It serves as a second prerequisite for reading any constraint formulation – the LP Formulation, Equipment Formulations, and Hydro Production Models specs all reference variables introduced there.

Data Model

This section specifies every data structure that flows into, through, and out of the Cobre solver. On the input side, that means the JSON registries that define physical entities (hydro plants, thermal units, buses, transmission lines), the Parquet tables that carry stage-varying bounds and stochastic parameters, the penalty cascade that guarantees LP feasibility, and the config.json file that controls all solver behavior. On the output side, it covers the schemas for training convergence reports, simulation result tables, MPI-partitioned file manifests, and the binary persistence formats used for warm-starting and resuming interrupted runs.

The specs are organized around the data lifecycle. Input specs describe what the user provides and how the solver validates and loads it. Internal structure specs describe the in-memory model that the solver builds from those inputs. Output specs describe what the solver produces and how distributed results are assembled. Binary format specs describe the FlatBuffers schemas used for zero-copy serialization of policy data (cuts, states, basis vectors). Together, these 10 specs fully define the contract between the user, the I/O layer (cobre-io), the data model library (cobre-core), and the MPI communication layer (ferrompi).

Every file path, column name, JSON key, and Parquet schema documented here is normative. The solver rejects inputs that do not conform to these specs, and the output schemas are guaranteed stable within a major version. Where design choices exist (e.g., JSON vs. Parquet for a given file, sparse vs. dense override tables), the rationale is stated inline using the format selection criteria from the Design Principles spec.

Reading Order

The specs have extensive cross-references, so reading order matters. The following sequence builds concepts from the filesystem inward:

  1. Input Directory Structure – Start here. Defines the case directory layout, the config.json schema, and the penalty summary that motivates the dedicated penalty spec.
  2. Input System Entities – The seven entity registries in system/: buses, lines, hydros, thermals, non-controllable sources, pumping stations, and energy contracts. Required context for reading any other input spec.
  3. Input Hydro Extensions – Hydro-specific extension files: geometry curves, stage-varying production model configuration, and precomputed FPHA hyperplanes.
  4. Input Scenarios – The stages.json schema (seasons, policy graph, blocks, risk measures), inflow and load models, correlation profiles, and external scenario injection.
  5. Input Constraints – Initial conditions, stage-varying entity bounds, exchange capacity factors, and generic linear constraints.
  6. Penalty System – The three-tier penalty cascade (global defaults, entity overrides, stage overrides), the full penalty inventory, and resolution semantics that guarantee LP feasibility.
  7. Internal Structures – The in-memory solver model built from input files: indexed entity tables, assembled LP matrices, and the runtime state that the forward and backward passes operate on.
  8. Output Schemas – Training convergence tables, simulation result Parquet files, and per-iteration diagnostic exports.
  9. Output Infrastructure – File manifests, MPI rank-partitioned output assembly, streaming vs. buffered write modes, and compression settings.
  10. Binary Formats – FlatBuffers schemas for policy persistence: cut coefficients, visited states, inner approximation vertices, and solver basis snapshots.

Spec Index

SpecDescriptionMath Reference
Input Directory StructureCase directory layout, config.json schema, penalty summary
Input System EntitiesSeven entity registries: buses, lines, hydros, thermals, NCS, pumping, contractsSystem Elements
Input Hydro ExtensionsHydro geometry curves, production model config, FPHA hyperplanesHydro Production Models
Input ScenariosStage definitions, policy graph, inflow/load models, correlations, external scenariosPAR Inflow Model, Risk Measures
Input ConstraintsInitial conditions, stage-varying bounds, exchange factors, generic constraintsLP Formulation
Penalty SystemThree-tier penalty cascade, full inventory, resolution semanticsLP Formulation
Internal StructuresIn-memory solver model: indexed tables, LP matrices, runtime stateLP Formulation, SDDP Algorithm
Output SchemasTraining convergence, simulation results, diagnostic exportsUpper Bound Evaluation, Stopping Rules
Output InfrastructureFile manifests, MPI-partitioned assembly, streaming writes, compression
Binary FormatsFlatBuffers schemas for cuts, states, vertices, basis persistenceCut Management

Conventions

All specs in this section follow the format selection criteria and declaration order invariance principle defined in Design Principles. In brief: JSON is used for human-editable structured objects with nested or optional fields (entity registries, configuration, correlation profiles); Parquet is used for typed columnar tabular data (stage-varying overrides, time series, scenario parameters); FlatBuffers is used for binary persistence where zero-copy deserialization matters (policy data). Declaration order within JSON arrays and Parquet rows never affects solver behavior – entities are identified by their id field, not by position.

The Notation Conventions spec establishes the index sets, symbols, and unit conventions used throughout. Column names in Parquet schemas and JSON keys are chosen to match the mathematical notation where practical (e.g., volume for \(v*{i,t}\), turbined for \(u*{i,t}\)).

Architecture

This section contains the architectural specifications that define how Cobre’s SDDP solver is structured at the software level. Where the Mathematical Formulations section defines what the solver computes and the Data Model section defines what data flows in and out, the architecture specs define how the solver is organized internally: the training loop that drives SDDP iteration, the simulation engine that evaluates trained policies, the solver abstraction layer that isolates LP solver dependencies, the scenario generation pipeline that produces correlated noise vectors, the input loading sequence that builds the in-memory model, the validation pipeline that rejects malformed inputs before any computation begins, the CLI entrypoint that orchestrates the full execution lifecycle, the convergence monitor that decides when to stop, the cut management implementation that maintains the future cost function, and the extension points that allow algorithm variants to be composed at configuration time.

Together, these 14 specs fully describe the runtime architecture of the Cobre solver. They are written at the behavioral level – specifying component responsibilities, interaction contracts, data flow, and parallelization strategy – without prescribing Rust module boundaries or struct layouts. A developer implementing a component should be able to read its architecture spec alongside the referenced math and data-model specs and produce a correct implementation without ambiguity. Where performance-critical design decisions exist (e.g., thread-trajectory affinity in the forward pass, streaming output in simulation, LP template cloning for solver workspaces, the performance adaptation layer that transforms domain types into solver-ready representations), each spec documents the rationale and the constraints that drove the choice.

The specs assume familiarity with the SDDP algorithm as described in SDDP Algorithm, the stage LP structure from LP Formulation, and the input/output contracts from the Data Model section. Readers new to the solver’s high-level design should start with CLI and Lifecycle, which maps the full execution sequence from process invocation to shutdown, before diving into the individual subsystem specs.

Reading Order

The specs have extensive cross-references, so reading order matters. The following sequence builds concepts from the outermost orchestration layer inward to the solver core:

  1. Training Loop – Start here. Defines the SDDP iteration lifecycle (forward pass, backward pass, convergence check), the four abstraction points (risk measure, cut formulation, horizon mode, sampling scheme), state management, and dual extraction for cut coefficients. This is the central spec that most other architecture specs plug into.
  2. Simulation Architecture – How trained policies are evaluated on large scenario sets: parallel distribution, per-scenario forward pass, policy compatibility validation, non-convex extensions, statistics computation, and streaming output.
  3. Solver Abstraction – The unified interface through which the SDDP algorithm interacts with LP solvers: solver interface contract, LP layout convention, cut pool design, error categories, retry logic, dual normalization, basis storage, and compile-time solver selection.
  4. Solver HiGHS Implementation – HiGHS-specific patterns for the C API, batch bound operations, retry strategy, basis management, memory footprint, and SDDP-tuned configuration.
  5. Solver CLP Implementation – CLP-specific patterns for the C API baseline, mutable pointer optimization, C++ wrapper strategy for LP template cloning, retry strategy, basis management, and memory footprint.
  6. Solver Workspaces – Thread-local solver workspace infrastructure and LP scaling: NUMA-local solver instances, pre-allocated buffers, and the bridge between the solver abstraction and the HPC execution layer.
  7. Performance Adaptation Layer – How cobre-core’s domain types are transformed into cobre-sddp’s performance-adapted runtime representations: transformation taxonomy, adapted type inventory, initialization build order, entity data flow mapping, and adaptation contracts.
  8. Scenario Generation – The scenario generation pipeline: PAR model preprocessing, correlated noise generation, the sampling scheme abstraction, external scenario integration, load scenario generation, and the memory layout optimized for the forward pass hot-path.
  9. Input Loading Pipeline – Rank-0 centric loading pattern, file loading sequence with dependency ordering, sparse time-series expansion, data broadcasting, parallel policy loading for warm-start, and transition to the in-memory data model.
  10. Extension Points – How algorithm variants are selected, composed, and validated at configuration time: the four abstraction points mapped to their configuration sources, validation rules, and cross-variant compatibility constraints.
  11. CLI and Lifecycle – Program entrypoint, command-line interface, exit codes, execution phase lifecycle, conditional execution modes, configuration resolution hierarchy, and job scheduler integration.
  12. Validation Architecture – Multi-layer input validation pipeline: the five validation layers, error collection strategy, error type catalog, and validation report format.
  13. Convergence Monitoring – Convergence criteria, stopping rules, bound computation with cross-rank aggregation, and training log format for progress reporting.
  14. Cut Management Implementation – How the mathematical cut management concepts are implemented: future cost function runtime structure, cut selection on the pre-allocated cut pool, FlatBuffers serialization for checkpoint/resume, cross-rank cut synchronization via MPI, cut coefficient extraction via fixing constraint duals, and cut activity tracking.

Spec Index

SpecDescriptionMath/Data Reference
Training LoopSDDP iteration lifecycle, abstraction points, forward/backward passes, state management, dual extractionSDDP Algorithm, Cut Management, Stopping Rules
Simulation ArchitecturePolicy evaluation on large scenario sets, parallel distribution, statistics, streaming outputRisk Measures, Discount Rate, Output Schemas
Solver AbstractionUnified LP solver interface, LP layout, cut pool design, error handling, basis storageLP Formulation
Solver HiGHS ImplementationHiGHS C API integration, batch operations, SDDP-tuned configurationLP Formulation
Solver CLP ImplementationCLP C/C++ API integration, LP template cloning, mutable pointer optimizationLP Formulation
Solver WorkspacesThread-local NUMA-aware solver instances, pre-allocated buffers, LP scalingLP Formulation
Performance Adaptation LayerDomain-to-solver type transformation taxonomy, adapted type inventory, build order, entity flow, contractsInternal Structures, PAR Inflow Model
Scenario GenerationPAR preprocessing, correlated noise, sampling schemes, external scenarios, memory layoutPAR Inflow Model, Input Scenarios
Input Loading PipelineRank-0 loading, dependency ordering, sparse expansion, broadcast, warm-start policy loadingInput Directory Structure, Binary Formats
Extension PointsAlgorithm variant selection, composition, validation, cross-variant compatibilityRisk Measures, Infinite Horizon
CLI and LifecycleProgram entrypoint, CLI, exit codes, phase lifecycle, configuration resolutionInput Directory Structure
Validation ArchitectureFive validation layers, error collection, error catalog, validation reportInput System Entities, Input Constraints
Convergence MonitoringConvergence criteria, bound computation, cross-rank aggregation, training logStopping Rules, Upper Bound Evaluation
Cut Management ImplementationFCF runtime structure, cut selection, FlatBuffers serialization, MPI cut sync, activity trackingCut Management, Binary Formats

Conventions

All specs in this section describe behavioral contracts rather than implementation artifacts. Component responsibilities are stated as “the component does X” rather than “the struct has field Y”. This keeps the specs stable across refactors while remaining precise enough to verify an implementation against. Where a spec references mathematical quantities (cut coefficients, dual variables, risk weights), it uses the notation from Notation Conventions and links to the relevant math spec for the full derivation. Where a spec references data schemas (Parquet columns, JSON keys, FlatBuffers tables), it links to the relevant data-model spec for the normative definition. Cross-references to the High-Performance Computing section appear where parallelization strategy is architecturally significant (MPI distribution, OpenMP threading, NUMA placement).

High-Performance Computing

This section contains the specifications for Cobre’s hybrid MPI+OpenMP parallelization strategy. Where the Architecture section defines how the solver is structured at the software level, the HPC specs define how that architecture maps onto distributed and shared-memory hardware: the process topology that places one MPI rank per NUMA domain, the OpenMP threading layer that parallelizes LP solves within each rank, the communication patterns that synchronize cuts and bounds across ranks, the memory layout that eliminates false sharing and minimizes NUMA penalties, and the deployment recipes that translate these design choices into SLURM job scripts.

Together, these 8 specs fully describe the parallel execution model of the Cobre solver. They are written at the behavioral level – specifying distribution strategies, synchronization contracts, memory placement policies, and communication protocols – without prescribing MPI implementation details or OpenMP pragma syntax. A developer implementing the HPC layer should be able to read these specs alongside the referenced architecture and math specs and produce a correct parallel implementation without ambiguity. Where performance-critical design decisions exist (e.g., static contiguous block distribution over dynamic dispatch, sequential opening evaluation over parallel, thread-trajectory affinity), each spec documents the rationale and the constraints that drove the choice.

The specs assume familiarity with the SDDP training loop as described in Training Loop, the stage LP structure from LP Formulation, and the solver workspace infrastructure from Solver Workspaces. Readers new to the parallel execution model should start with Hybrid Parallelism, which establishes the two-level ferrompi+OpenMP architecture, before diving into the individual specs.

Reading Order

The specs have cross-references, so reading order matters. The following sequence builds concepts from the parallelization model outward to deployment:

  1. Work Distribution – How forward pass scenarios and backward pass trial points are distributed across MPI ranks and OpenMP threads: static contiguous block assignment, thread-trajectory affinity, and the load balancing strategy.
  2. Hybrid Parallelism – The two-level parallelization model: ferrompi as the backbone for process-level parallelism and shared memory, OpenMP via C FFI for intra-rank threading, design rationale, configuration, initialization sequence, and build integration.
  3. Communication Patterns – MPI communication patterns used during the SDDP training loop: MPI_Allreduce for bound aggregation, MPI_Allgatherv for cut synchronization, and shared memory windows for intra-node data sharing.
  4. Memory Architecture – Memory layout and NUMA-aware allocation: per-rank memory budget, shared memory region sizing, first-touch initialization, and false sharing avoidance.
  5. Shared Memory Aggregation – Hierarchical cut aggregation within MPI ranks sharing a physical node: node-local aggregation before inter-node communication to reduce message volume.
  6. Synchronization – Synchronization barriers and coordination points in the SDDP training loop: per-stage backward pass barriers, forward pass completion, and thread synchronization within ranks.
  7. Checkpointing – Checkpoint and restart for fault tolerance: what state is saved, when checkpoints are taken, how the solver resumes from a checkpoint across MPI ranks.
  8. SLURM Deployment – SLURM job submission and configuration: job scripts for single-node and multi-node runs, resource allocation, environment variable setup, and performance monitoring.

Spec Index

SpecDescriptionArchitecture Reference
Work DistributionStatic block distribution, thread-trajectory affinity, load balancingTraining Loop, SDDP Algorithm
Hybrid Parallelismferrompi + OpenMP architecture, design rationale, configuration, initializationTraining Loop, Solver Workspaces
Communication PatternsMPI collectives, shared memory windows, cut synchronization protocolsCut Management Implementation, Convergence Monitoring
Memory ArchitectureNUMA-aware allocation, memory budget, shared region sizing, false sharing avoidanceSolver Workspaces
Shared Memory AggregationNode-local cut aggregation, hierarchical reduction, shared memory scenariosCut Management Implementation
SynchronizationPer-stage barriers, forward pass completion, thread coordinationTraining Loop
CheckpointingCheckpoint/restart, fault tolerance, state serialization across ranksCut Management Implementation, CLI and Lifecycle
SLURM DeploymentJob scripts, resource allocation, environment setup, multi-node deploymentCLI and Lifecycle

Conventions

All specs in this section describe parallel execution behavior and resource placement rather than sequential algorithmic logic. Where a spec references mathematical quantities (cut coefficients, dual variables, trial points), it uses the notation from Notation Conventions and links to the relevant math spec for the full derivation. Where a spec references architectural components (training loop, solver workspaces, cut management), it links to the relevant architecture spec for the behavioral contract. The HPC specs complement rather than duplicate the architecture specs – the architecture specs define what happens at each algorithmic step, while the HPC specs define how that step is distributed, synchronized, and placed in memory.

Configuration

This section contains the configuration reference that maps every tunable parameter exposed by Cobre to its effect on LP subproblem construction, solver behavior, and algorithm variant selection. Configuration is split across two files – config.json for global solver parameters and stages.json for temporal structure and per-stage options – and the reference documents all valid values, defaults, and LP-level consequences for each setting.

Spec Index

SpecDescription
Configuration ReferenceComplete mapping of configuration options to LP effects, with JSON examples, formulation-to-config traceability, and variable correspondence

Cross-Section References

The configuration options documented here reference definitions from three other specification sections. Modeling options and training parameters map to formulations in Mathematical Formulations (cut selection strategies, stopping rules, risk measures, discount rates). Data file paths and JSON schemas are defined in Data Model (input directory structure, stages schema, penalty system). Algorithm variant selection and validation rules are specified in Architecture (extension points, scenario generation, cut management implementation).

Interfaces

This section specifies the four interface layers through which external agents, tools, and users interact with Cobre beyond the traditional MPI batch execution path. Each interface layer is implemented as a separate crate with its own responsibility boundary, but all share the same event types defined in cobre-core and operate in single-process mode (no MPI).

InterfaceCratePurpose
Structured Outputcobre-cliJSON and JSON-lines output protocol for CLI responses and progress streaming
MCP Servercobre-mcpModel Context Protocol server exposing Cobre operations as tools, resources, and prompts
Python Bindingscobre-pythonPyO3-based Python module for programmatic access to validation, training, simulation, and results
Terminal UIcobre-tuiInteractive terminal dashboard for real-time training monitoring and convergence visualization

All four interfaces consume the shared event stream architecture defined in the Training Loop and Convergence Monitoring specs. The structured output spec (CLI JSON protocol) serves as the foundational schema layer – the MCP server, Python bindings, and TUI all reuse its error schema and event type definitions.

Deferred Features

Purpose

This spec documents features that are planned but not yet implemented in the Cobre SDDP solver. Each feature includes a description, rationale for deferral, prerequisites, and estimated effort. The data model is designed to accommodate these extensions without breaking changes.

C.1 GNL Thermal Plants

Status: DEFERRED

Description: Gas Natural Liquefeito (GNL) thermal plants have complex operational constraints including:

  • Minimum take-or-pay contracts
  • Variable fuel costs based on LNG spot market
  • Start-up and shutdown constraints
  • Fuel inventory management

Planned Formulation:

  • Binary variables for unit commitment (requires MIP solver integration)
  • Fuel inventory balance constraints
  • Contract fulfillment constraints
  • Piecewise-linear fuel cost functions

Why Deferred: Requires MIP solver integration (SDDiP or Lagrangian relaxation) which is a significant architectural change. Unit commitment is not in the immediate roadmap for medium/long-term planning.

Prerequisites:

  • Duality handler infrastructure (Lagrangian relaxation for MIP subproblems)
  • MIP solver integration (Gurobi, CPLEX, or Cbc)
  • GNL-specific data model extensions

Estimated Effort: Large (3-4 weeks). Requires SDDiP infrastructure before GNL-specific modeling.

Reference: CEPEL NEWAVE/DECOMP GNL modeling documentation.

C.2 Battery Energy Storage Systems

Status: DEFERRED

Description: Grid-scale batteries with:

  • State-of-charge management
  • Charge/discharge efficiency losses
  • Degradation modeling (cycle counting)
  • Capacity fade over time

Planned Formulation:

Variables:

VariableDomainUnitsDescription
MWhState of charge
MWCharging power
MWDischarging power

Energy Balance:

Load Balance Contribution:

Data Model: The system/batteries.json schema is fully specified with fields for capacity (energy/charge/discharge), efficiency, initial SOC, and SOC limits. LP variables include battery_soc (state), battery_charge, and battery_discharge (controls). Output schema in simulation/batteries/ is also defined. See Input System Entities for the entity registry pattern and Internal Structures for how entities are resolved at runtime.

Why Deferred: Batteries are linear storage devices (no integer variables needed), but require:

  • New state variable dimension (SOC per battery)
  • Integration with bus load balance
  • Testing with realistic battery degradation scenarios

Prerequisites:

  • State variable infrastructure supports dynamic dimension
  • Bus balance constraint generation handles battery charge/discharge
  • Output schema for battery simulation results

Estimated Effort: Medium (2-3 weeks). LP formulation is straightforward; main effort is data pipeline and testing.

C.3 Multi-Cut Formulation

Status: DEFERRED

Description: Alternative to single-cut aggregation that creates one cut per scenario.

Formulation:

Instead of a single aggregated future cost variable , introduce per-scenario variables :

With per-scenario cuts:

Trade-offs:

AspectSingle-CutMulti-Cut
Cuts per iteration1 (one per scenario)
LP sizeSmaller (1 future cost variable)Larger ( future cost vars)
Convergence rateSlower (more iterations)Faster (fewer iterations)
Time per iterationFasterSlower
MemoryLowerHigher
Numerical stabilityMore stableCan have issues with risk measures
Best forLarge scenario counts, risk-averseSmall scenario counts, risk-neutral

Why Deferred: Multi-cut requires significant changes:

  • LP construction must handle multiple future cost variables
  • Cut storage and selection becomes more complex
  • Interaction with CVaR risk measures needs careful implementation
  • Performance tuning (when to use which formulation) is problem-dependent

Prerequisites:

  • LP builder supports variable number of future cost variables
  • Cut pool indexed by scenario
  • Cut selection adapted for multi-cut pools

Estimated Effort: Medium (2-3 weeks). Core algorithm change with wide-reaching effects on cut management.

Reference: Birge, J.R. (1985). “Decomposition and partitioning methods for multistage stochastic linear programs.” Operations Research, 33(5), 989-1007.

C.4 Markovian Policy Graphs

Status: DEFERRED

Description: Extension to handle scenario-dependent transitions (e.g., different inflow regimes).

Current Limitation: Cobre assumes stage-wise independent scenarios. The same scenario tree structure is used regardless of which scenario was realized in the previous stage.

Planned Extension:

  • Markov chain over “regimes” (e.g., wet/dry/normal)
  • Transition probabilities between regimes
  • Regime-dependent inflow distributions
  • Cut sharing across nodes in same regime

Formulation:

Let be a Markov chain with states and transition matrix .

The policy graph becomes:

  • Nodes: for stage and regime
  • Edges: with probability

Value function approximation:

Cuts are regime-specific and only shared within the same regime.

Data Model: The stages.json schema supports optional markov_states fields. Transitions include source_markov and target_markov fields. Cut files are indexed by (stage_id, markov_state) as stage_XXX_markov_YYY.bin. See Input Scenarios for the stages.json schema and Binary Formats for cut file persistence.

Why Deferred: Markovian policy graphs substantially increase algorithm complexity:

  • Forward passes must track Markov state transitions
  • Backward passes generate cuts for each (stage, markov_state) node
  • State space grows by factor of |markov_states|
  • Requires careful handling of stagewise-independent noise within each Markov state

Prerequisites:

  • Policy graph supports multi-node-per-stage structure
  • Cut pool indexed by (stage, markov_state) tuples
  • Forward/backward pass logic handles Markov transitions
  • Scenario generation respects regime-dependent distributions

Estimated Effort: Large (3-4 weeks). Fundamental change to policy graph and forward/backward pass logic.

Reference: Philpott, A.B., & de Matos, V.L. (2012). “Dynamic sampling algorithms for multi-stage stochastic programs with risk aversion.” European Journal of Operational Research, 218(2), 470-483.

C.5 Non-Controllable Sources (Wind/Solar)

Status: IMPLEMENTED

Note: Non-controllable sources are no longer deferred. The LP formulation (generation bounds, curtailment variables, bus balance participation) is specified in Equipment Formulations §6. The data model (entity registry, scenario pipeline, penalty overrides) is specified in Input System Entities §7. The penalty system includes curtailment cost as a Category 3 regularization penalty in Penalty System §2. The formulation and data model descriptions below are retained for reference.

Variables:

VariableDomainUnitsDescription
MWNon-controllable generation
MWCurtailment

Generation Constraint:

where is the stochastic availability factor.

Curtailment Penalty:

Data Model: The system/non_controllable_sources.json schema defines source type, bus assignment, capacity, and curtailment settings. Generation models in scenarios/non_controllable_models.parquet provide mean and standard deviation per source per stage. Correlation with inflows is supported via correlation.json blocks. Output schema in simulation/non_controllables/ is defined.

C.6 FPHA Enhancements

Status: DEFERRED (Partial – core FPHA implemented)

Description: Advanced extensions to the FPHA (Four-Point Head Approximation) model for improved accuracy in hydroelectric production function modeling.

C.6.1 Variable Efficiency Curves

Current: Constant turbine-generator efficiency .

Enhancement: Flow-dependent efficiency using characteristic curves:

where is a hill chart approximation, typically:

Data Requirements:

  • Efficiency curve coefficients in hydro_production_data.parquet
  • efficiency_type = "flow_dependent"
  • efficiency_coeffs = [a_0, a_1, a_2, a_3]

Impact on FPHA: Hyperplane fitting must use at each grid point. Increases nonlinearity captured by the approximation. More planes may be needed for same accuracy.

C.6.2 Pumped Hydro Production Function

Current: Pumping modeled separately from generation.

Enhancement: Unified production function for reversible hydro plants:

Generation Mode (standard FPHA):

Pumping Mode (reversed inequality – pumping power increases with head):

Pumping Production Function:

where = pumping head (downstream to upstream) and = pumping efficiency (typically 0.85-0.90).

Hyperplane Form:

Operational Constraints:

  • Mutual exclusion: (nonlinear)
  • Alternative: Big-M or SOS1 constraints (introduces integer variables)
  • Cobre approach: Allow simultaneous gen/pump with high penalty (relaxation)

C.6.3 Dynamic FPHA Recomputation

Current: FPHA hyperplanes fixed per stage configuration.

Enhancement: Recompute hyperplanes based on expected operating region.

Approach:

  1. Track volume distribution per stage across forward passes
  2. Adjust to cover observed operation
  3. Generate new planes for updated windows
  4. Manage cut validity after FPHA updates

Configuration (future):

{
  "fpha_config": {
    "dynamic_recomputation": {
      "enabled": true,
      "recompute_every_n_iterations": 50,
      "window_adaptation": "narrow_only",
      "percentile_margin": 5
    }
  }
}

Warning: Dynamic recomputation changes the LP structure across iterations. This may affect SDDP convergence guarantees.

Why Deferred: Core FPHA is implemented; these are accuracy improvements requiring:

  • Variable efficiency: Hill chart data and fitting infrastructure
  • Pumped hydro: Unified gen/pump production function with mutual exclusion
  • Dynamic recomputation: Online hyperplane refitting with cut validity management

Prerequisites:

  • Core FPHA operational and validated
  • Hyperplane fitting infrastructure supports refitting
  • Performance baseline established to measure improvements

Estimated Effort: Medium-Large (2-4 weeks total across all three sub-features).

C.7 Temporal Scope Decoupling

Status: DEFERRED

Description: Advanced temporal decomposition inspired by SPARHTACUS that decouples the physical time resolution (decision dynamics) from the SDDP stage decomposition (Benders cut generation points). Enables flexible multi-resolution modeling with controlled cut growth.

Motivation: In conventional SDDP, three temporal scopes are tightly coupled: stage (SDDP decomposition unit), decision period (physical time resolution), and stochastic process (uncertainty realization base). This forces a trade-off between fine temporal resolution (accurate physics, exponential cut growth) and coarse resolution (manageable cuts, poor short-term dynamics).

Three Independent Temporal Scopes (SPARHTACUS nomenclature):

ScopePortuguese TermCobre CurrentPurpose
Optimization PeriodPeriodo de otimizacaostages[t]SDDP decomposition unit, Benders cut generation
Study PeriodPeriodo de estudo(coupled to stage)Physical time resolution for constraints and decisions
Stochastic Process PeriodPeriodo do processo estocasticoinflow_seasonal_stats.parquet per stageBase for uncertainty realization

Extended Multi-Period Stage Subproblem:

Let stage contain decision periods indexed by .

Subject to:

  • Period 1 constraints:
  • Period k constraints: for
  • State transition:

Key property: State variable dimension is unchanged – cuts reference only at stage boundaries, not intermediate periods. LP size increases by factor but cut count remains constant.

LP Size Impact:

ConfigurationStagesAvg LP SizeCut Pool
Standard monthly601500 vars~1200 cuts @ 20 iter
Hybrid (4 weekly + rest monthly)60~1600 vars~1200 cuts
All weekly2601500 vars~5200 cuts @ 20 iter

Why Deferred: Requires significant architectural changes:

  • Multi-period LP construction within single stage
  • Modified forward/backward pass logic
  • Data model changes (periods array within stages)
  • Interaction with chronological blocks (nested: Stage → Periods → Blocks)

Prerequisites:

  • Core SDDP training loop validated and stable
  • Chronological block formulation operational
  • Performance profiling shows cut growth is the bottleneck

Estimated Effort: Large (4-6 weeks). Fundamental change to LP construction, data model, and algorithm.

References:

  • SPARHTACUS/SPTcpp: Escopo Temporal
  • Pereira, M.V.F., & Pinto, L.M.V.G. (1991): Original SDDP paper with monthly stages

C.8 CEPEL PAR(p)-A Variant

Status: DEFERRED

Description: CEPEL’s PAR(p)-A model (referenced in Rel-1941_2021) extends the standard PAR(p) with:

  • Order constraint: Maximum AR order often fixed at 12 (annual cycle)
  • Stationarity enforcement: Coefficients adjusted to ensure
  • Lognormal transformation: Working with for strictly positive inflows
  • Regional correlation: Cross-correlation between hydros in the same river basin

Why Deferred: The standard PAR(p) model covers most practical use cases. The lognormal variant is primarily relevant for basins with highly skewed inflow distributions where negative synthetic inflows become problematic. The inflow non-negativity handling strategies (see Inflow Non-Negativity) provide adequate mitigation for the standard model.

Prerequisites:

  • Standard PAR(p) fitting and validation operational
  • Lognormal transformation infrastructure (log-space fitting, back-transformation)
  • Validation suite comparing PAR(p) vs. PAR(p)-A on representative basins

Data Model Compatibility: The current input format (inflow_seasonal_stats.parquet + inflow_ar_coefficients.parquet) supports PAR(p)-A — the lognormal transformation is applied to history before computing seasonal stats, and the resulting μ, s, ψ values are stored in the same schema.

Estimated Effort: Small-Medium (1-2 weeks). Mathematical extensions are straightforward; main effort is validation and testing.

Reference: CEPEL Rel-1941_2021.

C.9 Policy Compatibility Validation

Status: DEFERRED (requires dedicated spec)

Description: When the solver runs in simulation-only, warm-start, or checkpoint resume mode, it must validate that the current input data is compatible with the previously trained policy (cuts). Incompatible inputs produce silently incorrect results — cut coefficients encode LP structural information that becomes invalid if the system changes.

Properties to validate (non-exhaustive):

PropertyWhy It Matters
Block mode per stageCut duals come from different water balance structures (parallel vs. chronological)
Block count and durations per stageLP column/row dimensions change
Number of hydro plantsState variable dimension changes
AR orders per hydroState variable dimension changes
Cascade topologyWater balance constraint structure changes
Number of buses, linesLoad balance constraint structure changes
Number of thermals, contracts, NCSLP column count changes
Production model per hydro per stageFPHA vs. constant affects generation constraint and dual structure
Penalty configurationAffects objective coefficients and thus cut intercepts

Design considerations:

  • The training phase must persist a policy metadata record alongside the cut data, capturing all input properties that affect LP structure
  • The validation phase compares the current input against this metadata and produces a hard error on any mismatch
  • The metadata format should be versioned for forward compatibility
  • Some properties may allow controlled relaxation (e.g., adding a new thermal plant at the end might be compatible if the policy’s state variables are unchanged) — these exceptions require careful analysis

Why Deferred: This is a complex cross-cutting concern that touches training, simulation, checkpointing, and input loading. It requires a dedicated specification that defines:

  1. The complete list of validated properties
  2. The metadata format persisted by training
  3. The validation algorithm (exact match vs. compatible subset)
  4. Error reporting format
  5. Interaction with checkpoint versioning

Prerequisites (all now met — approved specs):

C.9 is unblocked and can proceed to its own dedicated specification.

Estimated Effort: Medium (2-3 weeks). Primarily specification and testing; implementation is straightforward once the property list is defined.

Cross-references:

C.10 Fine-Grained Temporal Resolution (Typical Days)

Status: DEFERRED (requires research)

Description: Decompose each stage into D representative typical day types (e.g., weekday, weekend, peak-season day), each containing N chronological blocks (e.g., 24 hourly periods). This enables accurate modeling of daily cycling patterns within monthly or weekly stages.

Motivation: The current block formulation uses a single level of temporal decomposition — a few load blocks (e.g., peak/shoulder/off-peak) with duration τ_k representing the total monthly hours for that load level. This is adequate for long-term planning but cannot capture:

  • Daily storage cycling (pumped hydro, batteries)
  • Hourly renewable generation profiles (solar peak, wind patterns)
  • Time-of-use pricing dynamics
  • Intra-day ramp constraints

Key design questions (require research):

  1. Day-type chaining: Should typical days chain sequentially within a stage (day 1 end-storage → day 2 initial storage), or operate independently with weighted-average end-of-stage storage?
  2. Objective weighting: Block durations within a day type are the actual hourly duration (e.g., 1 hour), but the objective contribution must be scaled by the day-type weight (number of days it represents). This requires separating the current τ_k into two components: block duration (for water balance) and effective duration (for objective).
  3. Two-phase architecture: Train with aggregated blocks, simulate with full typical-day resolution. Cut compatibility conditions need formal verification.
  4. Input data requirements: Day-type definitions, weights, hourly demand profiles per day type, hourly renewable availability profiles per day type.

LP size impact (estimated for 100 hydros):

ConfigurationBlocks/stageWater balance rowsAdditional LP vars
Current (3 load blocks)3100-3000-200
3 day types × 24 hours727,2007,100
5 day types × 24 hours12012,00011,900

References:

  • PSR SDDP v17.3 release notes — “Typical Days” representation
  • NZ Battery Project (Jacobs/PSR, 2023) — 21 chronological blocks per weekly stage
  • Garcia et al. (2020), “Genesys” — 3 chronological blocks per day in weekly stages
  • SPARHTACUS temporal decoupling (see §C.7 above)

Prerequisites:

  • Core parallel and chronological block modes operational and validated
  • Simulation architecture supports variable block configurations
  • Research on day-type chaining and two-phase cut compatibility completed

Estimated Effort: Large (4-6 weeks). Significant input schema design, LP construction changes, and research required.


C.11 User-Supplied Noise Openings

Status: DEFERRED (requires design investigation)

Description: Allow users to directly input pre-sampled, pre-correlated noise values for the opening tree, bypassing the internal noise generation and correlation pipeline entirely.

Motivation: The standard pipeline generates noise internally (sample independent , apply Cholesky correlation). Some use cases require full user control over the noise:

  • Importing noise realizations from external stochastic models that use non-Gaussian distributions
  • Reproducing exact noise sequences from legacy tools for validation
  • Using domain-specific spatial correlation structures not captured by the Cholesky approach
  • Research workflows where specific noise patterns are under study

Proposed Input File: scenarios/noise_openings.parquet

ColumnTypeDescription
opening_idint32Opening index ()
stage_idint32Stage identifier
entity_idint32Hydro (or bus, for load noise) identifier
noise_valuefloat64Already-correlated noise

When this file is present, the scenario generator skips internal noise sampling and Cholesky correlation entirely, loading the user-supplied values directly into the opening tree (§2.3 of Scenario Generation).

Design Questions (require investigation before implementation):

  1. Relationship to external scenarios — Can the existing external scenario mechanism (with noise inversion) cover all use cases, or does direct noise input serve fundamentally different needs?
  2. Validation — What checks should be applied? (e.g., noise dimensionality matches system, reasonable value ranges, correlation structure is PSD)
  3. Interaction with load noise — Should the file include load entity noise, or only inflow noise?
  4. Forward/backward separation — Should users supply separate noise sets for forward and backward passes?

Prerequisites:

  • Opening tree architecture (§2.3) implemented and validated
  • Forward/backward noise separation (§3.1) operational
  • Clear use case catalog that cannot be served by external scenarios + noise inversion

Estimated Effort: Small (1 week). Input loading and validation are straightforward; the opening tree already supports external population. Main effort is design decisions above.

Cross-references:

C.12 Complete Tree Solver Integration

Status: DEFERRED (concept documented, solver integration pending)

Description: Full solver integration for complete tree mode — enumerating all nodes in an explicit scenario tree and solving a subproblem per node using Benders decomposition, as in CEPEL’s DECOMP model.

The concept and tree structure are documented in Scenario Generation §7. This deferred item covers the solver-side integration:

Required Components:

  1. Tree enumerator — Given per-stage branching counts , enumerate all tree nodes with parent-child relationships and branching probabilities
  2. Node-to-subproblem mapping — Each tree node maps to a stage subproblem with specific RHS values (from the node’s branching realization) and a specific state variable value (from the parent node’s solution)
  3. Tree-aware backward pass — Instead of SDDP’s sample-based backward pass, solve backward through the tree: at each node, aggregate cuts from its children (weighted by branching probabilities)
  4. Result aggregation — Collect optimal values, state trajectories, and duals from all tree nodes; compute expected cost and policy metrics
  5. Exhaustive forward pass — Replace sampling with deterministic tree traversal, visiting every path from root to leaf

DECOMP Special Case: When for all , the tree degenerates into a deterministic trunk with branching only at stage . The forward pass solves a single path up to , then branches. This is the standard DECOMP configuration for short-term planning.

LP Construction: Each node’s LP is identical in structure to the SDDP stage subproblem — the complete tree mode reuses the existing LP builder. The difference is purely in the traversal logic (enumeration vs. sampling) and cut aggregation (tree-weighted vs. sample-averaged).

Why Deferred: Solver integration requires:

  • Tree traversal infrastructure (BFS/DFS node enumeration with MPI distribution)
  • Modified training loop that replaces SDDP’s forward/backward sampling with tree enumeration
  • Result storage for potentially millions of tree nodes
  • Convergence criterion different from SDDP (the tree solution is exact — convergence means Benders gap closure on the tree, not statistical bound convergence)

Prerequisites:

  • Core SDDP training loop operational
  • Opening tree infrastructure (§2.3) supports variable per-stage branching counts
  • External scenario integration validated
  • Performance profiling establishes tractability bounds for target problem sizes

Estimated Effort: Medium-Large (3-4 weeks). LP construction is reused; main effort is tree traversal, MPI distribution of tree nodes, and result aggregation.

References:


C.13 Alternative Forward Pass Model

Status: DEFERRED

Description: Solve a different LP model in the forward pass — one that includes simulation-only features (linearized head, unit commitment, bottom discharge) — to generate trial points that better reflect real-world operations, while keeping the training LP (convex, no simulation-only features) for backward pass cut generation.

Motivation: The default forward pass solves the training LP, which excludes simulation-only features (see Simulation Architecture). Trial points from this simplified model may not visit states that are realistic under full operational modeling. An alternative forward pass addresses this gap by solving a richer model to generate more representative trial points.

Design (inspired by SDDP.jl’s AlternativeForwardPass):

  1. Maintain two LP models per stage: the training LP (convex) and the alternative LP (includes simulation-only features)
  2. Forward pass solves the alternative LP at each stage, producing trial states
  3. Backward pass solves the training LP at each stage using these trial states, generating valid Benders cuts
  4. After each backward pass, new cuts are added to both LP models (the alternative LP needs cuts too, for its variable)

Key properties:

  • Cuts remain valid because they are generated from the convex training LP
  • Trial points are more realistic because they come from the richer alternative LP
  • Convergence may be slower (trial points from the alternative model may not be optimal for the training model)
  • Memory cost approximately doubles (two LP models per stage)

Why Deferred: Requires maintaining two parallel LP models per stage, which doubles memory and complicates solver workspace management. The benefit depends on how different simulation-only features make trial points — this is problem-dependent and needs empirical investigation.

Prerequisites:

  • Core SDDP training loop operational and validated
  • Simulation-only LP construction (linearized head, unit commitment) implemented
  • Solver workspace infrastructure supports multiple LP models per stage

Estimated Effort: Medium (2-3 weeks). LP construction infrastructure is reused; main effort is dual LP management, cut copying, and convergence testing.

Reference: SDDP.jl AlternativeForwardPass and AlternativePostIterationCallback in src/plugins/forward_passes.jl.

C.14 Monte Carlo Backward Sampling

Status: DEFERRED

Description: Sample openings with replacement from the fixed opening tree instead of evaluating all in the backward pass. This reduces backward pass cost from to LP solves per stage per trial point.

Motivation: When is large (e.g., 500+ for high-fidelity tail representation), the backward pass dominates iteration time. Sampling a subset provides an unbiased cut estimator with reduced computation.

Design (inspired by SDDP.jl’s MonteCarloSampler):

  • At each backward stage, sample noise vectors uniformly with replacement from the opening tree
  • Compute cut coefficients from only these solves
  • The resulting cut is an unbiased estimator of the full cut (with higher variance)

Trade-offs:

AspectComplete (current)MonteCarlo(n)
Solves per stage
Cut qualityExact (for given tree)Unbiased estimator, higher variance
ConvergenceMonotonic lower boundNon-monotonic (stochastic cuts)
Best forSmall-medium Large

Why Deferred: Introduces non-monotonic lower bound behavior, which complicates convergence monitoring. Requires careful tuning of relative to . The default complete evaluation is reliable and performant for typical production sizes (50-200 openings).

Prerequisites:

  • Core SDDP with complete backward sampling validated
  • Convergence monitoring supports non-monotonic lower bounds
  • Empirical study of vs. convergence rate trade-off

Estimated Effort: Small (1 week). Sampling infrastructure is trivial; main effort is convergence monitoring adaptation.

Reference: SDDP.jl MonteCarloSampler in src/plugins/backward_sampling_schemes.jl.

C.15 Risk-Adjusted Forward Sampling

Status: DEFERRED (supersedes “Risk-Adjusted Forward Passes” in Additional Variants below)

Description: Oversample scenarios from distribution tails in the forward pass, improving exploration of worst-case outcomes for risk-averse policies. This is a forward sampling scheme variant that biases sampling toward extreme scenarios.

Design (inspired by SDDP.jl’s RiskAdjustedForwardPass):

  • After solving each forward pass stage, evaluate the risk measure over the candidate noise terms
  • Re-weight or re-sample the next-stage noise based on the risk adjustment
  • The resulting forward trajectory visits states that are more relevant for the tail of the cost distribution

Complementary approach — Importance Sampling (inspired by SDDP.jl’s ImportanceSamplingForwardPass):

  • Weight forward trajectories by their likelihood ratio under the risk-adjusted distribution vs. the nominal distribution
  • Use these weights in upper bound estimation for tighter risk-averse bounds

Why Deferred: Requires integration with the CVaR risk measure configuration and careful handling of importance weights. Default uniform sampling is sufficient for most applications. The benefit is primarily for strongly risk-averse configurations ( close to 1.0).

Prerequisites:

  • CVaR risk measure implemented and validated
  • Forward sampling scheme abstraction supports per-stage re-weighting
  • Upper bound evaluation handles importance-weighted trajectories

Estimated Effort: Medium (2-3 weeks). Algorithm is well-documented in literature; main effort is integration with risk measure and convergence analysis.

References:

  • SDDP.jl RiskAdjustedForwardPass in src/plugins/forward_passes.jl
  • Philpott, A.B., & de Matos, V.L. (2012). “Dynamic sampling algorithms for multi-stage stochastic programs with risk aversion.”

C.16 Revisiting Forward Pass

Status: DEFERRED

Description: Encourage state-space diversity by occasionally re-solving forward passes from previously visited states rather than always starting from the root node. This helps the algorithm explore under-represented regions of the state space.

Design (inspired by SDDP.jl’s RevisitingForwardPass):

  • Maintain a buffer of previously visited states from past iterations
  • With some probability, start a forward pass from a randomly selected historical state at a randomly selected stage (rather than from stage 1 with )
  • The resulting trial points provide cuts in previously unvisited regions

Why Deferred: Modifies the forward pass initialization, which affects upper bound estimation (partial trajectories don’t contribute full-horizon costs). Requires careful interaction with convergence monitoring. The benefit is primarily for problems with large state spaces where standard forward passes repeatedly visit similar states.

Prerequisites:

  • Core SDDP training loop validated
  • State history buffer infrastructure
  • Convergence monitoring handles partial-trajectory iterations

Estimated Effort: Small-Medium (1-2 weeks). State buffer is straightforward; main effort is convergence analysis for partial trajectories.

Reference: SDDP.jl RevisitingForwardPass in src/plugins/forward_passes.jl.


C.17 Forward Pass State Deduplication

Status: DEFERRED

Description: When multiple forward scenarios visit identical (or near-identical) states at a given stage, the backward pass redundantly evaluates the cost-to-go from duplicate trial points. State deduplication merges these duplicates before the backward pass, reducing the number of backward LP solves without affecting cut quality (identical states produce identical cuts).

Design Considerations:

  • Exact deduplication — Hash-based deduplication of state vectors with identical storage volumes and AR lag values. Straightforward but limited benefit (exact duplicates are rare with continuous state spaces)
  • Approximate deduplication — Merge states within a tolerance using spatial indexing (e.g., k-d tree). Greater reduction in backward solves, but introduces approximation error in cut coefficients. Requires analysis of the impact on convergence guarantees

Why Deferred: Exact duplicates are uncommon in continuous-state SDDP, so the benefit of exact deduplication is marginal. Approximate deduplication requires careful analysis of convergence implications. Should be implemented only when profiling shows the backward pass is bottlenecked on trial point count rather than per-solve cost.

Prerequisites:

  • Core SDDP training loop validated and profiled
  • Backward pass timing data showing trial point count as the dominant cost factor

Estimated Effort: Small (< 1 week) for exact deduplication; Medium (2-3 weeks) for approximate with convergence analysis.

Cross-references:


C.18 Pipelined Backward Pass

Status: DEFERRED

Description: The standard (sequential) backward pass uses — the freshly computed approximation from the current iteration — requiring a synchronization barrier at each stage boundary. The pipelined variant uses (previous iteration’s approximation), allowing stages to be computed with overlapped communication. This eliminates per-stage barriers and enables non-blocking MPI broadcasts (ibroadcast) to overlap with computation at the next stage.

Trade-offs:

AspectSequential (current)Pipelined (deferred)
Cut source (current iteration) (previous iteration)
Cut qualityTighterLooser
Iterations to convergeFewerMore
Time per iterationLonger (per-stage barriers)Shorter (overlapped communication)
ImplementationSimpleComplex (async state management)
MPI primitivesMPI_Allgatherv (blocking)MPI_Iallgatherv + MPI_Wait (non-blocking)

Mathematical validity: Both approaches produce valid cuts — supporting hyperplanes of the true value function. The difference is in tightness: sequential cuts incorporate more recent information (downstream cuts from the same iteration), leading to faster convergence per iteration.

When to consider: When profiling shows backward pass per-stage barrier synchronization accounts for a significant fraction (>20%) of backward pass time. This is most likely with very large stage counts (>100 stages) and high inter-node network latency.

Why Deferred: The sequential mode is simpler, produces tighter cuts, and is the default in SDDP.jl and most production implementations. The benefit of pipelining depends on hardware-specific communication latency, which cannot be determined without profiling production workloads.

Prerequisites:

  • Core SDDP training loop validated and profiled
  • Backward pass timing data showing barrier synchronization as a bottleneck
  • Non-blocking MPI collective support in ferrompi

Estimated Effort: Medium (2-3 weeks). Requires async state management, non-blocking collective wrappers, and convergence regression testing.

Cross-references:


C.19 Dynamic Forward-Passes Scheduler

Status: DEFERRED

Description: A scheduler that adjusts the number of forward passes per iteration (forward_passes) during training based on convergence metrics or wall-clock budget.

Why Deferred: The cut pool capacity is pre-allocated using the formula warm_start_cuts + max_iterations × forward_passes (see Cut Management Implementation SS1.3). A dynamic scheduler would require either a worst-case static allocation (wasteful for most runs) or dynamic reallocation (invalidates the deterministic slot assignment in SS1.2). Both alternatives need profiling data to choose correctly.


Additional Deferred Algorithm Variants

The following algorithm variants are also deferred:

Objective States

Extends SDDP to handle exogenous random processes that affect objective coefficients (e.g., electricity spot prices following an AR process). Uses inner approximation (Lipschitz interpolation) for the value function component that depends on objective states.

Why Deferred: Not typically needed for hydrothermal dispatch where prices are marginal cost-based. Can often be approximated by scenario-based approaches.

Belief States (POMDP)

Extends SDDP to partially observable Markov decision processes where the agent maintains a probability distribution (belief) over hidden states. Useful for modeling phenomena like unobservable climate regimes.

Why Deferred: Research-level feature with limited practical benefit for most hydrothermal applications. Can often be approximated by expanding Markov states.

Duality Handlers (Lagrangian Relaxation)

Methods to generate valid cuts from MIP subproblems when integer variables are present (e.g., unit commitment). Includes Lagrangian relaxation and strengthened Benders cuts.

Why Deferred: Significant complexity in Lagrangian multiplier updates. Alternative: solve unit commitment deterministically after SDDP provides marginal values.

Cross-References

Glossary

Power system terminology used in Cobre, with Portuguese equivalents where they appear in documentation or Brazilian regulatory context.

Power System

EnglishPortugueseDefinition
BlockPatamarAn intra-stage time period (e.g., peak, shoulder, off-peak) representing load level variation within a stage; can be parallel (independent) or chronological (sequential)
BusBarramentoA node in the electrical network where components connect
LineLinha / CircuitoA transmission line or transformer connecting two buses
SubsystemSubsistemaA region of the interconnected grid (e.g., SE/CO, S, NE, N in Brazil)
ExchangeIntercâmbioPower transfer between subsystems
LoadCarga / DemandaElectrical power consumption at a bus
DeficitDéficitUnmet demand — load that cannot be served by available generation

Hydro Generation

EnglishPortugueseDefinition
Hydro plantUsina hidrelétrica (UHE)A hydroelectric generating station
ReservoirReservatórioWater storage volume behind a dam
StorageArmazenamentoCurrent water volume in a reservoir (hm³)
InflowAfluência / Vazão naturalNatural water flow arriving at a reservoir
Turbined outflowVazão turbinadaWater passing through turbines to generate electricity
SpillageVertimentoWater released from a reservoir without generating electricity
CascadeCascataSequence of hydro plants along the same river
DownstreamJusanteDirection of water flow; the plant that receives outflow from upstream
UpstreamMontanteDirection against water flow
ProductivityProdutibilidadeConversion factor from water flow (m³/s) to power (MW)
Run-of-riverFio d’águaHydro plant with no significant storage capacity
DiversionDesvioWater bypassed to a separate channel, not passing through turbines
EvaporationEvaporaçãoWater loss from the reservoir surface due to heat
Forebay levelNível de montanteWater level at the upstream face of the dam, a function of reservoir storage
FPHA-Four-Point Head Approximation — piecewise-linear model of hydro generation as a function of storage, flow, and spillage
HeadQuedaHeight difference between reservoir level and tailrace level, determining generation efficiency
Tailrace levelNível de jusanteWater level at the downstream channel below the dam, a function of total outflow

Thermal Generation

EnglishPortugueseDefinition
Thermal unitUsina termelétrica (UTE)A fossil-fuel or nuclear generating station
Minimum generationGeração mínima / InflexibilidadeMinimum output when the unit is committed
Operating costCusto variável unitário / CVUVariable cost per MWh of generation
Startup costCusto de partidaCost incurred when bringing a unit online

Stochastic Modeling

EnglishPortugueseDefinition
ScenarioCenárioOne realization of uncertain quantities (inflows, wind, etc.)
StageEstágioA time period in the planning horizon
State variableVariável de estadoVariables that link one stage to the next (storage, lagged inflows)
PAR(p)PAR(p)Periodic Autoregressive model of order p for inflow generation
Historical recordRegistro históricoObserved inflow data used to fit stochastic models
InnovationInovaçãoThe independent noise term in the PAR(p) model, representing the unpredictable component after removing autoregressive structure
Yule-Walker equationsEquações de Yule-WalkerSystem of linear equations relating autoregressive coefficients to sample autocorrelations, used to fit PAR(p) model parameters

SDDP Algorithm

EnglishPortugueseDefinition
Cut (Benders cut)Corte (de Benders)A linear inequality approximating the future cost function
Cost-to-go functionFunção de custo futuro (FCF)Expected cost from the current stage to the end of the horizon
Forward passPassagem diretaSimulation phase: solve stages sequentially under sampled scenarios
Backward passPassagem reversaOptimization phase: generate cuts by solving from the last stage backward
Lower boundLimite inferiorEstimate from the first-stage problem (improves with more cuts)
Upper boundLimite superiorStatistical estimate from simulation (converges to true cost in risk-neutral setup)
Optimality gapGap de otimalidadeDifference between upper and lower bounds, as a percentage
Dual variableVariável dual / MultiplicadorShadow price from LP solution; indicates marginal value of a resource
Marginal cost (CMO)Custo Marginal de OperaçãoShadow price of the demand constraint — the cost of one additional MWh
Cut poolConjunto de cortesCollection of all generated Benders cuts for a given stage
Discount factorFator de descontoMultiplicative factor applied to future costs reflecting the time value of money; required for infinite-horizon SDDP convergence
Epigraph variable-The auxiliary LP variable that lower-bounds the true cost-to-go function ; named after the epigraph of a convex function
Infinite horizonHorizonte infinitoPolicy graph with cyclic transitions, used for long-term planning
OpeningAberturaA pre-generated scenario noise vector used in the backward pass
Opening treeÁrvore de aberturasThe fixed set of pre-generated noise vectors used in the backward pass; generated once before training begins and reused across all iterations. Each stage has num_scenarios noise vectors. See Scenario Generation.
Outer approximationAproximação exteriorThe piecewise-linear lower bound on the cost-to-go function constructed from Benders cuts; the primary output of SDDP training
Policy graphGrafo de políticaDirected graph defining the stage structure and transitions in an SDDP problem
Relatively complete recourseRecurso relativamente completoProperty that every LP subproblem is feasible for all incoming states and scenario realizations; ensured in Cobre via penalty slack variables
Trajectory recordTrajetóriaData structure capturing one stage’s forward pass result: primal solution, dual solution, stage cost, and end-of-stage state. Used for cut coefficient extraction in the backward pass and for simulation output
Trial pointPonto amostralThe state visited during a forward pass, used to construct cuts in the backward pass

Risk Measures

EnglishPortugueseDefinition
Coherent risk measureMedida de risco coerenteA risk measure satisfying monotonicity, translation equivariance, positive homogeneity, and subadditivity; CVaR is the canonical example used in SDDP
CVaRCVaRConditional Value at Risk — expected cost in the worst α% of scenarios
EAVaR-Expectation plus Average Value-at-Risk; the convex combination used as Cobre’s risk measure
Risk-neutralNeutro ao riscoOptimization that minimizes expected cost only
Risk-averseAverso ao riscoOptimization that penalizes high-cost tail scenarios

Brazilian Ecosystem

TermDefinition
NEWAVELong-term hydrothermal dispatch model (monthly, 5–10 years)
DECOMPMedium-term model (weekly resolution)
DESSEMShort-term model (hourly/half-hourly, day-ahead)
GEVAZPSynthetic scenario generation tool
ONSOperador Nacional do Sistema Elétrico — Brazilian grid operator
CCEECâmara de Comercialização de Energia Elétrica — electricity trading chamber
CEPELCentro de Pesquisas de Energia Elétrica — R&D center that develops the official programs
SINSistema Interligado Nacional — the Brazilian interconnected power system

Solver

EnglishPortugueseDefinition
BasisBaseThe set of basic variables defining a vertex of the LP feasible region
CLP-Open-source LP solver from COIN-OR, used as a reference backend in cobre-solver
HiGHS-Open-source LP/MIP solver used as the default backend in cobre-solver
LP (Linear Program)Programa LinearAn optimization problem with a linear objective and linear constraints
RowBatch-A batch of LP rows (constraints) in CSR sparse format for bulk addition to a solver instance via the add_rows method
Simplex methodMétodo SimplexAlgorithm for solving linear programs by traversing vertices of the feasible polytope
Warm-startPartida a quenteReusing a previous solution basis to accelerate solving a modified LP

Data Formats

EnglishPortugueseDefinition
Arrow-In-memory columnar data format for analytics; Parquet is its on-disk counterpart
CSC (Compressed Sparse Column)-Column-major sparse matrix format used for stage LP templates passed to solvers
CSR (Compressed Sparse Row)-Row-major sparse matrix format used for batch cut addition via solver addRows APIs
FlatBuffers-Zero-copy serialization library used for policy data (cuts, states)
Parquet-Columnar file format for efficient storage and retrieval of large tabular datasets

HPC (High-Performance Computing)

EnglishPortugueseDefinition
MPI-Message Passing Interface — standard for distributed-memory parallel computing
NUMA-Non-Uniform Memory Access — hardware topology where memory access time depends on processor-memory proximity
OpenMP-API for shared-memory parallel programming via compiler directives; Cobre uses Rayon (Rust data-parallelism library) instead of OpenMP for intra-node thread parallelism
Rayon-Rust data-parallelism library used for intra-node thread parallelism in Cobre; provides work-stealing parallel iterators as a safe, idiomatic alternative to OpenMP
Rank-An MPI process; each rank has its own address space
Thread affinity-Binding of threads to specific CPU cores to prevent migration and ensure NUMA-local memory access

Cobre Ecosystem

EnglishPortugueseDefinition
Solver vertical-A complete solver algorithm stack built on the Cobre ecosystem (e.g., SDDP for hydrothermal dispatch, OPF for power flow)
Ecosystem vision-The design goal of Cobre as a generic power system ecosystem with multiple solver verticals sharing a common data model and HPC infrastructure

Bibliography

Core references for the algorithms and methods implemented in Cobre.

SDDP Foundations

  • Benders, J.F. (1962). Partitioning procedures for solving mixed-variables programming problems. Numerische Mathematik, 4(1), 238–252. — The original Benders decomposition paper. Foundation for the L-shaped method and SDDP.

  • Birge, J.R. (1985). Decomposition and partitioning methods for multistage stochastic linear programs. Operations Research, 33(5), 989–1007. — Multi-cut formulation for stochastic programs. Origin of the multi-cut L-shaped method.

  • Birge, J.R. & Louveaux, F.V. (2011). Introduction to Stochastic Programming. Springer, 2nd edition. — Standard textbook reference for stochastic programming theory and decomposition methods.

  • Pereira, M.V.F. & Pinto, L.M.V.G. (1991). Multi-stage stochastic optimization applied to energy planning. Mathematical Programming, 52(1–3), 359–375. — The original SDDP paper. Foundational for everything in cobre-sddp.

  • Philpott, A.B. & Guan, Z. (2008). On the convergence of stochastic dual dynamic programming and related methods. Operations Research Letters, 36(4), 450–455. — Convergence theory for SDDP.

  • Costa, B.F.P., Calixto, A.O., Sousa, R.F.S., Figueiredo, R.T., Penna, D.D.J., Khenayfis, L.S. & Oliveira, A.M.R. (2025). Boundary conditions for hydrothermal operation planning problems: the infinite horizon approach. Proceeding Series of the Brazilian Society of Computational and Applied Mathematics, 11(1), 1–7. doi:10.5540/03.2025.011.01.0355 — Infinite horizon boundary conditions for hydrothermal planning. Related to the infinite horizon extension in cobre-sddp.

Cut Management and Performance

  • de Matos, V.L., Philpott, A.B. & Finardi, E.C. (2015). Improving the performance of Stochastic Dual Dynamic Programming. Journal of Computational and Applied Mathematics, 290, 196–208. — Cut selection strategies. Basis for the cut selection in cobre-sddp.

  • Bandarra, M. & Guigues, V. (2021). Single cut and multicut stochastic dual dynamic programming with cut selection for multistage stochastic linear programs: convergence proof and numerical experiments. Computational Management Science, 18(2), 125–148. doi:10.1007/s10287-021-00387-8. Preprint: arXiv:1902.06757 — Convergence proof for Level-1 and LML1 cut selection strategies. Guarantees finite convergence with probability 1.

Risk Measures

  • Shapiro, A. (2011). Analysis of stochastic dual dynamic programming method. European Journal of Operational Research, 209(1), 63–72. — Convergence analysis, complexity bounds, and risk-averse extensions (including CVaR) for SDDP.

  • Philpott, A.B. & de Matos, V.L. (2012). Dynamic sampling algorithms for multi-stage stochastic programs with risk aversion. European Journal of Operational Research, 218(2), 470–483. — Dynamic sampling with risk aversion and Markovian scenario transitions.

  • Philpott, A.B., de Matos, V.L. & Finardi, E.C. (2013). On solving multistage stochastic programs with coherent risk measures. Operations Research, 61(4), 957–970. doi:10.1287/opre.2013.1175 — Time-consistent risk-averse SDDP with CVaR. Dual representation for risk-averse cut generation and nested risk measures.

Upper Bound and Inner Approximation

  • Costa, B.F.P. & Leclere, V. (2023). Duality of upper bounds in stochastic dynamic programming. Optimization Online. optimization-online.org/?p=23738 — Duality framework for upper bounds in stochastic dynamic programming. Basis for the upper bound evaluation in cobre-sddp.

Inflow Modeling

  • Larroyd, P.V., Pedrini, R., Beltran, F., Teixeira, G., Finardi, E.C. & Picarelli, L.B. (2022). Dealing with Negative Inflows in the Long-Term Hydrothermal Scheduling Problem. Energies, 15(3), 1115. doi:10.3390/en15031115 — Inflow non-negativity treatment for PAR(p) models in hydrothermal dispatch.

Software References

  • Dowson, O. & Kapelevich, L. (2021). SDDP.jl: A Julia Package for Stochastic Dual Dynamic Programming. INFORMS Journal on Computing, 33(1), 27–33. — Algorithmic reference for SDDP.jl. Influenced cut management and risk measure implementation in Cobre.

Brazilian Power System

Solver

  • Huangfu, Q. & Hall, J.A.J. (2018). Parallelizing the dual revised simplex method. Mathematical Programming Computation, 10, 119–142. — HiGHS simplex implementation. Cobre uses HiGHS as its default LP solver.

Frequently Asked Questions

This page is under construction.

Notation

This page defines the complete mathematical notation used across the Cobre documentation: index sets, parameters, decision variables, and dual variables. It is the canonical reference for symbol meanings, ensuring consistency across all mathematical and data model content.

1. General Notation Conventions

This document follows SDDP.jl notation conventions for consistency with the broader SDDP literature:

ConventionMeaning
Stage index
Scenario realization at stage
State variables at end of stage
Incoming state (from previous stage)
Value function (cost-to-go) at stage
Epigraph variable approximating
Dual variables (Lagrange multipliers)
Cut intercept and coefficients
Iteration counter

2. Index Sets

SymbolDescriptionTypical SizeNotes
Stages60-1205-10 year monthly horizon
Blocks within stage1-243 typical (LEVE/MÉDIA/PESADA)
Buses4-104-5 for SIN subsystems
Hydro plants160All plants in system
Operating hydros (can generate)Most/all plants typically operating
Filling hydros (no generation)0Usually 0; rare for new plants under commissioning
Hydros using FPHA production model50Subset with fitted hyperplanes
Hydros using constant productivityComplement of within
Thermal plants130
Non-controllable generation sources0Renewable curtailment entities
Transmission lines10Regional interconnections
All contracts ()10Unified contract set
, Import/export contracts5
Pumping stations5
Generic constraints50User-defined
Deficit segments for bus 1Multiple segments optional
FPHA planes for hydro 125Typical value; depends on grid resolution
Upstream hydros of 1-2Immediate upstream in cascade
Scenario realizations at stage 20Standard branching factor

3. Parameters

3.1 Time and Conversion

SymbolUnitsDescription
hoursDuration of block
-Block weight (fraction of stage)
hm³/(m³/s)Time conversion: m³/s over stage → hm³

Time Conversion Factor Derivation

The factor converts a flow rate in m³/s to a volume in hm³ accumulated over the stage duration.

Fundamental Relationship:

Unit Conversion Chain:

  1. Flow rate: [m³/s]
  2. Time period: [hours]
  3. Target volume: [hm³] =

For a stage with multiple blocks: If the stage has blocks with durations hours, and the flow is assumed constant across the stage (parallel blocks), the total time is hours:

Dimensional Analysis:

Worked Example (Monthly Stage):

BlockNameDuration (h)
1LEVE200
2MÉDIA300
3PESADA228
Total728

Verification: A constant inflow of m³/s over the month yields:

Direct calculation:

3.2 Load and Costs

SymbolUnitsDescription
MWLoad at bus , block
$/MWhDeficit cost at bus , segment
MWDeficit segment depth
$/MWhExcess generation cost
$/MWhThermal cost at plant , segment
$/(m³/s·h)Spillage cost
$/(m³/s·h)Diversion cost
$/MWhExchange (transmission) cost
, $/MWhContract import cost / export revenue

3.3 Hydro Parameters

SymbolUnitsDescription
hm³Incoming storage (state from previous stage)
, hm³Storage bounds
, m³/sTurbined flow bounds
, MWGeneration bounds
, m³/sOutflow bounds
MW/(m³/s)Productivity (constant model)
-FPHA plane coefficients

3.4 Transmission and Contract Parameters

SymbolUnitsDescription
, MWLine capacity (direct/reverse)
-Line efficiency
, MWContract capacity bounds

3.5 Inflow Model Parameters

Note on Periodicity: The PAR(p) model uses periodic parameters that repeat with a cycle length . Common configurations:

  • Monthly stages: (seasons = months)
  • Weekly stages: (seasons = weeks)
  • Custom resolution: = number of distinct periods in the cycle

We use “season as a generic term for the position within the cycle, avoiding the term “month” which is resolution-specific. The mapping converts stage index to season index .

SymbolUnitsDescription
m³/sSeasonal mean inflow for season
-AR coefficient for season , lag
m³/sResidual standard deviation for season
m³/sIncoming AR lag (state)

4. Decision Variables

Notation Convention:

  • Generation variables use with entity subscript: (hydro at plant ), (thermal at plant )
  • Flow variables use intuitive single letters: (turbined), (spillage), (diversion/bypass)
  • Total outflow is explicitly defined: (downstream channel flow)
  • Contract variables use (chi) with direction superscript: ,
  • Slack variables use with constraint-type superscript

Symbol Selection Rationale:

  • (turbined): from “vazão turbinada” (Portuguese) or “discharge through turbines”
  • (spillage): standard hydrology notation
  • (diversion): “bypass” or “desvio” — avoids confusion with demand or deficit
  • (outflow): total downstream flow affecting tailrace level
  • (withdrawal): “retirada” — consumptive removal from the system
  • (contract): Greek chi, visually distinct from cost symbol

4.1 Per-Block Variables

Per-block variables are indexed by :

VariableDomainUnitsDescription
MWDeficit at bus , segment
MWExcess generation at bus
MWDirect flow on line
MWReverse flow on line
MWThermal generation at plant , segment
m³/sTurbined flow at hydro
m³/sSpillage at hydro
MWHydro generation at plant
m³/sDiversion/bypass flow (to separate channel)
-m³/sTotal downstream outflow:
freem³/sEvaporation (can be negative for condensation)
m³/sWater withdrawal (consumptive use)
m³/sPumped flow at station
MWContract import
MWContract export

4.2 Stage-Level State Variables

VariableDomainUnitsDescription
hm³End-of-stage storage
-hm³Average storage during stage:
fixedm³/sAR lag (fixed by state transition)
$Future cost (cost-to-go approximation)

4.3 Slack Variables

Slack variables for soft constraints:

VariableDomainUnitsConstraint
hm³Storage below minimum
hm³Filling target shortfall
m³/sTurbined flow below minimum
m³/sOutflow below minimum
m³/sOutflow above maximum
MWGeneration below minimum
, m³/sEvaporation violation
m³/sWater withdrawal violation
m³/sInflow non-negativity (if enabled)

5. Dual Variables

Dual variables are essential for cut coefficient computation in the SDDP backward pass. This section describes how state-linking constraints are formulated in the LP for efficient solver updates, and how the resulting dual variables map to cut coefficients.

5.1 LP Formulation Strategy for Efficient Hot-Path Updates

In the SDDP algorithm, each subproblem solve requires setting the incoming state values (storage volumes and AR lags from the previous stage). For computational efficiency with solvers like HiGHS, we formulate constraints so that:

Design Principle: All incoming state variables are isolated on the right-hand side (RHS) of their respective constraints.

This allows the hot path (forward/backward passes) to update subproblems by simply modifying row bounds via changeRowBounds() without rebuilding constraint matrices. The LP matrix coefficients remain constant across all subproblem solves within a stage.

5.2 Water Balance: LP Form

The water balance is mathematically:

For LP implementation, we rearrange to isolate on the RHS:

Expanding the net flows and collecting all LP variables on the LHS:

LP Structure:

  • LHS: Linear combination of LP variables (storage , flows , , , etc.)
  • RHS: Incoming state only (set via row bounds in hot path)
  • Constraint type: Equality ()

5.3 AR Lag Constraints: LP Form

For autoregressive inflow state variables, the constraint fixes the current-stage lag variable to the incoming value:

LP Structure:

  • LHS: Single LP variable (coefficient = 1)
  • RHS: Incoming lag value (set via row bounds in hot path)
  • Constraint type: Equality ()

5.4 Cut Coefficient Derivation from Duals

The SDDP cut at stage has the form:

where is the intercept and are the coefficients with respect to state variables.

Key principle: For a constraint written as , the dual variable represents:

where is the optimal objective value. This is the marginal cost with respect to increasing the RHS.

Storage Dual ()

For the storage fixing constraint (see LP Formulation §4a):

The dual measures: “How does optimal cost change if incoming storage increases by 1 hm³?”

Economic interpretation:

  • More incoming storage means more water available for generation
  • Water has value (can displace thermal generation or avoid deficit)
  • Therefore, increasing decreases cost:
  • By LP convention (minimization), this gives

Cut coefficient:

No sign change is needed because the incoming state appears directly on the RHS with coefficient . By the LP envelope theorem, this dual automatically captures all downstream effects — water balance, FPHA hyperplanes, and generic constraints — without manual combination of duals from multiple constraint types. See Cut Management.

AR Lag Dual ()

For the lag fixing constraint:

The dual measures: _“How does optimal cost change if incoming lag increases by 1 m³/s?”_

Economic interpretation:

  • Higher historical inflow (in the PAR model) correlates with higher expected current inflow
  • Higher inflows reduce cost (more hydro generation possible)
  • Therefore, (increasing the lag decreases cost)

Cut coefficient:

The cut coefficient for lag is the dual variable directly, since appears on the RHS with coefficient . No sign change or scaling is needed.

5.5 Summary Table

SymbolConstraint (LP Form)RHSCut Coefficient
(storage fixing) (captures all downstream effects)
(direct)
Load balanceMarginal cost of energy
Water balance-Not used directly for cut coefficients
FPHA hyperplane -Captured via automatically
Generic constraint -Captured via automatically
Benders cut Cut activity indicator

5.6 Implementation Notes

The hot-path solver update pattern (modifying RHS via changeRowBounds for incoming state, extracting duals via getRowDual for cut coefficients) is documented in the Solver HiGHS Implementation and Solver Abstraction specs. The key property: since incoming state variables appear on the RHS of fixing constraints with coefficient , no sign change is needed when mapping duals to cut coefficients (; for AR lags, is used directly). Cut coefficient extraction is a single contiguous slice read: dual[0..n_state].

Verification check: In a typical hydrothermal system:

  • (water has value, more storage reduces cost)
  • (cut value increases as storage decreases — future is more expensive with less water)
  • The cut correctly penalizes low storage

Cross-References