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 | RangeIndex, periods: Index | None = None, scenarios: Index | None = None, clusters: Index | None = None, hours_of_last_timestep: int | float | None = None, hours_of_previous_timesteps: int | float | ndarray | None = None, weight_of_last_period: int | float | None = None, scenario_weights: Numeric_S | None = None, cluster_weight: Numeric_TPS | None = None, scenario_independent_sizes: bool | list[str] = True, scenario_independent_flow_rates: bool | list[str] = False, name: str | None = None, timestep_duration: DataArray | None = None)
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 | RangeIndex | 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 | Duration of the last timestep. If None, computed from the last time interval. | None |
hours_of_previous_timesteps | int | float | ndarray | None | Duration of previous timesteps. If None, computed from the first time interval. Can be a scalar (all previous timesteps have same duration) or array (different durations). Used to calculate previous values (e.g., uptime and downtime). | None |
weight_of_last_period | int | float | None | Weight/duration of the last period. If None, computed from the last period interval. Used for calculating sums over periods in multi-period models. | None |
scenario_weights | Numeric_S | None | The weights of each scenario. If None, all scenarios have the same weight (normalized to 1). Period weights are always computed internally from the period index (like timestep_duration for time). The final | None |
cluster_weight | Numeric_TPS | None | Weight for each cluster. If None (default), all clusters have weight 1.0. Used by cluster() to specify how many original timesteps each cluster represents. Multiply with timestep_duration for proper time aggregation in clustered models. | 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], status_parameters=...)
>>> heat_bus = fx.Bus('Heat', imbalance_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
Power user pattern - Efficient chaining without conversion overhead:
>>> # Instead of chaining (causes multiple conversions):
>>> result = flow_system.sel(time='2020-01').resample('2h') # Slow
>>>
>>> # Use dataset methods directly (single conversion):
>>> ds = flow_system.to_dataset()
>>> ds = FlowSystem._dataset_sel(ds, time='2020-01')
>>> ds = flow_system._dataset_resample(ds, freq='2h', method='mean')
>>> result = FlowSystem.from_dataset(ds) # Fast!
>>>
>>> # Available dataset methods:
>>> # - FlowSystem._dataset_sel(dataset, time=..., period=..., scenario=...)
>>> # - FlowSystem._dataset_isel(dataset, time=..., period=..., scenario=...)
>>> # - flow_system._dataset_resample(dataset, freq=..., method=..., **kwargs)
>>> 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.
- 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 optimize.
Attributes¶
flow_carriers property ¶
solution property writable ¶
Access the optimization solution as an xarray Dataset.
The solution is indexed by timesteps_extra (the original timesteps plus one additional timestep at the end). Variables that do not have data for the extra timestep (most variables except storage charge states) will contain NaN values at the final timestep.
Returns:
| Type | Description |
|---|---|
Dataset | None | xr.Dataset: The solution dataset with all optimization variable results, or None if the model hasn't been solved yet. |
Example
flow_system.optimize(solver) flow_system.solution.isel(time=slice(None, -1)) # Exclude trailing NaN (and final charge states)
variable_categories property ¶
Variable categories for filtering and segment expansion.
Returns:
| Type | Description |
|---|---|
dict[str, VariableCategory] | Dict mapping variable names to their VariableCategory. |
is_locked property ¶
Check if the FlowSystem is locked (has a solution).
A locked FlowSystem cannot be modified. Use reset() to unlock it.
optimize property ¶
Access optimization methods for this FlowSystem.
This property returns an OptimizeAccessor that can be called directly for standard optimization, or used to access specialized optimization modes.
Returns:
| Type | Description |
|---|---|
OptimizeAccessor | An OptimizeAccessor instance. |
Examples:
Standard optimization (call directly):
Access element solutions directly:
>>> flow_system.optimize(solver)
>>> boiler = flow_system.components['Boiler']
>>> print(boiler.solution)
Future specialized modes:
transform property ¶
Access transformation methods for this FlowSystem.
This property returns a TransformAccessor that provides methods to create transformed versions of this FlowSystem (e.g., clustered for time aggregation).
Returns:
| Type | Description |
|---|---|
TransformAccessor | A TransformAccessor instance. |
Examples:
Clustered optimization:
stats property ¶
Access statistics and plotting methods for optimization results.
This property returns a StatisticsAccessor that provides methods to analyze and visualize optimization results stored in this FlowSystem's solution.
Note
The FlowSystem must have a solution (from optimize() or solve()) before most statistics methods can be used.
Returns:
| Type | Description |
|---|---|
StatisticsAccessor | A cached StatisticsAccessor instance. |
Examples:
After optimization:
topology property ¶
Access network topology inspection and visualization methods.
This property returns a cached TopologyAccessor that provides methods to inspect the network structure and visualize it. The accessor is invalidated when the FlowSystem structure changes (via reset() or invalidate()).
Returns:
| Type | Description |
|---|---|
TopologyAccessor | A cached TopologyAccessor instance. |
Examples:
Visualize the network:
Interactive visualization:
>>> flow_system.topology.start_app()
>>> # ... interact with the visualization ...
>>> flow_system.topology.stop_app()
Get network structure info:
storages property ¶
All storage components as an ElementContainer.
Returns:
| Type | Description |
|---|---|
ElementContainer[Storage] | ElementContainer containing all Storage components in the FlowSystem, |
ElementContainer[Storage] | sorted by label for reproducibility. |
dims property ¶
indexes property ¶
temporal_dims property ¶
Temporal dimensions for summing over time.
Returns ['time', 'cluster'] for clustered systems, ['time'] otherwise.
temporal_weight property ¶
Combined temporal weight (timestep_duration × cluster_weight).
Use for converting rates to totals before summing. Note: cluster_weight is used even without a clusters dimension.
coords property ¶
Active coordinates for variable creation.
.. deprecated:: Use :attr:indexes instead.
Returns a dict of dimension names to coordinate arrays. When clustered, includes 'cluster' dimension before 'time'.
Returns:
| Type | Description |
|---|---|
dict[FlowSystemDimensions, Index] | Dict mapping dimension names to coordinate arrays. |
is_segmented property ¶
Check if this FlowSystem uses segmented time (RangeIndex instead of DatetimeIndex).
Segmented systems have variable timestep durations stored in timestep_duration, and use a RangeIndex for time coordinates instead of DatetimeIndex.
scenario_weights property writable ¶
Weights for each scenario.
Returns:
| Type | Description |
|---|---|
DataArray | None | xr.DataArray: Scenario weights with 'scenario' dimension |
weights property ¶
Weights for active dimensions (unit weights if not explicitly set).
Returns:
| Type | Description |
|---|---|
dict[str, DataArray] | Dict mapping dimension names to weight DataArrays. |
dict[str, DataArray] | Keys match :attr: |
Example
fs.weights['time'] # timestep durations fs.weights['cluster'] # cluster weights (unit if not set)
is_clustered property ¶
Check if this FlowSystem uses time series clustering.
Returns:
| Type | Description |
|---|---|
bool | True if the FlowSystem was created with transform.cluster(), |
bool | False otherwise. |
Example
fs_clustered = flow_system.transform.cluster(n_clusters=8, cluster_duration='1D') fs_clustered.is_clustered True flow_system.is_clustered False
scenario_independent_sizes property writable ¶
scenario_independent_flow_rates property writable ¶
prefix property ¶
The prefix used for naming transformed data (e.g., 'Boiler(Q_th)|status_parameters').
flow_system property ¶
Access the FlowSystem this interface is linked to.
Returns:
| Type | Description |
|---|---|
FlowSystem | The FlowSystem instance this interface belongs to. |
Raises:
| Type | Description |
|---|---|
RuntimeError | If interface has not been linked to a FlowSystem yet. |
Note
For Elements, this is set during add_elements(). For parameter classes, this is set recursively when the parent Element is registered.
Functions¶
calculate_timestep_duration staticmethod ¶
Calculate duration of each timestep in hours as a 1D DataArray.
For RangeIndex (segmented systems), returns None since duration cannot be computed from the index. Use timestep_duration parameter instead.
calculate_weight_per_period staticmethod ¶
Calculate weight of each period from period index differences.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
periods_extra | Index | Period index with an extra period at the end | required |
Returns:
| Type | Description |
|---|---|
DataArray | DataArray with weights for each period (1D, 'period' dimension) |
to_dataset ¶
Convert the FlowSystem to an xarray Dataset. Ensures FlowSystem is connected before serialization.
Data is stored in minimal form (scalars stay scalar, 1D arrays stay 1D) without broadcasting to full model dimensions. This provides significant memory savings for multi-period and multi-scenario models.
If a solution is present and include_solution=True, it will be included in the dataset with variable names prefixed by 'solution|' to avoid conflicts with FlowSystem configuration variables. Solution time coordinates are renamed to 'solution_time' to preserve them independently of the FlowSystem's time coordinates.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
include_solution | bool | Whether to include the optimization solution in the dataset. Defaults to True. Set to False to get only the FlowSystem structure without solution data (useful for copying or saving templates). | True |
include_original_data | bool | Whether to include clustering.original_data in the dataset. Defaults to True. Set to False for smaller files (~38% reduction) when clustering.plot.compare() isn't needed after loading. The core workflow (optimize → expand) works without original_data. | True |
Returns:
| Type | Description |
|---|---|
Dataset | xr.Dataset: Dataset containing all DataArrays with structure in attributes |
See Also
from_dataset: Create FlowSystem from dataset to_netcdf: Save to NetCDF file
from_dataset classmethod ¶
Create a FlowSystem from an xarray Dataset.
If the dataset contains solution data (variables prefixed with 'solution|'), the solution will be restored to the FlowSystem. Solution time coordinates are renamed back from 'solution_time' to 'time'.
Supports clustered datasets with (cluster, time) dimensions. When detected, creates a synthetic DatetimeIndex for compatibility and stores the clustered data structure for later use.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ds | Dataset | Dataset containing the FlowSystem data | required |
Returns:
| Type | Description |
|---|---|
FlowSystem | FlowSystem instance |
See Also
to_dataset: Convert FlowSystem to dataset from_netcdf: Load from NetCDF file
to_netcdf ¶
to_netcdf(path: str | Path, compression: int = 5, overwrite: bool = False, include_original_data: bool = True)
Save the FlowSystem to a NetCDF file. Ensures FlowSystem is connected before saving.
The FlowSystem's name is automatically set from the filename (without extension) when saving.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path | str | Path | The path to the netCDF file. Parent directories are created if they don't exist. | required |
compression | int | The compression level to use when saving the file (0-9). | 5 |
overwrite | bool | If True, overwrite existing file. If False, raise error if file exists. | False |
include_original_data | bool | Whether to include clustering.original_data in the file. Defaults to True. Set to False for smaller files (~38% reduction) when clustering.plot.compare() isn't needed after loading. | True |
Raises:
| Type | Description |
|---|---|
FileExistsError | If overwrite=False and file already exists. |
from_netcdf classmethod ¶
Load a FlowSystem from a NetCDF file.
The FlowSystem's name is automatically derived from the filename (without extension), overriding any name that may have been stored.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path | str | Path | Path to the NetCDF file | required |
Returns:
| Type | Description |
|---|---|
FlowSystem | FlowSystem instance with name set from filename |
from_old_results classmethod ¶
Load a FlowSystem from old-format Results files (pre-v5 API).
This method loads results saved with the deprecated Results API (which used multiple files: *--flow_system.nc4, *--solution.nc4) and converts them to a FlowSystem with the solution attached.
The method performs the following:
- Loads the old multi-file format
- Renames deprecated parameters in the FlowSystem structure (e.g.,
on_off_parameters→status_parameters) - Attaches the solution data to the FlowSystem
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
folder | str | Path | Directory containing the saved result files | required |
name | str | Base name of the saved files (without extensions) | required |
Returns:
| Type | Description |
|---|---|
FlowSystem | FlowSystem instance with solution attached |
Warning
This is a best-effort migration for accessing old results:
- Solution variable names are NOT renamed - only basic variables work (flow rates, sizes, charge states, effect totals)
- Advanced variable access may require using the original names
- Summary metadata (solver info, timing) is not loaded
For full compatibility, re-run optimizations with the new API.
Examples:
# Load old results
fs = FlowSystem.from_old_results('results_folder', 'my_optimization')
# Access basic solution data
fs.solution['Boiler(Q_th)|flow_rate'].plot()
# Save in new single-file format
fs.to_netcdf('my_optimization.nc')
Deprecated
This method will be removed in v6.
from_old_dataset classmethod ¶
Load a FlowSystem from an old-format dataset file (pre-v5 API).
This method loads a FlowSystem saved with older versions of flixopt (the *--flow_system.nc4 file) and converts parameter names to the current API. Unlike :meth:from_old_results, this does not require a solution file and returns a FlowSystem without solution data.
The method performs the following:
- Loads the old netCDF format
- Renames deprecated parameters in the FlowSystem structure (e.g.,
on_off_parameters→status_parameters)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path | str | Path | Path to the old-format FlowSystem file (typically | required |
Returns:
| Type | Description |
|---|---|
FlowSystem | FlowSystem instance without solution |
Warning
This is a best-effort migration for loading old FlowSystem definitions. For full compatibility, consider re-saving with the new API after loading.
Examples:
# Load old FlowSystem file
fs = FlowSystem.from_old_dataset('results/my_run--flow_system.nc4')
# Modify and optimize with current API
fs.optimize(solver)
# Save in new single-file format
fs.to_netcdf('my_run.nc')
Deprecated
This method will be removed in v6.
copy ¶
Create a copy of the FlowSystem without optimization state.
Creates a new FlowSystem with copies of all elements, but without: - The solution dataset - The optimization model - Element submodels and variable/constraint names
This is useful for creating variations of a FlowSystem for different optimization scenarios without affecting the original.
Returns:
| Type | Description |
|---|---|
FlowSystem | A new FlowSystem instance that can be modified and optimized independently. |
Examples:
>>> original = FlowSystem(timesteps)
>>> original.add_elements(boiler, bus)
>>> original.optimize(solver) # Original now has solution
>>>
>>> # Create a copy to try different parameters
>>> variant = original.copy() # No solution, can be modified
>>> variant.add_elements(new_component)
>>> variant.optimize(solver)
get_structure ¶
to_json ¶
fit_to_model_coords ¶
fit_to_model_coords(name: str, data: NumericOrBool | None, dims: Collection[FlowSystemDimensions] | None = None) -> xr.DataArray | None
Fit data to model coordinate system (currently time, but extensible).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name | str | Name of the data | required |
data | NumericOrBool | None | Data to fit to model coordinates (accepts any dimensionality including scalars) | required |
dims | Collection[FlowSystemDimensions] | None | Collection of dimension names to use for fitting. If None, all dimensions are used. | None |
Returns:
| Type | Description |
|---|---|
DataArray | 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: Effect_TPS | Numeric_TPS | None, label_suffix: str | None = None, dims: Collection[FlowSystemDimensions] | None = None, delimiter: str = '|') -> Effect_TPS | None
Transform EffectValues from the user to Internal Datatypes aligned with model coordinates.
connect_and_transform ¶
Connect the network and transform all element data to model coordinates.
This method performs the following steps:
- Connects flows to buses (establishing the network topology)
- Registers any missing carriers from CONFIG defaults
- Assigns colors to elements without explicit colors
- Transforms all element data to xarray DataArrays aligned with FlowSystem coordinates (time, period, scenario)
- Validates system integrity
This is called automatically by :meth:build_model and :meth:optimize.
Warning
After this method runs, element attributes (e.g., flow.size, flow.relative_minimum) contain transformed xarray DataArrays, not the original input values. If you modify element attributes after transformation, call :meth:invalidate to ensure the changes take effect on the next optimization.
Note
This method is idempotent within a single model lifecycle - calling it multiple times has no effect once connected_and_transformed is True. Use :meth:invalidate to reset this flag.
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 | () |
Raises:
| Type | Description |
|---|---|
RuntimeError | If the FlowSystem is locked (has a solution). Call |
add_carriers ¶
Register a custom carrier for this FlowSystem.
Custom carriers registered on the FlowSystem take precedence over CONFIG.Carriers defaults when resolving colors and units for buses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
carriers | Carrier | Carrier objects defining the carrier properties. | () |
Raises:
| Type | Description |
|---|---|
RuntimeError | If the FlowSystem is locked (has a solution). Call |
Examples:
import flixopt as fx
fs = fx.FlowSystem(timesteps)
# Define and register custom carriers
biogas = fx.Carrier('biogas', '#228B22', 'kW', 'Biogas fuel')
fs.add_carriers(biogas)
# Now buses can reference this carrier by name
bus = fx.Bus('BioGasNetwork', carrier='biogas')
fs.add_elements(bus)
# The carrier color will be used in plots automatically
get_carrier ¶
Get the carrier for a bus or flow.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label | str | Bus label (e.g., 'Fernwärme') or flow label (e.g., 'Boiler(Q_th)'). | required |
Returns:
| Type | Description |
|---|---|
Carrier | None | Carrier or None if not found. |
Note
To access a carrier directly by name, use flow_system.carriers['electricity'].
Raises:
| Type | Description |
|---|---|
RuntimeError | If FlowSystem is not connected_and_transformed. |
create_model ¶
Create a linopy model from the FlowSystem.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
normalize_weights | bool | None | Deprecated. Scenario weights are now always normalized in FlowSystem. | None |
build_model ¶
Build the optimization model for this FlowSystem.
This method prepares the FlowSystem for optimization by: 1. Connecting and transforming all elements (if not already done) 2. Creating the FlowSystemModel with all variables and constraints 3. Adding clustering constraints (if this is a clustered FlowSystem) 4. Adding typical periods modeling (if this is a reduced FlowSystem)
After calling this method, self.model will be available for inspection before solving.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
normalize_weights | bool | None | Deprecated. Scenario weights are now always normalized in FlowSystem. | None |
Returns:
| Type | Description |
|---|---|
FlowSystem | Self, for method chaining. |
Examples:
solve ¶
Solve the optimization model and populate the solution.
This method solves the previously built model using the specified solver. After solving, self.solution will contain the optimization results, and each element's .solution property will provide access to its specific variables.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
solver | _Solver | The solver to use (e.g., HighsSolver, GurobiSolver). | required |
Returns:
| Type | Description |
|---|---|
FlowSystem | Self, for method chaining. |
Raises:
| Type | Description |
|---|---|
RuntimeError | If the model has not been built yet (call build_model first). |
RuntimeError | If the model is infeasible. |
Examples:
get_variables_by_category ¶
Get variable names matching any of the specified categories.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*categories | VariableCategory | One or more VariableCategory values to filter by. | () |
from_solution | bool | If True, only return variables present in solution. If False, return all registered variables matching categories. | True |
Returns:
| Type | Description |
|---|---|
list[str] | List of variable names matching any of the specified categories. |
Example
fs.get_variables_by_category(VariableCategory.FLOW_RATE) ['Boiler(Q_th)|flow_rate', 'CHP(Q_th)|flow_rate', ...] fs.get_variables_by_category(VariableCategory.SIZE, VariableCategory.INVESTED) ['Boiler(Q_th)|size', 'Boiler(Q_th)|invested', ...]
reset ¶
Clear optimization state to allow modifications.
This method unlocks the FlowSystem by clearing: - The solution dataset - The optimization model - All element submodels and variable/constraint names - The connected_and_transformed flag
After calling reset(), the FlowSystem can be modified again (e.g., adding elements or carriers).
Returns:
| Type | Description |
|---|---|
FlowSystem | Self, for method chaining. |
Examples:
invalidate ¶
Invalidate the model to allow re-transformation after modifying elements.
Call this after modifying existing element attributes (e.g., flow.size, flow.relative_minimum) to ensure changes take effect on the next optimization. The next call to :meth:optimize or :meth:build_model will re-run :meth:connect_and_transform.
Note
Adding new elements via :meth:add_elements automatically invalidates the model. This method is only needed when modifying attributes of elements that are already part of the FlowSystem.
Returns:
| Type | Description |
|---|---|
FlowSystem | Self, for method chaining. |
Raises:
| Type | Description |
|---|---|
RuntimeError | If the FlowSystem has a solution. Call :meth: |
Examples:
Modify a flow's size and re-optimize:
>>> flow_system.optimize(solver)
>>> flow_system.reset() # Clear solution first
>>> flow_system.components['Boiler'].inputs[0].size = 200
>>> flow_system.invalidate()
>>> flow_system.optimize(solver) # Re-runs connect_and_transform
Modify before first optimization:
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
Deprecated: Use flow_system.topology.plot() instead.
Visualizes the network structure of a FlowSystem using PyVis.
start_network_app ¶
Deprecated: Use flow_system.topology.start_app() instead.
Visualizes the network structure using Dash and Cytoscape.
stop_network_app ¶
Deprecated: Use flow_system.topology.stop_app() instead.
Stop the network visualization server.
network_infos ¶
Deprecated: Use flow_system.topology.infos() instead.
Get network topology information as dictionaries.
sum_temporal ¶
Sum data over temporal dimensions with full temporal weighting.
Applies both timestep_duration and cluster_weight, then sums over temporal dimensions. Use this to convert rates to totals (e.g., flow_rate → total_energy).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data | DataArray | Data with time dimension (and optionally cluster). Typically a rate (e.g., flow_rate in MW, status as 0/1). | required |
Returns:
| Type | Description |
|---|---|
DataArray | Data summed over temporal dims with full temporal weighting applied. |
Example
total_energy = fs.sum_temporal(flow_rate) # MW → MWh total active_hours = fs.sum_temporal(status) # count → hours
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 label.
.. deprecated:: Use flow_system.transform.sel() instead. Will be removed in v6.0.0.
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') | 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., 'scenario1', or list of scenarios) | None |
Returns:
| Name | Type | Description |
|---|---|---|
FlowSystem | FlowSystem | New FlowSystem with selected data (no solution). |
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.
.. deprecated:: Use flow_system.transform.isel() instead. Will be removed in v6.0.0.
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 | None |
scenario | int | slice | list[int] | None | Scenario selection by integer index | None |
Returns:
| Name | Type | Description |
|---|---|---|
FlowSystem | FlowSystem | New FlowSystem with selected data (no solution). |
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.
.. deprecated:: Use flow_system.transform.resample() instead. Will be removed in v6.0.0.
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 | Duration of the last timestep after resampling. | None |
hours_of_previous_timesteps | int | float | ndarray | None | Duration of previous timesteps after resampling. | None |
**kwargs | Any | Additional arguments passed to xarray.resample() | {} |
Returns:
| Name | Type | Description |
|---|---|---|
FlowSystem | FlowSystem | New resampled FlowSystem (no solution). |
transform_data ¶
Transform the data of the interface to match the FlowSystem's dimensions.
Uses self._prefix (set during link_to_flow_system()) to name transformed data.
Raises:
| Type | Description |
|---|---|
NotImplementedError | Must be implemented by subclasses |
Note
The FlowSystem reference is available via self._flow_system (for Interface objects) or self.flow_system property (for Element objects). Elements must be registered to a FlowSystem before calling this method.
link_to_flow_system ¶
Link this interface and all nested interfaces to a FlowSystem.
This method is called automatically during element registration to enable elements to access FlowSystem properties without passing the reference through every method call. It also sets the prefix used for naming transformed data.
Subclasses with nested Interface objects should override this method to propagate the link to their nested interfaces by calling super().link_to_flow_system(flow_system, prefix) first, then linking nested objects with appropriate prefixes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
flow_system | FlowSystem | The FlowSystem to link to | required |
prefix | str | The prefix for naming transformed data (e.g., 'Boiler(Q_th)') | '' |
Examples:
Override in a subclass with nested interfaces:
def link_to_flow_system(self, flow_system, prefix: str = '') -> None:
super().link_to_flow_system(flow_system, prefix)
if self.nested_interface is not None:
self.nested_interface.link_to_flow_system(flow_system, f'{prefix}|nested' if prefix else 'nested')
Creating an Interface dynamically during modeling: