Skip to content

Write the hydro units inside a HydroSystemUnitBlock, as the UCBlock of a stage of an SDDPBlock wants them - #71

Open
dmeoli wants to merge 3 commits into
SPSUnipi:mainfrom
dmeoli:feature/hydro-system-unit-block
Open

dmeoli wants to merge 3 commits into
SPSUnipi:mainfrom
dmeoli:feature/hydro-system-unit-block

Conversation

@dmeoli

@dmeoli dmeoli commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

The UCBlock of a stage of an SDDPBlock has its hydro units inside a HydroSystemUnitBlock, whose PolyhedralFunctionBlock is the future cost of their water, i.e., the function whose cuts SDDP builds (UnitBlock_0 of tools/sddp_solver/examples/Block_0.nc4 in SMS++); pypsa2smspp wrote each hydro StorageUnit as a HydroUnitBlock of its own in the UCBlock, so that a stage could not be written from a PyPSA network.

With Transformation(..., hydro_system=True) (off by default, as nuclear_units) all the hydro units go into a single HydroSystemUnitBlock, together with an empty PolyhedralFunctionBlock: a single one for all, since the future value of the water depends on the volumes of all the reservoirs together, and one per unit would make it separable. The HydroSystemUnitBlock is the last unit of the UCBlock rather than the first, so that the indices of the other units, and the paths into them, stay those of today. The DataMappings of a stochastic parameter of a hydro unit (e.g., hydro_inflow) reach its HydroUnitBlock inside the HydroSystemUnitBlock, through the path OBBB of the SDDP example, and the solution of the hydro units is read back from it. The PolyhedralFunctionBlock has the lower bound PolyFunction_lb = 0 (HydroSystemUnitBlock_parameters in transformation_config.py), since without cuts and without a bound it is $-\infty$ and the problem is unbounded (as is the SDDP example, solved alone); 0 is a valid bound only where the costs of the later stages are nonnegative. The option refuses an extendable hydro unit and a non-hydro StorageUnit placed after the hydro ones.

With the option off the files written are byte for byte those of main. On the two test networks with a hydro unit the optimum with the option on is the one of PyPSA and of the option off, within 1e-6 relative, deterministic and as a TSSB with stochastic inflows:

case PyPSA option off option on
1n_1c_1g_1h 2.9533401e10 2.9533401e10 2.9533401e10
3n_3c_1gext_1h_1bext_2l 1.5550488e9 1.5550488e9 1.5550488e9
1n_1c_1g_1h, TSSB 7.5142150e8 7.51421e8 7.51421e8
3n_3c_1gext_1h_1bext_2l, TSSB 1.6094192e9 1.60942e9 1.60942e9

A MILPSolver needs the PolyhedralFunctionBlock in its linearized form, which the BlockConfig InnerBCfg.txt asks for: for a UCBlock, SPSUnipi/pySMSpp#126 ships it in the UCBlock templates, read by smspp_ucblock_solver by default; for a TSSB, the TSSBlock/InnerBCfg.txt of SPSUnipi/pySMSpp#116 has the entry, given with pysmspp_options={"B": "InnerBCfg.txt"}. Until then the tests take the configuration installed with the tool, and are skipped where there is none. A stage written with the option has not been run in smspp_sddp_solver yet, nor the option inside a MultiStageStochasticBlock.

…uture cost of their water, as the UCBlock of a stage of an SDDPBlock wants them (hydro_system, off by default)
…ydro_inflow, reach its HydroUnitBlock inside the HydroSystemUnitBlock when hydro_system is set

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant