flixopt 2.1.4__tar.gz → 2.1.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of flixopt might be problematic. Click here for more details.
- {flixopt-2.1.4 → flixopt-2.1.6}/.github/workflows/python-app.yaml +5 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/CHANGELOG.md +21 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/PKG-INFO +23 -9
- {flixopt-2.1.4 → flixopt-2.1.6}/examples/02_Complex/complex_example.py +1 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/aggregation.py +0 -1
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/components.py +130 -21
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/flow_system.py +53 -0
- flixopt-2.1.6/flixopt/network_app.py +612 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt.egg-info/PKG-INFO +23 -9
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt.egg-info/SOURCES.txt +2 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt.egg-info/requires.txt +18 -2
- {flixopt-2.1.4 → flixopt-2.1.6}/pyproject.toml +32 -16
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/conftest.py +5 -6
- flixopt-2.1.6/tests/test_network_app.py +29 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/.github/CONTRIBUTING.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/.github/pull_request_template.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/.gitignore +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/LICENSE +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/README.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/SUMMARY.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/contribute.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/examples/00-Minimal Example.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/examples/01-Basic Example.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/examples/02-Complex Example.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/examples/03-Calculation Modes.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/examples/index.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/faq/contribute.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/faq/index.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/getting-started.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/images/architecture_flixOpt-pre2.0.0.png +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/images/architecture_flixOpt.png +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/images/flixopt-icon.svg +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/index.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/javascripts/mathjax.js +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/user-guide/Mathematical Notation/Bus.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/user-guide/Mathematical Notation/Effects, Penalty & Objective.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/user-guide/Mathematical Notation/Flow.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/user-guide/Mathematical Notation/LinearConverter.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/user-guide/Mathematical Notation/Piecewise.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/user-guide/Mathematical Notation/Storage.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/user-guide/Mathematical Notation/index.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/user-guide/Mathematical Notation/others.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/docs/user-guide/index.md +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/examples/00_Minmal/minimal_example.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/examples/01_Simple/simple_example.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/examples/02_Complex/complex_example_results.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/examples/03_Calculation_types/Zeitreihen2020.csv +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/examples/03_Calculation_types/example_calculation_types.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/__init__.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/calculation.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/commons.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/config.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/config.yaml +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/core.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/effects.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/elements.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/features.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/interface.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/io.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/linear_converters.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/plotting.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/results.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/solvers.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/structure.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt/utils.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt.egg-info/dependency_links.txt +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/flixopt.egg-info/top_level.txt +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/mkdocs.yml +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/pics/architecture_flixOpt-pre2.0.0.png +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/pics/architecture_flixOpt.png +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/pics/flixOpt_plotting.jpg +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/pics/flixopt-icon.svg +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/pics/pics.pptx +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/scripts/extract_release_notes.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/scripts/gen_ref_pages.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/setup.cfg +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/__init__.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/ressources/Zeitreihen2020.csv +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/run_all_tests.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_bus.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_component.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_dataconverter.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_effect.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_examples.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_flow.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_functional.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_integration.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_io.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_linear_converter.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_on_hours_computation.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_plots.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_results_plots.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_storage.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/test_timeseries.py +0 -0
- {flixopt-2.1.4 → flixopt-2.1.6}/tests/todos.txt +0 -0
|
@@ -200,6 +200,11 @@ jobs:
|
|
|
200
200
|
with:
|
|
201
201
|
python-version: "3.11"
|
|
202
202
|
|
|
203
|
+
- name: Sync changelog to docs
|
|
204
|
+
run: |
|
|
205
|
+
cp CHANGELOG.md docs/changelog.md
|
|
206
|
+
echo "✅ Synced changelog to docs"
|
|
207
|
+
|
|
203
208
|
- name: Install documentation dependencies
|
|
204
209
|
run: |
|
|
205
210
|
python -m pip install --upgrade pip
|
|
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
|
|
11
|
+
## [2.1.6] - 2025-09-02
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- `Sink`, `Source` and `SourceAndSink` now accept multiple `flows` as `inputs` and `outputs` instead of just one. This enables to model more use cases using these classes. [[#291](https://github.com/flixOpt/flixopt/pull/291) by [@FBumann](https://github.com/FBumann)]
|
|
15
|
+
- Further, both `Sink` and `Source` now have a `prevent_simultaneous_flow_rates` argument to prevent simultaneous flow rates of more than one of their Flows. [[#291](https://github.com/flixOpt/flixopt/pull/291) by [@FBumann](https://github.com/FBumann)]
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- Added `FlowSystem.start_network_app()` and `FlowSystem.stop_network_app()` to easily visualize the network structure of a flow system in an interactive dash web app. This is still experimental and might change in the future. [[#293](https://github.com/flixOpt/flixopt/pull/293) by [@FBumann](https://github.com/FBumann)]
|
|
19
|
+
|
|
20
|
+
### Deprecated
|
|
21
|
+
- For the classes `Sink`, `Source` and `SourceAndSink`: `.sink`, `.source` and `.prevent_simultaneous_sink_and_source` are deprecated in favor of the new arguments `inputs`, `outputs` and `prevent_simultaneous_flow_rates`. [[#291](https://github.com/flixOpt/flixopt/pull/291) by [@FBumann](https://github.com/FBumann)]
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- Fixed testing issue with new `linopy` version 0.5.6 [[#296](https://github.com/flixOpt/flixopt/pull/296) by [@FBumann](https://github.com/FBumann)]
|
|
25
|
+
|
|
26
|
+
## [2.1.5] - 2025-07-08
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- Fixed Docs deployment
|
|
30
|
+
|
|
10
31
|
## [2.1.4] - 2025-07-08
|
|
11
32
|
|
|
12
33
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flixopt
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.6
|
|
4
4
|
Summary: Vector based energy and material flow optimization framework in Python.
|
|
5
5
|
Author-email: "Chair of Building Energy Systems and Heat Supply, TU Dresden" <peter.stange@tu-dresden.de>, Felix Bumann <felixbumann387@gmail.com>, Felix Panitz <baumbude@googlemail.com>, Peter Stange <peter.stange@tu-dresden.de>
|
|
6
6
|
Maintainer-email: Felix Bumann <felixbumann387@gmail.com>, Peter Stange <peter.stange@tu-dresden.de>
|
|
@@ -18,13 +18,12 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
18
18
|
Classifier: Intended Audience :: Developers
|
|
19
19
|
Classifier: Intended Audience :: Science/Research
|
|
20
20
|
Classifier: Topic :: Scientific/Engineering
|
|
21
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
22
21
|
Requires-Python: >=3.10
|
|
23
22
|
Description-Content-Type: text/markdown
|
|
24
23
|
License-File: LICENSE
|
|
25
24
|
Requires-Dist: numpy<3,>=1.21.5
|
|
26
25
|
Requires-Dist: pandas<3,>=2.0.0
|
|
27
|
-
Requires-Dist: linopy<0.6
|
|
26
|
+
Requires-Dist: linopy<0.5.6,>=0.5.1
|
|
28
27
|
Requires-Dist: netcdf4<2,>=1.6.1
|
|
29
28
|
Requires-Dist: PyYAML<7,>=6.0.0
|
|
30
29
|
Requires-Dist: rich>=13.0.0
|
|
@@ -32,6 +31,22 @@ Requires-Dist: tomli>=2.0.1; python_version < "3.11"
|
|
|
32
31
|
Requires-Dist: highspy>=1.5.3
|
|
33
32
|
Requires-Dist: matplotlib<4.0.0,>=3.5.2
|
|
34
33
|
Requires-Dist: plotly<6.0.0,>=5.15.0
|
|
34
|
+
Provides-Extra: network-viz
|
|
35
|
+
Requires-Dist: dash>=3.0.0; extra == "network-viz"
|
|
36
|
+
Requires-Dist: dash-cytoscape>=1.0.0; extra == "network-viz"
|
|
37
|
+
Requires-Dist: dash-daq>=0.6.0; extra == "network-viz"
|
|
38
|
+
Requires-Dist: networkx>=3.0.0; extra == "network-viz"
|
|
39
|
+
Requires-Dist: werkzeug>=3.0.0; extra == "network-viz"
|
|
40
|
+
Provides-Extra: full
|
|
41
|
+
Requires-Dist: pyvis==0.3.1; extra == "full"
|
|
42
|
+
Requires-Dist: tsam<3.0.0,>=2.3.1; extra == "full"
|
|
43
|
+
Requires-Dist: scipy<2.0.0,>=1.15.1; extra == "full"
|
|
44
|
+
Requires-Dist: gurobipy>=10.0.0; extra == "full"
|
|
45
|
+
Requires-Dist: dash>=3.0.0; extra == "full"
|
|
46
|
+
Requires-Dist: dash-cytoscape>=1.0.0; extra == "full"
|
|
47
|
+
Requires-Dist: dash-daq>=0.6.0; extra == "full"
|
|
48
|
+
Requires-Dist: networkx>=3.0.0; extra == "full"
|
|
49
|
+
Requires-Dist: werkzeug>=3.0.0; extra == "full"
|
|
35
50
|
Provides-Extra: dev
|
|
36
51
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
37
52
|
Requires-Dist: ruff>=0.9.0; extra == "dev"
|
|
@@ -39,12 +54,11 @@ Requires-Dist: pyvis==0.3.1; extra == "dev"
|
|
|
39
54
|
Requires-Dist: tsam<3.0.0,>=2.3.1; extra == "dev"
|
|
40
55
|
Requires-Dist: scipy<2.0.0,>=1.15.1; extra == "dev"
|
|
41
56
|
Requires-Dist: gurobipy>=10.0.0; extra == "dev"
|
|
42
|
-
|
|
43
|
-
Requires-Dist:
|
|
44
|
-
Requires-Dist:
|
|
45
|
-
Requires-Dist:
|
|
46
|
-
Requires-Dist:
|
|
47
|
-
Requires-Dist: gurobipy>=10.0.0; extra == "full"
|
|
57
|
+
Requires-Dist: dash>=3.0.0; extra == "dev"
|
|
58
|
+
Requires-Dist: dash-cytoscape>=1.0.0; extra == "dev"
|
|
59
|
+
Requires-Dist: dash-daq>=0.6.0; extra == "dev"
|
|
60
|
+
Requires-Dist: networkx>=3.0.0; extra == "dev"
|
|
61
|
+
Requires-Dist: werkzeug>=3.0.0; extra == "dev"
|
|
48
62
|
Provides-Extra: docs
|
|
49
63
|
Requires-Dist: mkdocs-material<10,>=9.0.0; extra == "docs"
|
|
50
64
|
Requires-Dist: mkdocstrings-python>=1.0.0; extra == "docs"
|
|
@@ -182,6 +182,7 @@ if __name__ == '__main__':
|
|
|
182
182
|
flow_system.add_elements(bhkw_2) if use_chp_with_piecewise_conversion else flow_system.add_elements(bhkw)
|
|
183
183
|
|
|
184
184
|
pprint(flow_system) # Get a string representation of the FlowSystem
|
|
185
|
+
flow_system.start_network_app() # Start the network app. DOes only work with extra dependencies installed
|
|
185
186
|
|
|
186
187
|
# --- Solve FlowSystem ---
|
|
187
188
|
calculation = fx.FullCalculation('complex example', flow_system, time_indices)
|
|
@@ -3,6 +3,7 @@ This module contains the basic components of the flixopt framework.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import logging
|
|
6
|
+
import warnings
|
|
6
7
|
from typing import TYPE_CHECKING, Dict, List, Literal, Optional, Set, Tuple, Union
|
|
7
8
|
|
|
8
9
|
import linopy
|
|
@@ -586,52 +587,160 @@ class SourceAndSink(Component):
|
|
|
586
587
|
def __init__(
|
|
587
588
|
self,
|
|
588
589
|
label: str,
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
590
|
+
inputs: List[Flow] = None,
|
|
591
|
+
outputs: List[Flow] = None,
|
|
592
|
+
prevent_simultaneous_flow_rates: bool = True,
|
|
592
593
|
meta_data: Optional[Dict] = None,
|
|
594
|
+
**kwargs,
|
|
593
595
|
):
|
|
594
596
|
"""
|
|
595
597
|
Args:
|
|
596
598
|
label: The label of the Element. Used to identify it in the FlowSystem
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
599
|
+
outputs: output-flows of this component
|
|
600
|
+
inputs: input-flows of this component
|
|
601
|
+
prevent_simultaneous_flow_rates: If True, inflow and outflow can not be active simultaniously.
|
|
600
602
|
meta_data: used to store more information about the Element. Is not used internally, but saved in the results. Only use python native types.
|
|
601
603
|
"""
|
|
604
|
+
source = kwargs.pop('source', None)
|
|
605
|
+
sink = kwargs.pop('sink', None)
|
|
606
|
+
prevent_simultaneous_sink_and_source = kwargs.pop('prevent_simultaneous_sink_and_source', None)
|
|
607
|
+
if source is not None:
|
|
608
|
+
warnings.deprecated(
|
|
609
|
+
'The use of the source argument is deprecated. Use the outputs argument instead.',
|
|
610
|
+
stacklevel=2,
|
|
611
|
+
)
|
|
612
|
+
if outputs is not None:
|
|
613
|
+
raise ValueError('Either source or outputs can be specified, but not both.')
|
|
614
|
+
outputs = [source]
|
|
615
|
+
|
|
616
|
+
if sink is not None:
|
|
617
|
+
warnings.deprecated(
|
|
618
|
+
'The use of the sink argument is deprecated. Use the outputs argument instead.',
|
|
619
|
+
stacklevel=2,
|
|
620
|
+
)
|
|
621
|
+
if inputs is not None:
|
|
622
|
+
raise ValueError('Either sink or outputs can be specified, but not both.')
|
|
623
|
+
inputs = [sink]
|
|
624
|
+
|
|
625
|
+
if prevent_simultaneous_sink_and_source is not None:
|
|
626
|
+
warnings.deprecated(
|
|
627
|
+
'The use of the prevent_simultaneous_sink_and_source argument is deprecated. Use the prevent_simultaneous_flow_rates argument instead.',
|
|
628
|
+
stacklevel=2,
|
|
629
|
+
)
|
|
630
|
+
prevent_simultaneous_flow_rates = prevent_simultaneous_sink_and_source
|
|
631
|
+
|
|
602
632
|
super().__init__(
|
|
603
633
|
label,
|
|
604
|
-
inputs=
|
|
605
|
-
outputs=
|
|
606
|
-
prevent_simultaneous_flows=
|
|
634
|
+
inputs=inputs,
|
|
635
|
+
outputs=outputs,
|
|
636
|
+
prevent_simultaneous_flows=inputs + outputs if prevent_simultaneous_flow_rates is True else None,
|
|
607
637
|
meta_data=meta_data,
|
|
608
638
|
)
|
|
609
|
-
self.
|
|
610
|
-
|
|
611
|
-
|
|
639
|
+
self.prevent_simultaneous_flow_rates = prevent_simultaneous_flow_rates
|
|
640
|
+
|
|
641
|
+
@property
|
|
642
|
+
def source(self) -> Flow:
|
|
643
|
+
warnings.warn(
|
|
644
|
+
'The source property is deprecated. Use the outputs property instead.',
|
|
645
|
+
DeprecationWarning,
|
|
646
|
+
stacklevel=2,
|
|
647
|
+
)
|
|
648
|
+
return self.outputs[0]
|
|
649
|
+
|
|
650
|
+
@property
|
|
651
|
+
def sink(self) -> Flow:
|
|
652
|
+
warnings.warn(
|
|
653
|
+
'The sink property is deprecated. Use the outputs property instead.',
|
|
654
|
+
DeprecationWarning,
|
|
655
|
+
stacklevel=2,
|
|
656
|
+
)
|
|
657
|
+
return self.inputs[0]
|
|
658
|
+
|
|
659
|
+
@property
|
|
660
|
+
def prevent_simultaneous_sink_and_source(self) -> bool:
|
|
661
|
+
warnings.warn(
|
|
662
|
+
'The prevent_simultaneous_sink_and_source property is deprecated. Use the prevent_simultaneous_flow_rates property instead.',
|
|
663
|
+
DeprecationWarning,
|
|
664
|
+
stacklevel=2,
|
|
665
|
+
)
|
|
666
|
+
return self.prevent_simultaneous_flow_rates
|
|
612
667
|
|
|
613
668
|
|
|
614
669
|
@register_class_for_io
|
|
615
670
|
class Source(Component):
|
|
616
|
-
def __init__(
|
|
671
|
+
def __init__(
|
|
672
|
+
self,
|
|
673
|
+
label: str,
|
|
674
|
+
outputs: List[Flow] = None,
|
|
675
|
+
meta_data: Optional[Dict] = None,
|
|
676
|
+
prevent_simultaneous_flow_rates: bool = False,
|
|
677
|
+
**kwargs
|
|
678
|
+
):
|
|
617
679
|
"""
|
|
618
680
|
Args:
|
|
619
681
|
label: The label of the Element. Used to identify it in the FlowSystem
|
|
620
|
-
|
|
682
|
+
outputs: output-flows of source
|
|
621
683
|
meta_data: used to store more information about the Element. Is not used internally, but saved in the results. Only use python native types.
|
|
622
684
|
"""
|
|
623
|
-
|
|
624
|
-
|
|
685
|
+
source = kwargs.pop('source', None)
|
|
686
|
+
if source is not None:
|
|
687
|
+
warnings.warn(
|
|
688
|
+
'The use of the source argument is deprecated. Use the outputs argument instead.',
|
|
689
|
+
DeprecationWarning,
|
|
690
|
+
stacklevel=2,
|
|
691
|
+
)
|
|
692
|
+
if outputs is not None:
|
|
693
|
+
raise ValueError('Either source or outputs can be specified, but not both.')
|
|
694
|
+
outputs = [source]
|
|
695
|
+
|
|
696
|
+
self.prevent_simultaneous_flow_rates = prevent_simultaneous_flow_rates
|
|
697
|
+
super().__init__(label, outputs=outputs, meta_data=meta_data, prevent_simultaneous_flows=outputs if prevent_simultaneous_flow_rates else None)
|
|
698
|
+
|
|
699
|
+
@property
|
|
700
|
+
def source(self) -> Flow:
|
|
701
|
+
warnings.warn(
|
|
702
|
+
'The source property is deprecated. Use the outputs property instead.',
|
|
703
|
+
DeprecationWarning,
|
|
704
|
+
stacklevel=2,
|
|
705
|
+
)
|
|
706
|
+
return self.outputs[0]
|
|
625
707
|
|
|
626
708
|
|
|
627
709
|
@register_class_for_io
|
|
628
710
|
class Sink(Component):
|
|
629
|
-
def __init__(
|
|
711
|
+
def __init__(
|
|
712
|
+
self,
|
|
713
|
+
label: str,
|
|
714
|
+
inputs: List[Flow] = None,
|
|
715
|
+
meta_data: Optional[Dict] = None,
|
|
716
|
+
prevent_simultaneous_flow_rates: bool = False,
|
|
717
|
+
**kwargs
|
|
718
|
+
):
|
|
630
719
|
"""
|
|
631
720
|
Args:
|
|
632
721
|
label: The label of the Element. Used to identify it in the FlowSystem
|
|
633
|
-
|
|
634
|
-
|
|
722
|
+
inputs: output-flows of source
|
|
723
|
+
meta_data: used to store more information about the Element. Is not used internally, but saved in the results. Only use python native types.
|
|
635
724
|
"""
|
|
636
|
-
|
|
637
|
-
|
|
725
|
+
sink = kwargs.pop('sink', None)
|
|
726
|
+
if sink is not None:
|
|
727
|
+
warnings.warn(
|
|
728
|
+
'The use of the sink argument is deprecated. Use the outputs argument instead.',
|
|
729
|
+
DeprecationWarning,
|
|
730
|
+
stacklevel=2,
|
|
731
|
+
)
|
|
732
|
+
if inputs is not None:
|
|
733
|
+
raise ValueError('Either sink or outputs can be specified, but not both.')
|
|
734
|
+
inputs = [sink]
|
|
735
|
+
|
|
736
|
+
self.prevent_simultaneous_flow_rates = prevent_simultaneous_flow_rates
|
|
737
|
+
super().__init__(label, inputs=inputs, meta_data=meta_data, prevent_simultaneous_flows=inputs if prevent_simultaneous_flow_rates else None)
|
|
738
|
+
|
|
739
|
+
@property
|
|
740
|
+
def sink(self) -> Flow:
|
|
741
|
+
warnings.warn(
|
|
742
|
+
'The sink property is deprecated. Use the outputs property instead.',
|
|
743
|
+
DeprecationWarning,
|
|
744
|
+
stacklevel=2,
|
|
745
|
+
)
|
|
746
|
+
return self.inputs[0]
|
|
@@ -61,6 +61,8 @@ class FlowSystem:
|
|
|
61
61
|
|
|
62
62
|
self._connected = False
|
|
63
63
|
|
|
64
|
+
self._network_app = None
|
|
65
|
+
|
|
64
66
|
@classmethod
|
|
65
67
|
def from_dataset(cls, ds: xr.Dataset):
|
|
66
68
|
timesteps_extra = pd.DatetimeIndex(ds.attrs['timesteps_extra'], name='time')
|
|
@@ -241,6 +243,57 @@ class FlowSystem:
|
|
|
241
243
|
node_infos, edge_infos = self.network_infos()
|
|
242
244
|
return plotting.plot_network(node_infos, edge_infos, path, controls, show)
|
|
243
245
|
|
|
246
|
+
def start_network_app(self):
|
|
247
|
+
"""Visualizes the network structure of a FlowSystem using Dash, Cytoscape, and networkx.
|
|
248
|
+
Requires optional dependencies: dash, dash-cytoscape, networkx, werkzeug.
|
|
249
|
+
"""
|
|
250
|
+
from .network_app import DASH_CYTOSCAPE_AVAILABLE, VISUALIZATION_ERROR, flow_graph, shownetwork
|
|
251
|
+
|
|
252
|
+
warnings.warn(
|
|
253
|
+
'The network visualization is still experimental and might change in the future.',
|
|
254
|
+
stacklevel=2,
|
|
255
|
+
category=UserWarning,
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
if not DASH_CYTOSCAPE_AVAILABLE:
|
|
259
|
+
raise ImportError(
|
|
260
|
+
f"Network visualization requires optional dependencies. "
|
|
261
|
+
f"Install with: pip install flixopt[viz], flixopt[full] or pip install dash dash_cytoscape networkx werkzeug. "
|
|
262
|
+
f"Original error: {VISUALIZATION_ERROR}"
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
if not self._connected:
|
|
266
|
+
self._connect_network()
|
|
267
|
+
|
|
268
|
+
if self._network_app is not None:
|
|
269
|
+
logger.warning('The network app is already running. Restarting it.')
|
|
270
|
+
self.stop_network_app()
|
|
271
|
+
|
|
272
|
+
self._network_app = shownetwork(flow_graph(self))
|
|
273
|
+
|
|
274
|
+
def stop_network_app(self):
|
|
275
|
+
"""Stop the network visualization server."""
|
|
276
|
+
from .network_app import DASH_CYTOSCAPE_AVAILABLE, VISUALIZATION_ERROR
|
|
277
|
+
if not DASH_CYTOSCAPE_AVAILABLE:
|
|
278
|
+
raise ImportError(
|
|
279
|
+
f'Network visualization requires optional dependencies. '
|
|
280
|
+
f'Install with: pip install flixopt[viz]. '
|
|
281
|
+
f'Original error: {VISUALIZATION_ERROR}'
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
if self._network_app is None:
|
|
285
|
+
logger.warning('No network app is currently running. Cant stop it')
|
|
286
|
+
return
|
|
287
|
+
|
|
288
|
+
try:
|
|
289
|
+
logger.info('Stopping network visualization server...')
|
|
290
|
+
self._network_app.server_instance.shutdown()
|
|
291
|
+
logger.info('Network visualization stopped.')
|
|
292
|
+
except Exception as e:
|
|
293
|
+
logger.error(f'Failed to stop the network visualization app: {e}')
|
|
294
|
+
finally:
|
|
295
|
+
self._network_app = None
|
|
296
|
+
|
|
244
297
|
def network_infos(self) -> Tuple[Dict[str, Dict[str, str]], Dict[str, Dict[str, str]]]:
|
|
245
298
|
if not self._connected:
|
|
246
299
|
self._connect_network()
|