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

Input Hydro Extensions

Purpose

This spec defines the optional extension files for the hydro subsystem: reservoir geometry, production function model selection, and pre-computed FPHA hyperplanes. These files augment the core hydro registry defined in Input System Entities and live under system/ in the input case directory.

For other system elements (pumping stations, energy contracts, non-controllable sources), see Input System Entities. For deferred features (battery storage), see Deferred Features.

1. Hydro Geometry (system/hydro_geometry.parquet) — Optional

Format Rationale

Entity-level lookup table — Per-hydro tabular data (Volume-Height-Area curves) with multiple rows per hydro forming a static physical relationship. Parquet for typed columnar data with efficient per-hydro filtering.

Defines the Volume-Height-Area relationship for reservoirs. This data is used for:

  • Evaporation modeling: Surface area as a function of storage determines evaporated volume (see evaporation coefficients in Input System Entities §3)
  • Forebay level: Storage-to-height relationship for production function models that account for head variation (linearized_head, fpha)

Instead of polynomial fits, Cobre uses a tabular approach with linear interpolation — more transparent and easier to validate against surveyed data.

For the mathematical formulation of evaporation linearization and forebay level computation, see Hydro Production Functions and System Element Modeling.

Schema

ColumnTypeDescription
hydro_idi32Hydro plant identifier
volume_hm3f64Total volume (hm³) — must include dead volume
height_mf64Reservoir surface elevation (m)
area_km2f64Water surface area (km²)

Example rows (Sobradinho):

hydro_idvolume_hm3height_marea_km2
425447.0380.0800.0
428000.0385.01200.0
4212500.0390.02000.0
4218000.0395.03000.0
4228000.0400.04200.0

Validation

RuleDescription
VolumesMust be monotonically increasing per hydro
HeightsMust be monotonically increasing with volume
AreasMust be monotonically increasing with height
Minimum volume entryShould be at or below min_storage_hm3
Maximum volume entryShould be at or above max_storage_hm3
Dead volume geometryGeometry below min_storage_hm3 is optional; if not provided, filling evaporation uses geometry at min_storage_hm3

2. Hydro Production Models (system/hydro_production_models.json) — Optional

Format Rationale

Registry — Small config selecting model type per hydro with nested optional params and stage/season configuration. JSON handles optional/nested structures well.

Configures the hydro production function (HPF) modeling approach per hydro. Different stages or seasons can use different accuracy levels. See Hydro Production Functions for the mathematical formulation.

Model Hierarchy (increasing complexity and accuracy):

  1. constant_productivity: Fixed productivity factor — single multiplication, fastest
  2. linearized_head: Accounts for head variation with storage — requires geometry data. Simulation-only — excluded from training because the bilinear term changes the LP between iterations, breaking SDDP convergence (see Hydro Production Models §3)
  3. fpha: Full piecewise-linear approximation via hyperplanes — most accurate

See Hydro Production Functions §4 for model selection guidelines and accuracy trade-offs.

Default Behavior: If this file is not provided or a hydro is not listed, the model uses the generation.model field from hydros.json for all stages.

Selection Modes (Tagged Union)

The selection_mode field determines how the model is chosen per stage:

Mode: stage_ranges — Explicit stage ranges (structural changes across the horizon)

{
  "$schema": "https://cobre.dev/schemas/v2/production_models.schema.json",
  "production_models": [
    {
      "hydro_id": 0,
      "selection_mode": "stage_ranges",
      "stage_ranges": [
        {
          "start_stage_id": 0,
          "end_stage_id": 24,
          "model": "fpha",
          "fpha_config": {
            "source": "computed",
            "volume_discretization_points": 7,
            "turbine_discretization_points": 15,
            "fitting_window": {
              "volume_min_hm3": null,
              "volume_max_hm3": null
            }
          }
        },
        {
          "start_stage_id": 25,
          "end_stage_id": null,
          "model": "constant_productivity"
        }
      ]
    }
  ]
}

Mode: seasonal — Model selection keyed by season index, cycling across the horizon

Each stage is mapped to its season via the stage-to-season mapping defined in stages.json (see Input Scenarios). For a monthly study, seasons 0–11 correspond to January–December. This mode is useful for studies where accuracy requirements vary cyclically (e.g., wet season uses FPHA, dry season uses linearized head).

{
  "$schema": "https://cobre.dev/schemas/v2/production_models.schema.json",
  "production_models": [
    {
      "hydro_id": 5,
      "selection_mode": "seasonal",
      "default_model": "linearized_head",
      "seasons": [
        {
          "season_id": 0,
          "model": "fpha",
          "fpha_config": {
            "source": "computed",
            "volume_discretization_points": 5,
            "turbine_discretization_points": 10
          }
        },
        {
          "season_id": 1,
          "model": "fpha",
          "fpha_config": {
            "source": "computed",
            "volume_discretization_points": 5,
            "turbine_discretization_points": 10
          }
        }
      ]
    }
  ]
}

In this example, seasons 0 and 1 (e.g., January and February — wet season) use FPHA; all other seasons fall back to default_model (linearized head).

Note: This example uses linearized_head as the default model, which restricts this hydro’s configuration to simulation only. For training, replace the default_model with constant_productivity or fpha. See Hydro Production Models §3.

Combined usage: Different hydros in the same file can use different selection modes. Stage ranges and seasonal modes can coexist across hydros but not within a single hydro.

Selection Mode Fields

FieldTypeRequiredDescription
hydro_idi32YesHydro plant identifier
selection_modestringYes"stage_ranges" or "seasonal"
stage_rangesarrayIf mode = SRArray of stage range objects (see below)
default_modelstringIf mode = SFallback model for seasons not listed in seasons array
seasonsarrayIf mode = SArray of season-specific model configs (see below)

Stage Range Fields

FieldTypeRequiredDescription
start_stage_idi32YesFirst stage in range (inclusive)
end_stage_idi32 | nullYesLast stage in range (null = until end)
modelstringYes"constant_productivity", "linearized_head" (simulation-only), or "fpha"
fpha_configobjectIf fphaFPHA configuration (see below)

Season Fields

FieldTypeRequiredDescription
season_idi32YesSeason index (0-based, matching stages.json season map)
modelstringYes"constant_productivity", "linearized_head" (simulation-only), or "fpha"
fpha_configobjectIf fphaFPHA configuration (see below)

FPHA Configuration Fields

FieldTypeDescription
sourcestring"computed" (fit from topology) or "precomputed" (from fpha_hyperplanes.parquet)
volume_discretization_pointsi32Number of volume points in grid (default: 5)
turbine_discretization_pointsi32Number of turbine flow points (default: 5)
spillage_discretization_pointsi32Number of spillage flow points in grid (default: 5)
max_planes_per_hydroi32Maximum hyperplanes retained after heuristic selection (default: 10)
fitting_window.volume_min_hm3f64?Explicit minimum volume for fitting (null = physical min)
fitting_window.volume_max_hm3f64?Explicit maximum volume for fitting (null = physical max)
fitting_window.volume_min_percentilef64?Minimum as percentile of operating range
fitting_window.volume_max_percentilef64?Maximum as percentile of operating range

Use absolute bounds (volume_min_hm3, volume_max_hm3) OR percentiles, not both. Percentiles are relative to [min_storage_hm3, max_storage_hm3] from hydros.json.

Implementation note (v0.1.4): spillage_discretization_points and max_planes_per_hydro were added in v0.1.4 when the computed-source FPHA pipeline was implemented. The default for turbine_discretization_points is 5 (not 10 as originally specced); both defaults produce grids sufficient for typical reservoir configurations. All discretization counts must be >= 2; max_planes_per_hydro must be >= 1. The computed source path is fully implemented — no preprocessing step or external tool is required. Hyperplanes are fitted during the Initialization phase on rank 0 and written to output/hydro_models/fpha_hyperplanes.parquet.

Required Data by Model

Modelhydros.jsonhydro_geometryfpha_hyperplanes
constant_productivityproductivity_mw_per_m3s
linearized_headproductivity_mw_per_m3s
fpha (computed)productivity_mw_per_m3s¹
fpha (precomputed)productivity_mw_per_m3s¹

¹ Used as fallback for stages without FPHA configuration.

Implementation note (v0.1.4): The "computed" source path is implemented. Fitting runs during Initialization on MPI rank 0 from hydro_geometry.parquet and the tailrace, hydraulic_losses, and efficiency fields in hydros.json. Fitted planes are exported to output/hydro_models/fpha_hyperplanes.parquet using the same 11-column schema as the input file, enabling round-trip use in subsequent runs as "precomputed" planes.

Note: For computed FPHA, the solver also uses the optional tailrace, hydraulic_losses, and efficiency fields from the hydro object in hydros.json (see Input System Entities §3). If these fields are omitted, fallback assumptions apply (no tailrace adjustment, zero losses, efficiency derived from productivity).

3. FPHA Hyperplanes (system/fpha_hyperplanes.parquet) — Optional

Format Rationale

Pre-computed coefficient table — Per-hydro tabular data with many rows of hyperplane coefficients, potentially varying by stage. Parquet for typed columnar data with efficient per-hydro filtering.

Pre-computed FPHA hyperplane coefficients for hydro production function modeling. Allows using externally-fitted planes instead of computing them at runtime. Different stages can have different plane sets per hydro (e.g., near-term fitting with more detail vs. far-term with fewer planes).

Use CaseDescription
Legacy system migrationImport FPHA coefficients from DECOMP/DESSEM input files
External calibrationUse coefficients fitted by specialized tools
Performance optimizationSkip runtime fitting for large systems

If not provided, Cobre computes hyperplanes from hydro_geometry data and the hydro object’s tailrace/losses/efficiency fields during preprocessing.

Schema

ColumnTypeRequiredDescription
hydro_idi32YesHydro plant identifier
stage_idi32 | nullNoStage this plane set applies to (null = valid for all stages)
plane_idi32YesPlane index within hydro (0 to M-1)
gamma_0f64YesIntercept coefficient (MW)
gamma_vf64YesVolume coefficient (MW/hm³)
gamma_qf64YesTurbined flow coefficient (MW per m³/s)
gamma_sf64YesSpillage coefficient (MW per m³/s, typically ≤ 0)
kappaf64NoCorrection factor κ (default: 1.0). See Hydro Production Functions for mathematical definition.
valid_v_min_hm3f64NoVolume range minimum where plane is valid
valid_v_max_hm3f64NoVolume range maximum where plane is valid
valid_q_max_m3sf64NoMaximum turbined flow where plane is valid

Example rows (Itaipu):

hydro_idstage_idplane_idgamma_0gamma_vgamma_qgamma_skappa
66null01250.50.00230.892-0.0150.985
66null11180.20.00310.875-0.0120.985
66null21320.80.00180.901-0.0180.985
66null31095.40.00420.858-0.0100.985
66null41410.10.00120.915-0.0220.985

For the mathematical formulation of how these hyperplanes define the production function constraint, see Hydro Production Functions.

Validation

RuleDescription
Minimum planesEach hydro_id (per stage_id) should have at least 3 planes
Typical range5–30 planes per hydro per stage
gamma_vShould be positive (higher storage → higher generation)
gamma_qShould be positive (more flow → more generation)
gamma_sShould be negative or zero (spillage reduces effective head)
Validity rangesIf provided, planes are only activated when hydro is within range
Stage coverageIf stage_id is used, stages without specific planes fall back to null rows

Cross-References