flixopt.flow_system ¶
This module contains the FlowSystem class, which is used to collect instances of many other classes by the end User.
Attributes¶
Classes¶
FlowSystem ¶
FlowSystem(timesteps: DatetimeIndex, periods: Index | None = None, scenarios: Index | None = None, hours_of_last_timestep: int | float | None = None, hours_of_previous_timesteps: int | float | ndarray | None = None, weights: PeriodicDataUser | None = None, scenario_independent_sizes: bool | list[str] = True, scenario_independent_flow_rates: bool | list[str] = False)
Bases: Interface, CompositeContainerMixin[Element]
A FlowSystem organizes the high level Elements (Components, Buses, Effects & Flows).
This is the main container class that users work with to build and manage their energy or material flow system. FlowSystem provides both direct container access (via .components, .buses, .effects, .flows) and a unified dict-like interface for accessing any element by label across all container types.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timesteps | DatetimeIndex | The timesteps of the model. | required |
periods | Index | None | The periods of the model. | None |
scenarios | Index | None | The scenarios of the model. | None |
hours_of_last_timestep | int | float | None | The duration of the last time step. Uses the last time interval if not specified | None |
hours_of_previous_timesteps | int | float | ndarray | None | The duration of previous timesteps. If None, the first time increment of time_series is used. This is needed to calculate previous durations (for example consecutive_on_hours). If you use an array, take care that its long enough to cover all previous values! | None |
weights | PeriodicDataUser | None | The weights of each period and scenario. If None, all scenarios have the same weight (normalized to 1). Its recommended to normalize the weights to sum up to 1. | None |
scenario_independent_sizes | bool | list[str] | Controls whether investment sizes are equalized across scenarios. - True: All sizes are shared/equalized across scenarios - False: All sizes are optimized separately per scenario - list[str]: Only specified components (by label_full) are equalized across scenarios | True |
scenario_independent_flow_rates | bool | list[str] | Controls whether flow rates are equalized across scenarios. - True: All flow rates are shared/equalized across scenarios - False: All flow rates are optimized separately per scenario - list[str]: Only specified flows (by label_full) are equalized across scenarios | False |
Examples:
Creating a FlowSystem and accessing elements:
>>> import flixopt as fx
>>> import pandas as pd
>>> timesteps = pd.date_range('2023-01-01', periods=24, freq='h')
>>> flow_system = fx.FlowSystem(timesteps)
>>>
>>> # Add elements to the system
>>> boiler = fx.Component('Boiler', inputs=[heat_flow], on_off_parameters=...)
>>> heat_bus = fx.Bus('Heat', excess_penalty_per_flow_hour=1e4)
>>> costs = fx.Effect('costs', is_objective=True, is_standard=True)
>>> flow_system.add_elements(boiler, heat_bus, costs)
Unified dict-like access (recommended for most cases):
>>> # Access any element by label, regardless of type
>>> boiler = flow_system['Boiler'] # Returns Component
>>> heat_bus = flow_system['Heat'] # Returns Bus
>>> costs = flow_system['costs'] # Returns Effect
>>>
>>> # Check if element exists
>>> if 'Boiler' in flow_system:
... print('Boiler found in system')
>>>
>>> # Iterate over all elements
>>> for label in flow_system.keys():
... element = flow_system[label]
... print(f'{label}: {type(element).__name__}')
>>>
>>> # Get all element labels and objects
>>> all_labels = list(flow_system.keys())
>>> all_elements = list(flow_system.values())
>>> for label, element in flow_system.items():
... print(f'{label}: {element}')
Direct container access for type-specific operations:
>>> # Access specific container when you need type filtering
>>> for component in flow_system.components.values():
... print(f'{component.label}: {len(component.inputs)} inputs')
>>>
>>> # Access buses directly
>>> for bus in flow_system.buses.values():
... print(f'{bus.label}')
>>>
>>> # Flows are automatically collected from all components
>>> for flow in flow_system.flows.values():
... print(f'{flow.label_full}: {flow.size}')
>>>
>>> # Access effects
>>> for effect in flow_system.effects.values():
... print(f'{effect.label}')
Notes
- The dict-like interface (
flow_system['element']) searches across all containers (components, buses, effects, flows) to find the element with the matching label. - Element labels must be unique across all container types. Attempting to add elements with duplicate labels will raise an error, ensuring each label maps to exactly one element.
- The
.all_elementsproperty is deprecated. Use the dict-like interface instead:flow_system['element'],'element' in flow_system,flow_system.keys(),flow_system.values(), orflow_system.items(). - Direct container access (
.components,.buses,.effects,.flows) is useful when you need type-specific filtering or operations. - The
.flowscontainer is automatically populated from all component inputs and outputs. - Creates an empty registry for components and buses, an empty EffectCollection, and a placeholder for a SystemModel.
- The instance starts disconnected (self._connected_and_transformed == False) and will be connected_and_transformed automatically when trying to solve a calculation.
Attributes¶
all_elements property ¶
Get all elements as a dictionary.
.. deprecated:: 3.2.0 Use dict-like interface instead: flow_system['element'], 'element' in flow_system, flow_system.keys(), flow_system.values(), or flow_system.items(). This property will be removed in v4.0.0.
Returns:
| Type | Description |
|---|---|
dict[str, Element] | Dictionary mapping element labels to element objects. |
scenario_independent_sizes property writable ¶
scenario_independent_flow_rates property writable ¶
Functions¶
calculate_hours_per_timestep staticmethod ¶
Calculate duration of each timestep as a 1D DataArray.
to_dataset ¶
Convert the FlowSystem to an xarray Dataset. Ensures FlowSystem is connected before serialization.
Returns:
| Type | Description |
|---|---|
Dataset | xr.Dataset: Dataset containing all DataArrays with structure in attributes |
from_dataset classmethod ¶
Create a FlowSystem from an xarray Dataset. Handles FlowSystem-specific reconstruction logic.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds | Dataset | Dataset containing the FlowSystem data | required |
Returns:
| Type | Description |
|---|---|
FlowSystem | FlowSystem instance |
to_netcdf ¶
get_structure ¶
to_json ¶
fit_to_model_coords ¶
fit_to_model_coords(name: str, data: TemporalDataUser | PeriodicDataUser | None, dims: Collection[FlowSystemDimensions] | None = None) -> TemporalData | PeriodicData | None
Fit data to model coordinate system (currently time, but extensible).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name | str | Name of the data | required |
data | TemporalDataUser | PeriodicDataUser | None | Data to fit to model coordinates | required |
dims | Collection[FlowSystemDimensions] | None | Collection of dimension names to use for fitting. If None, all dimensions are used. | None |
Returns:
| Type | Description |
|---|---|
TemporalData | PeriodicData | None | xr.DataArray aligned to model coordinate system. If data is None, returns None. |
fit_effects_to_model_coords ¶
fit_effects_to_model_coords(label_prefix: str | None, effect_values: TemporalEffectsUser | PeriodicEffectsUser | None, label_suffix: str | None = None, dims: Collection[FlowSystemDimensions] | None = None, delimiter: str = '|') -> TemporalEffects | PeriodicEffects | None
Transform EffectValues from the user to Internal Datatypes aligned with model coordinates.
connect_and_transform ¶
Transform data for all elements using the new simplified approach.
add_elements ¶
Add Components(Storages, Boilers, Heatpumps, ...), Buses or Effects to the FlowSystem
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*elements | Element | childs of Element like Boiler, HeatPump, Bus,... modeling Elements | () |
create_model ¶
Create a linopy model from the FlowSystem.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
normalize_weights | bool | Whether to automatically normalize the weights (periods and scenarios) to sum up to 1 when solving. | True |
plot_network ¶
plot_network(path: bool | str | Path = 'flow_system.html', controls: bool | list[Literal['nodes', 'edges', 'layout', 'interaction', 'manipulation', 'physics', 'selection', 'renderer']] = True, show: bool | None = None) -> pyvis.network.Network | None
Visualizes the network structure of a FlowSystem using PyVis, saving it as an interactive HTML file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path | bool | str | Path | Path to save the HTML visualization. - | 'flow_system.html' |
controls | bool | list[Literal['nodes', 'edges', 'layout', 'interaction', 'manipulation', 'physics', 'selection', 'renderer']] | UI controls to add to the visualization. - | True |
show | bool | None | Whether to open the visualization in the web browser. | None |
Returns: - 'pyvis.network.Network' | None: The Network instance representing the visualization, or None if pyvis is not installed.
Examples:
>>> flow_system.plot_network()
>>> flow_system.plot_network(show=False)
>>> flow_system.plot_network(path='output/custom_network.html', controls=['nodes', 'layout'])
Notes: - This function requires pyvis. If not installed, the function prints a warning and returns None. - Nodes are styled based on type (e.g., circles for buses, boxes for components) and annotated with node information.
start_network_app ¶
Visualizes the network structure of a FlowSystem using Dash, Cytoscape, and networkx. Requires optional dependencies: dash, dash-cytoscape, dash-daq, networkx, flask, werkzeug.
sel ¶
sel(time: str | slice | list[str] | Timestamp | DatetimeIndex | None = None, period: int | slice | list[int] | Index | None = None, scenario: str | slice | list[str] | Index | None = None) -> FlowSystem
Select a subset of the flowsystem by the time coordinate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
time | str | slice | list[str] | Timestamp | DatetimeIndex | None | Time selection (e.g., slice('2023-01-01', '2023-12-31'), '2023-06-15', or list of times) | None |
period | int | slice | list[int] | Index | None | Period selection (e.g., slice(2023, 2024), or list of periods) | None |
scenario | str | slice | list[str] | Index | None | Scenario selection (e.g., slice('scenario1', 'scenario2'), or list of scenarios) | None |
Returns:
| Name | Type | Description |
|---|---|---|
FlowSystem | FlowSystem | New FlowSystem with selected data |
isel ¶
isel(time: int | slice | list[int] | None = None, period: int | slice | list[int] | None = None, scenario: int | slice | list[int] | None = None) -> FlowSystem
Select a subset of the flowsystem by integer indices.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
time | int | slice | list[int] | None | Time selection by integer index (e.g., slice(0, 100), 50, or [0, 5, 10]) | None |
period | int | slice | list[int] | None | Period selection by integer index (e.g., slice(0, 100), 50, or [0, 5, 10]) | None |
scenario | int | slice | list[int] | None | Scenario selection by integer index (e.g., slice(0, 3), 50, or [0, 5, 10]) | None |
Returns:
| Name | Type | Description |
|---|---|---|
FlowSystem | FlowSystem | New FlowSystem with selected data |
resample ¶
resample(time: str, method: Literal['mean', 'sum', 'max', 'min', 'first', 'last', 'std', 'var', 'median', 'count'] = 'mean', hours_of_last_timestep: int | float | None = None, hours_of_previous_timesteps: int | float | ndarray | None = None, **kwargs: Any) -> FlowSystem
Create a resampled FlowSystem by resampling data along the time dimension (like xr.Dataset.resample()). Only resamples data variables that have a time dimension.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
time | str | Resampling frequency (e.g., '3h', '2D', '1M') | required |
method | Literal['mean', 'sum', 'max', 'min', 'first', 'last', 'std', 'var', 'median', 'count'] | Resampling method. Recommended: 'mean', 'first', 'last', 'max', 'min' | 'mean' |
hours_of_last_timestep | int | float | None | New duration of the last time step. Defaults to the last time interval of the new timesteps | None |
hours_of_previous_timesteps | int | float | ndarray | None | New duration of the previous timestep. Defaults to the first time increment of the new timesteps | None |
**kwargs | Any | Additional arguments passed to xarray.resample() | {} |
Returns:
| Name | Type | Description |
|---|---|---|
FlowSystem | FlowSystem | New resampled FlowSystem |
items ¶
Return (label, element) pairs for all elements.
transform_data ¶
Transform the data of the interface to match the FlowSystem's dimensions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
flow_system | FlowSystem | The FlowSystem containing timing and dimensional information | required |
name_prefix | str | The prefix to use for the names of the variables. Defaults to '', which results in no prefix. | '' |
Raises:
| Type | Description |
|---|---|
NotImplementedError | Must be implemented by subclasses |
from_netcdf classmethod ¶
Load an instance from a NetCDF file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path | str | Path | Path to the NetCDF file | required |
Returns:
| Type | Description |
|---|---|
Interface | Interface instance |
Raises:
| Type | Description |
|---|---|
IOError | If file cannot be read |
ValueError | If file format is invalid |