flixopt.clustering.intercluster_helpers ¶
Helper utilities for inter-cluster storage linking.
This module provides utilities for building inter-cluster storage linking constraints following the S-N model from Blanke et al. (2022).
Background¶
When time series are clustered (aggregated into representative periods), storage behavior needs special handling. The S-N linking model introduces:
-
SOC_boundary: Absolute state-of-charge at the boundary between original periods. With N original periods, there are N+1 boundary points.
-
Linking: SOC_boundary[d+1] = SOC_boundary[d] + delta_SOC[cluster_assignments[d]] Each boundary is connected to the next via the net charge change of the representative cluster for that period.
These utilities help construct the coordinates and bounds for SOC_boundary variables.
References¶
- Blanke, T., et al. (2022). "Inter-Cluster Storage Linking for Time Series Aggregation in Energy System Optimization Models."
- Kotzur, L., et al. (2018). "Time series aggregation for energy system design: Modeling seasonal storage."
See Also¶
:class:flixopt.components.InterclusterStorageModel The storage model that uses these utilities.
Classes¶
CapacityBounds dataclass ¶
Bounds for SOC_boundary variable creation.
This dataclass holds the lower and upper bounds for the SOC_boundary variable, along with a flag indicating whether investment sizing is used.
Attributes:
| Name | Type | Description |
|---|---|---|
lower | DataArray | Lower bound DataArray (typically zeros). |
upper | DataArray | Upper bound DataArray (capacity or maximum investment size). |
has_investment | bool | True if the storage uses InvestParameters for sizing. |
Functions¶
extract_capacity_bounds ¶
extract_capacity_bounds(capacity_param: InvestParameters | int | float | None, boundary_coords: dict, boundary_dims: list[str]) -> CapacityBounds
Extract capacity bounds from storage parameters for SOC_boundary variable.
This function determines the appropriate bounds for the SOC_boundary variable based on the storage's capacity parameter:
- Fixed capacity (numeric): Upper bound is the fixed value.
- InvestParameters: Upper bound is maximum_size (or fixed_size if set). The actual bound is enforced via separate constraints linked to investment.size.
- None/Unbounded: Upper bound is set to a large value (1e6).
The lower bound is always zero (SOC cannot be negative).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
capacity_param | InvestParameters | int | float | None | Storage capacity specification. Can be: - Numeric (int/float): Fixed capacity - InvestParameters: Investment-based sizing with min/max - None: Unbounded storage | required |
boundary_coords | dict | Coordinate dictionary for SOC_boundary variable. Must contain 'cluster_boundary' key. | required |
boundary_dims | list[str] | Dimension names for SOC_boundary variable. First dimension must be 'cluster_boundary'. | required |
Returns:
| Type | Description |
|---|---|
CapacityBounds | CapacityBounds with lower/upper bounds and investment flag. |
Example
coords, dims = build_boundary_coords(14, flow_system) bounds = extract_capacity_bounds(InvestParameters(maximum_size=10000), coords, dims) bounds.has_investment True bounds.upper.max() 10000.0
build_boundary_coords ¶
Build coordinates and dimensions for SOC_boundary variable.
Creates the coordinate dictionary and dimension list needed to create the SOC_boundary variable. The primary dimension is 'cluster_boundary' with N+1 values (one for each boundary between N original periods).
Additional dimensions (period, scenario) are included if present in the FlowSystem, ensuring the SOC_boundary variable has the correct shape for multi-period or stochastic optimizations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_original_clusters | int | Number of original (non-aggregated) time periods. For example, if a year is clustered into 8 typical days but originally had 365 days, this would be 365. | required |
flow_system | FlowSystem | The FlowSystem containing optional period/scenario dimensions. | required |
Returns:
| Type | Description |
|---|---|
tuple[dict, list[str]] | Tuple of (coords, dims) where: - coords: Dictionary mapping dimension names to coordinate arrays - dims: List of dimension names in order |
Example
coords, dims = build_boundary_coords(14, flow_system) dims ['cluster_boundary'] # or ['cluster_boundary', 'period'] if periods exist coords['cluster_boundary'] array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])