flixopt 2.1.0__tar.gz → 2.1.2__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.

Files changed (99) hide show
  1. {flixopt-2.1.0 → flixopt-2.1.2}/.github/workflows/deploy-docs.yaml +5 -1
  2. {flixopt-2.1.0 → flixopt-2.1.2}/.github/workflows/python-app.yaml +43 -6
  3. flixopt-2.1.2/CHANGELOG.md +82 -0
  4. {flixopt-2.1.0 → flixopt-2.1.2}/PKG-INFO +29 -29
  5. {flixopt-2.1.0 → flixopt-2.1.2}/docs/SUMMARY.md +1 -1
  6. {flixopt-2.1.0 → flixopt-2.1.2}/examples/02_Complex/complex_example_results.py +5 -0
  7. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/components.py +5 -2
  8. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/elements.py +4 -3
  9. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/results.py +1 -1
  10. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt.egg-info/PKG-INFO +29 -29
  11. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt.egg-info/SOURCES.txt +2 -6
  12. flixopt-2.1.2/flixopt.egg-info/requires.txt +39 -0
  13. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt.egg-info/top_level.txt +0 -1
  14. {flixopt-2.1.0 → flixopt-2.1.2}/mkdocs.yml +3 -2
  15. {flixopt-2.1.0 → flixopt-2.1.2}/pyproject.toml +40 -31
  16. flixopt-2.1.2/scripts/extract_release_notes.py +45 -0
  17. {flixopt-2.1.0 → flixopt-2.1.2}/tests/conftest.py +1 -1
  18. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_flow.py +137 -2
  19. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_storage.py +2 -2
  20. flixopt-2.1.0/docs/release-notes/_template.txt +0 -32
  21. flixopt-2.1.0/docs/release-notes/index.md +0 -7
  22. flixopt-2.1.0/docs/release-notes/v2.0.0.md +0 -93
  23. flixopt-2.1.0/docs/release-notes/v2.0.1.md +0 -12
  24. flixopt-2.1.0/docs/release-notes/v2.1.0.md +0 -31
  25. flixopt-2.1.0/flixopt.egg-info/requires.txt +0 -37
  26. flixopt-2.1.0/site/release-notes/_template.txt +0 -32
  27. {flixopt-2.1.0 → flixopt-2.1.2}/.gitignore +0 -0
  28. {flixopt-2.1.0 → flixopt-2.1.2}/LICENSE +0 -0
  29. {flixopt-2.1.0 → flixopt-2.1.2}/README.md +0 -0
  30. {flixopt-2.1.0 → flixopt-2.1.2}/docs/contribute.md +0 -0
  31. {flixopt-2.1.0 → flixopt-2.1.2}/docs/examples/00-Minimal Example.md +0 -0
  32. {flixopt-2.1.0 → flixopt-2.1.2}/docs/examples/01-Basic Example.md +0 -0
  33. {flixopt-2.1.0 → flixopt-2.1.2}/docs/examples/02-Complex Example.md +0 -0
  34. {flixopt-2.1.0 → flixopt-2.1.2}/docs/examples/03-Calculation Modes.md +0 -0
  35. {flixopt-2.1.0 → flixopt-2.1.2}/docs/examples/index.md +0 -0
  36. {flixopt-2.1.0 → flixopt-2.1.2}/docs/faq/contribute.md +0 -0
  37. {flixopt-2.1.0 → flixopt-2.1.2}/docs/faq/index.md +0 -0
  38. {flixopt-2.1.0 → flixopt-2.1.2}/docs/getting-started.md +0 -0
  39. {flixopt-2.1.0 → flixopt-2.1.2}/docs/images/architecture_flixOpt-pre2.0.0.png +0 -0
  40. {flixopt-2.1.0 → flixopt-2.1.2}/docs/images/architecture_flixOpt.png +0 -0
  41. {flixopt-2.1.0 → flixopt-2.1.2}/docs/images/flixopt-icon.svg +0 -0
  42. {flixopt-2.1.0 → flixopt-2.1.2}/docs/index.md +0 -0
  43. {flixopt-2.1.0 → flixopt-2.1.2}/docs/javascripts/mathjax.js +0 -0
  44. {flixopt-2.1.0 → flixopt-2.1.2}/docs/user-guide/Mathematical Notation/Bus.md +0 -0
  45. {flixopt-2.1.0 → flixopt-2.1.2}/docs/user-guide/Mathematical Notation/Effects, Penalty & Objective.md +0 -0
  46. {flixopt-2.1.0 → flixopt-2.1.2}/docs/user-guide/Mathematical Notation/Flow.md +0 -0
  47. {flixopt-2.1.0 → flixopt-2.1.2}/docs/user-guide/Mathematical Notation/LinearConverter.md +0 -0
  48. {flixopt-2.1.0 → flixopt-2.1.2}/docs/user-guide/Mathematical Notation/Piecewise.md +0 -0
  49. {flixopt-2.1.0 → flixopt-2.1.2}/docs/user-guide/Mathematical Notation/Storage.md +0 -0
  50. {flixopt-2.1.0 → flixopt-2.1.2}/docs/user-guide/Mathematical Notation/index.md +0 -0
  51. {flixopt-2.1.0 → flixopt-2.1.2}/docs/user-guide/Mathematical Notation/others.md +0 -0
  52. {flixopt-2.1.0 → flixopt-2.1.2}/docs/user-guide/index.md +0 -0
  53. {flixopt-2.1.0 → flixopt-2.1.2}/examples/00_Minmal/minimal_example.py +0 -0
  54. {flixopt-2.1.0 → flixopt-2.1.2}/examples/01_Simple/simple_example.py +0 -0
  55. {flixopt-2.1.0 → flixopt-2.1.2}/examples/02_Complex/complex_example.py +0 -0
  56. {flixopt-2.1.0 → flixopt-2.1.2}/examples/03_Calculation_types/Zeitreihen2020.csv +0 -0
  57. {flixopt-2.1.0 → flixopt-2.1.2}/examples/03_Calculation_types/example_calculation_types.py +0 -0
  58. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/__init__.py +0 -0
  59. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/aggregation.py +0 -0
  60. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/calculation.py +0 -0
  61. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/commons.py +0 -0
  62. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/config.py +0 -0
  63. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/config.yaml +0 -0
  64. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/core.py +0 -0
  65. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/effects.py +0 -0
  66. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/features.py +0 -0
  67. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/flow_system.py +0 -0
  68. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/interface.py +0 -0
  69. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/io.py +0 -0
  70. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/linear_converters.py +0 -0
  71. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/plotting.py +0 -0
  72. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/solvers.py +0 -0
  73. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/structure.py +0 -0
  74. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt/utils.py +0 -0
  75. {flixopt-2.1.0 → flixopt-2.1.2}/flixopt.egg-info/dependency_links.txt +0 -0
  76. {flixopt-2.1.0 → flixopt-2.1.2}/pics/architecture_flixOpt-pre2.0.0.png +0 -0
  77. {flixopt-2.1.0 → flixopt-2.1.2}/pics/architecture_flixOpt.png +0 -0
  78. {flixopt-2.1.0 → flixopt-2.1.2}/pics/flixOpt_plotting.jpg +0 -0
  79. {flixopt-2.1.0 → flixopt-2.1.2}/pics/flixopt-icon.svg +0 -0
  80. {flixopt-2.1.0 → flixopt-2.1.2}/pics/pics.pptx +0 -0
  81. {flixopt-2.1.0 → flixopt-2.1.2}/scripts/gen_ref_pages.py +0 -0
  82. {flixopt-2.1.0 → flixopt-2.1.2}/setup.cfg +0 -0
  83. {flixopt-2.1.0 → flixopt-2.1.2}/tests/__init__.py +0 -0
  84. {flixopt-2.1.0 → flixopt-2.1.2}/tests/ressources/Zeitreihen2020.csv +0 -0
  85. {flixopt-2.1.0 → flixopt-2.1.2}/tests/run_all_tests.py +0 -0
  86. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_bus.py +0 -0
  87. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_component.py +0 -0
  88. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_dataconverter.py +0 -0
  89. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_effect.py +0 -0
  90. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_examples.py +0 -0
  91. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_functional.py +0 -0
  92. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_integration.py +0 -0
  93. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_io.py +0 -0
  94. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_linear_converter.py +0 -0
  95. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_on_hours_computation.py +0 -0
  96. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_plots.py +0 -0
  97. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_results_plots.py +0 -0
  98. {flixopt-2.1.0 → flixopt-2.1.2}/tests/test_timeseries.py +0 -0
  99. {flixopt-2.1.0 → flixopt-2.1.2}/tests/todos.txt +0 -0
@@ -8,6 +8,8 @@ on:
8
8
  jobs:
9
9
  deploy-docs:
10
10
  runs-on: ubuntu-latest
11
+ # Only deploy docs for stable releases (not pre-releases)
12
+ if: github.event.release.prerelease == false
11
13
  steps:
12
14
  - uses: actions/checkout@v4
13
15
  with:
@@ -30,4 +32,6 @@ jobs:
30
32
  - name: Deploy docs
31
33
  run: |
32
34
  VERSION=${GITHUB_REF#refs/tags/v}
33
- mike deploy --push --update-aliases $VERSION latest
35
+ echo "Deploying docs for stable release: $VERSION"
36
+ mike deploy --push --update-aliases $VERSION latest
37
+ mike set-default --push latest
@@ -56,12 +56,49 @@ jobs:
56
56
  - name: Run tests
57
57
  run: pytest -v -p no:warnings
58
58
 
59
+ create-release:
60
+ name: Create Release with Changelog
61
+ runs-on: ubuntu-22.04
62
+ needs: [test]
63
+ if: startsWith(github.ref, 'refs/tags/v')
64
+
65
+ steps:
66
+ - name: Checkout repository
67
+ uses: actions/checkout@v4
68
+ with:
69
+ fetch-depth: 0
70
+
71
+ - name: Set up Python
72
+ uses: actions/setup-python@v4
73
+ with:
74
+ python-version: "3.11"
75
+
76
+ - name: Sync changelog to docs
77
+ run: |
78
+ cp CHANGELOG.md docs/changelog.md
79
+ echo "✅ Synced changelog to docs"
80
+
81
+ - name: Extract release notes
82
+ run: |
83
+ VERSION=${GITHUB_REF#refs/tags/v}
84
+ echo "Extracting release notes for version: $VERSION"
85
+ python scripts/extract_release_notes.py $VERSION > current_release_notes.md
86
+
87
+ - name: Create GitHub Release
88
+ uses: softprops/action-gh-release@v1
89
+ with:
90
+ body_path: current_release_notes.md
91
+ draft: false
92
+ prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
93
+ env:
94
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
95
+
59
96
  publish-testpypi:
60
97
  name: Publish to TestPyPI
61
98
  runs-on: ubuntu-22.04
62
- needs: [test] # Only run after tests pass
63
- if: github.event_name == 'release' && github.event.action == 'created' # Only on release creation
64
-
99
+ needs: [test, create-release] # Run after tests and release creation
100
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') # Only on tag push
101
+
65
102
  steps:
66
103
  - name: Checkout repository
67
104
  uses: actions/checkout@v4
@@ -86,7 +123,7 @@ jobs:
86
123
  env:
87
124
  TWINE_USERNAME: __token__
88
125
  TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
89
-
126
+
90
127
  - name: Test install from TestPyPI
91
128
  run: |
92
129
  # Create a temporary environment to test installation
@@ -104,8 +141,8 @@ jobs:
104
141
  publish-pypi:
105
142
  name: Publish to PyPI
106
143
  runs-on: ubuntu-22.04
107
- needs: [test] # Only run after TestPyPI publish succeeds
108
- if: github.event_name == 'release' && github.event.action == 'created' # Only on release creation
144
+ needs: [publish-testpypi] # Only run after TestPyPI publish succeeds
145
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') # Only on tag push
109
146
 
110
147
  steps:
111
148
  - name: Checkout repository
@@ -0,0 +1,82 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [2.1.2] - 2025-06-14
11
+
12
+ ### Fixed
13
+ - Storage losses per hour where not calculated correctly, as mentioned by @brokenwings01. This might have lead to issues with modeling large losses and long timesteps.
14
+ - Old implementation: $c(\text{t}_{i}) \cdot (1-\dot{\text{c}}_\text{rel,loss}(\text{t}_i)) \cdot \Delta \text{t}_{i}$
15
+ - Correct implementation: $c(\text{t}_{i}) \cdot (1-\dot{\text{c}}_\text{rel,loss}(\text{t}_i)) ^{\Delta \text{t}_{i}}$
16
+
17
+ ### Known issues
18
+ - Just to mention: Plotly >= 6 may raise errors if "nbformat" is not installed. We pinned plotly to <6, but this may be fixed in the future.
19
+
20
+ ## [2.1.1] - 2025-05-08
21
+
22
+ ### Fixed
23
+ - Fixed bug in the `_ElementResults.constraints` not returning the constraints but rather the variables
24
+
25
+ ### Changed
26
+ - Improved docstring and tests
27
+
28
+ ## [2.1.0] - 2025-04-11
29
+
30
+ ### Added
31
+ - Python 3.13 support added
32
+ - Logger warning if relative_minimum is used without on_off_parameters in Flow
33
+ - Greatly improved internal testing infrastructure by leveraging linopy's testing framework
34
+
35
+ ### Fixed
36
+ - Fixed the lower bound of `flow_rate` when using optional investments without OnOffParameters
37
+ - Fixed bug that prevented divest effects from working
38
+ - Added lower bounds of 0 to two unbounded vars (numerical improvement)
39
+
40
+ ### Changed
41
+ - **BREAKING**: Restructured the modeling of the On/Off state of Flows or Components
42
+ - Variable renaming: `...|consecutive_on_hours` → `...|ConsecutiveOn|hours`
43
+ - Variable renaming: `...|consecutive_off_hours` → `...|ConsecutiveOff|hours`
44
+ - Constraint renaming: `...|consecutive_on_hours_con1` → `...|ConsecutiveOn|con1`
45
+ - Similar pattern for all consecutive on/off constraints
46
+
47
+ ## [2.0.1] - 2025-04-10
48
+
49
+ ### Added
50
+ - Logger warning if relative_minimum is used without on_off_parameters in Flow
51
+
52
+ ### Fixed
53
+ - Replace "|" with "__" in filenames when saving figures (Windows compatibility)
54
+ - Fixed bug that prevented the load factor from working without InvestmentParameters
55
+
56
+ ## [2.0.0] - 2025-03-29
57
+
58
+ ### Changed
59
+ - **BREAKING**: Complete migration from Pyomo to Linopy optimization framework
60
+ - **BREAKING**: Redesigned data handling to rely on xarray.Dataset throughout the package
61
+ - **BREAKING**: Framework renamed from flixOpt to flixopt (`import flixopt as fx`)
62
+ - **BREAKING**: Results handling completely redesigned with new `CalculationResults` class
63
+
64
+ ### Added
65
+ - Full model serialization support - save and restore unsolved Models
66
+ - Enhanced model documentation with YAML export containing human-readable mathematical formulations
67
+ - Extend flixopt models with native linopy language support
68
+ - Full Model Export/Import capabilities via linopy.Model
69
+ - Unified solution exploration through `Calculation.results` attribute
70
+ - Compression support for result files
71
+ - `to_netcdf/from_netcdf` methods for FlowSystem and core components
72
+ - xarray integration for TimeSeries with improved datatypes support
73
+ - Google Style Docstrings throughout the codebase
74
+
75
+ ### Fixed
76
+ - Improved infeasible model detection and reporting
77
+ - Enhanced time series management and serialization
78
+ - Reduced file size through improved compression
79
+
80
+ ### Removed
81
+ - **BREAKING**: Pyomo dependency (replaced by linopy)
82
+ - Period concepts in time management (simplified to timesteps)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flixopt
3
- Version: 2.1.0
3
+ Version: 2.1.2
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>
@@ -22,40 +22,40 @@ Classifier: License :: OSI Approved :: MIT License
22
22
  Requires-Python: >=3.10
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
- Requires-Dist: numpy>=1.21.5
26
- Requires-Dist: PyYAML>=6.0
27
- Requires-Dist: linopy>=0.5.1
28
- Requires-Dist: netcdf4>=1.6.1
29
- Requires-Dist: rich>=13.0.1
25
+ Requires-Dist: numpy<3,>=1.21.5
26
+ Requires-Dist: pandas<3,>=2.0.0
27
+ Requires-Dist: linopy<0.6.0,>=0.5.1
28
+ Requires-Dist: netcdf4<2,>=1.6.1
29
+ Requires-Dist: PyYAML<7,>=6.0.0
30
+ Requires-Dist: rich>=13.0.0
31
+ Requires-Dist: tomli>=2.0.1; python_version < "3.11"
30
32
  Requires-Dist: highspy>=1.5.3
31
- Requires-Dist: pandas<3,>=2
32
- Requires-Dist: matplotlib>=3.5.2
33
- Requires-Dist: plotly>=5.15
34
- Requires-Dist: tomli>=2.0.1
33
+ Requires-Dist: matplotlib<4.0.0,>=3.5.2
34
+ Requires-Dist: plotly<6.0.0,>=5.15.0
35
35
  Provides-Extra: dev
36
- Requires-Dist: pytest; extra == "dev"
37
- Requires-Dist: ruff; extra == "dev"
36
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
37
+ Requires-Dist: ruff>=0.9.0; extra == "dev"
38
38
  Requires-Dist: pyvis==0.3.1; extra == "dev"
39
- Requires-Dist: tsam>=2.3.1; extra == "dev"
40
- Requires-Dist: scipy>=1.15.1; extra == "dev"
41
- Requires-Dist: gurobipy>=10.0; extra == "dev"
39
+ Requires-Dist: tsam<3.0.0,>=2.3.1; extra == "dev"
40
+ Requires-Dist: scipy<2.0.0,>=1.15.1; extra == "dev"
41
+ Requires-Dist: gurobipy>=10.0.0; extra == "dev"
42
42
  Provides-Extra: full
43
43
  Requires-Dist: pyvis==0.3.1; extra == "full"
44
- Requires-Dist: tsam>=2.3.1; extra == "full"
45
- Requires-Dist: scipy>=1.15.1; extra == "full"
46
- Requires-Dist: streamlit>=1.44.0; extra == "full"
47
- Requires-Dist: gurobipy>=10.0; extra == "full"
44
+ Requires-Dist: tsam<3.0.0,>=2.3.1; extra == "full"
45
+ Requires-Dist: scipy<2.0.0,>=1.15.1; extra == "full"
46
+ Requires-Dist: streamlit<2.0.0,>=1.44.0; extra == "full"
47
+ Requires-Dist: gurobipy>=10.0.0; extra == "full"
48
48
  Provides-Extra: docs
49
- Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
50
- Requires-Dist: mkdocstrings-python; extra == "docs"
51
- Requires-Dist: mkdocs-table-reader-plugin; extra == "docs"
52
- Requires-Dist: mkdocs-gen-files; extra == "docs"
53
- Requires-Dist: mkdocs-include-markdown-plugin; extra == "docs"
54
- Requires-Dist: mkdocs-literate-nav; extra == "docs"
55
- Requires-Dist: markdown-include; extra == "docs"
56
- Requires-Dist: pymdown-extensions; extra == "docs"
57
- Requires-Dist: pygments; extra == "docs"
58
- Requires-Dist: mike; extra == "docs"
49
+ Requires-Dist: mkdocs-material<10,>=9.0.0; extra == "docs"
50
+ Requires-Dist: mkdocstrings-python>=1.0.0; extra == "docs"
51
+ Requires-Dist: mkdocs-table-reader-plugin>=2.0.0; extra == "docs"
52
+ Requires-Dist: mkdocs-gen-files>=0.4.0; extra == "docs"
53
+ Requires-Dist: mkdocs-include-markdown-plugin>=6.0.0; extra == "docs"
54
+ Requires-Dist: mkdocs-literate-nav>=0.6.0; extra == "docs"
55
+ Requires-Dist: markdown-include>=0.8.0; extra == "docs"
56
+ Requires-Dist: pymdown-extensions>=10.0.0; extra == "docs"
57
+ Requires-Dist: pygments>=2.14.0; extra == "docs"
58
+ Requires-Dist: mike<2,>=1.1.0; extra == "docs"
59
59
  Dynamic: license-file
60
60
 
61
61
  # FlixOpt: Energy and Material Flow Optimization Framework
@@ -4,4 +4,4 @@
4
4
  - [Examples](examples/)
5
5
  - [FAQ](faq/)
6
6
  - [API-Reference](api-reference/)
7
- - [Release Notes](release-notes/)
7
+ - [Release Notes](changelog.md)
@@ -31,3 +31,8 @@ if __name__ == '__main__':
31
31
  # --- Plotting internal variables manually ---
32
32
  results.plot_heatmap('BHKW2(Q_th)|on')
33
33
  results.plot_heatmap('Kessel(Q_th)|on')
34
+
35
+ # Dataframes from results:
36
+ fw_bus = results['Fernwärme'].node_balance().to_dataframe()
37
+ all = results.solution.to_dataframe()
38
+
@@ -43,7 +43,10 @@ class LinearConverter(Component):
43
43
  label: The label of the Element. Used to identify it in the FlowSystem
44
44
  inputs: The input Flows
45
45
  outputs: The output Flows
46
- on_off_parameters: Information about on and off states. See class OnOffParameters.
46
+ on_off_parameters: Information about on and off state of LinearConverter.
47
+ Component is On/Off, if all connected Flows are On/Off. This induces an On-Variable (binary) in all Flows!
48
+ If possible, use OnOffParameters in a single Flow instead to keep the number of binary variables low.
49
+ See class OnOffParameters.
47
50
  conversion_factors: linear relation between flows.
48
51
  Either 'conversion_factors' or 'piecewise_conversion' can be used!
49
52
  piecewise_conversion: Define a piecewise linear relation between flow rates of different flows.
@@ -488,7 +491,7 @@ class StorageModel(ComponentModel):
488
491
  self.add(
489
492
  self._model.add_constraints(
490
493
  charge_state.isel(time=slice(1, None))
491
- == charge_state.isel(time=slice(None, -1)) * (1 - rel_loss * hours_per_step)
494
+ == charge_state.isel(time=slice(None, -1)) * ((1 - rel_loss) ** hours_per_step)
492
495
  + charge_rate * eff_charge * hours_per_step
493
496
  - discharge_rate * eff_discharge * hours_per_step,
494
497
  name=f'{self.label_full}|charge_state',
@@ -47,8 +47,8 @@ class Component(Element):
47
47
  inputs: input flows.
48
48
  outputs: output flows.
49
49
  on_off_parameters: Information about on and off state of Component.
50
- Component is On/Off, if all connected Flows are On/Off.
51
- Induces On-Variable in all FLows!
50
+ Component is On/Off, if all connected Flows are On/Off. This induces an On-Variable (binary) in all Flows!
51
+ If possible, use OnOffParameters in a single Flow instead to keep the number of binary variables low.
52
52
  See class OnOffParameters.
53
53
  prevent_simultaneous_flows: Define a Group of Flows. Only one them can be on at a time.
54
54
  Induces On-Variable in all Flows! If possible, use OnOffParameters in a single Flow instead.
@@ -193,7 +193,8 @@ class Flow(Element):
193
193
  (relative_minimum and relative_maximum are ignored)
194
194
  used for fixed load or supply profiles, i.g. heat demand, wind-power, solarthermal
195
195
  If the load-profile is just an upper limit, use relative_maximum instead.
196
- previous_flow_rate: previous flow rate of the component.
196
+ previous_flow_rate: previous flow rate of the flow. Used to determine if and how long the
197
+ flow is already on / off. If None, the flow is considered to be off for one timestep.
197
198
  meta_data: used to store more information about the Element. Is not used internally, but saved in the results. Only use python native types.
198
199
  """
199
200
  super().__init__(label, meta_data=meta_data)
@@ -343,7 +343,7 @@ class _ElementResults:
343
343
  """
344
344
  if self._calculation_results.model is None:
345
345
  raise ValueError('The linopy model is not available.')
346
- return self._calculation_results.model.constraints[self._variable_names]
346
+ return self._calculation_results.model.constraints[self._constraint_names]
347
347
 
348
348
  def filter_solution(self, variable_dims: Optional[Literal['scalar', 'time']] = None) -> xr.Dataset:
349
349
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flixopt
3
- Version: 2.1.0
3
+ Version: 2.1.2
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>
@@ -22,40 +22,40 @@ Classifier: License :: OSI Approved :: MIT License
22
22
  Requires-Python: >=3.10
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
- Requires-Dist: numpy>=1.21.5
26
- Requires-Dist: PyYAML>=6.0
27
- Requires-Dist: linopy>=0.5.1
28
- Requires-Dist: netcdf4>=1.6.1
29
- Requires-Dist: rich>=13.0.1
25
+ Requires-Dist: numpy<3,>=1.21.5
26
+ Requires-Dist: pandas<3,>=2.0.0
27
+ Requires-Dist: linopy<0.6.0,>=0.5.1
28
+ Requires-Dist: netcdf4<2,>=1.6.1
29
+ Requires-Dist: PyYAML<7,>=6.0.0
30
+ Requires-Dist: rich>=13.0.0
31
+ Requires-Dist: tomli>=2.0.1; python_version < "3.11"
30
32
  Requires-Dist: highspy>=1.5.3
31
- Requires-Dist: pandas<3,>=2
32
- Requires-Dist: matplotlib>=3.5.2
33
- Requires-Dist: plotly>=5.15
34
- Requires-Dist: tomli>=2.0.1
33
+ Requires-Dist: matplotlib<4.0.0,>=3.5.2
34
+ Requires-Dist: plotly<6.0.0,>=5.15.0
35
35
  Provides-Extra: dev
36
- Requires-Dist: pytest; extra == "dev"
37
- Requires-Dist: ruff; extra == "dev"
36
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
37
+ Requires-Dist: ruff>=0.9.0; extra == "dev"
38
38
  Requires-Dist: pyvis==0.3.1; extra == "dev"
39
- Requires-Dist: tsam>=2.3.1; extra == "dev"
40
- Requires-Dist: scipy>=1.15.1; extra == "dev"
41
- Requires-Dist: gurobipy>=10.0; extra == "dev"
39
+ Requires-Dist: tsam<3.0.0,>=2.3.1; extra == "dev"
40
+ Requires-Dist: scipy<2.0.0,>=1.15.1; extra == "dev"
41
+ Requires-Dist: gurobipy>=10.0.0; extra == "dev"
42
42
  Provides-Extra: full
43
43
  Requires-Dist: pyvis==0.3.1; extra == "full"
44
- Requires-Dist: tsam>=2.3.1; extra == "full"
45
- Requires-Dist: scipy>=1.15.1; extra == "full"
46
- Requires-Dist: streamlit>=1.44.0; extra == "full"
47
- Requires-Dist: gurobipy>=10.0; extra == "full"
44
+ Requires-Dist: tsam<3.0.0,>=2.3.1; extra == "full"
45
+ Requires-Dist: scipy<2.0.0,>=1.15.1; extra == "full"
46
+ Requires-Dist: streamlit<2.0.0,>=1.44.0; extra == "full"
47
+ Requires-Dist: gurobipy>=10.0.0; extra == "full"
48
48
  Provides-Extra: docs
49
- Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
50
- Requires-Dist: mkdocstrings-python; extra == "docs"
51
- Requires-Dist: mkdocs-table-reader-plugin; extra == "docs"
52
- Requires-Dist: mkdocs-gen-files; extra == "docs"
53
- Requires-Dist: mkdocs-include-markdown-plugin; extra == "docs"
54
- Requires-Dist: mkdocs-literate-nav; extra == "docs"
55
- Requires-Dist: markdown-include; extra == "docs"
56
- Requires-Dist: pymdown-extensions; extra == "docs"
57
- Requires-Dist: pygments; extra == "docs"
58
- Requires-Dist: mike; extra == "docs"
49
+ Requires-Dist: mkdocs-material<10,>=9.0.0; extra == "docs"
50
+ Requires-Dist: mkdocstrings-python>=1.0.0; extra == "docs"
51
+ Requires-Dist: mkdocs-table-reader-plugin>=2.0.0; extra == "docs"
52
+ Requires-Dist: mkdocs-gen-files>=0.4.0; extra == "docs"
53
+ Requires-Dist: mkdocs-include-markdown-plugin>=6.0.0; extra == "docs"
54
+ Requires-Dist: mkdocs-literate-nav>=0.6.0; extra == "docs"
55
+ Requires-Dist: markdown-include>=0.8.0; extra == "docs"
56
+ Requires-Dist: pymdown-extensions>=10.0.0; extra == "docs"
57
+ Requires-Dist: pygments>=2.14.0; extra == "docs"
58
+ Requires-Dist: mike<2,>=1.1.0; extra == "docs"
59
59
  Dynamic: license-file
60
60
 
61
61
  # FlixOpt: Energy and Material Flow Optimization Framework
@@ -1,4 +1,5 @@
1
1
  .gitignore
2
+ CHANGELOG.md
2
3
  LICENSE
3
4
  README.md
4
5
  mkdocs.yml
@@ -20,11 +21,6 @@ docs/images/architecture_flixOpt-pre2.0.0.png
20
21
  docs/images/architecture_flixOpt.png
21
22
  docs/images/flixopt-icon.svg
22
23
  docs/javascripts/mathjax.js
23
- docs/release-notes/_template.txt
24
- docs/release-notes/index.md
25
- docs/release-notes/v2.0.0.md
26
- docs/release-notes/v2.0.1.md
27
- docs/release-notes/v2.1.0.md
28
24
  docs/user-guide/index.md
29
25
  docs/user-guide/Mathematical Notation/Bus.md
30
26
  docs/user-guide/Mathematical Notation/Effects, Penalty & Objective.md
@@ -70,8 +66,8 @@ pics/architecture_flixOpt.png
70
66
  pics/flixOpt_plotting.jpg
71
67
  pics/flixopt-icon.svg
72
68
  pics/pics.pptx
69
+ scripts/extract_release_notes.py
73
70
  scripts/gen_ref_pages.py
74
- site/release-notes/_template.txt
75
71
  tests/__init__.py
76
72
  tests/conftest.py
77
73
  tests/run_all_tests.py
@@ -0,0 +1,39 @@
1
+ numpy<3,>=1.21.5
2
+ pandas<3,>=2.0.0
3
+ linopy<0.6.0,>=0.5.1
4
+ netcdf4<2,>=1.6.1
5
+ PyYAML<7,>=6.0.0
6
+ rich>=13.0.0
7
+ highspy>=1.5.3
8
+ matplotlib<4.0.0,>=3.5.2
9
+ plotly<6.0.0,>=5.15.0
10
+
11
+ [:python_version < "3.11"]
12
+ tomli>=2.0.1
13
+
14
+ [dev]
15
+ pytest>=7.0.0
16
+ ruff>=0.9.0
17
+ pyvis==0.3.1
18
+ tsam<3.0.0,>=2.3.1
19
+ scipy<2.0.0,>=1.15.1
20
+ gurobipy>=10.0.0
21
+
22
+ [docs]
23
+ mkdocs-material<10,>=9.0.0
24
+ mkdocstrings-python>=1.0.0
25
+ mkdocs-table-reader-plugin>=2.0.0
26
+ mkdocs-gen-files>=0.4.0
27
+ mkdocs-include-markdown-plugin>=6.0.0
28
+ mkdocs-literate-nav>=0.6.0
29
+ markdown-include>=0.8.0
30
+ pymdown-extensions>=10.0.0
31
+ pygments>=2.14.0
32
+ mike<2,>=1.1.0
33
+
34
+ [full]
35
+ pyvis==0.3.1
36
+ tsam<3.0.0,>=2.3.1
37
+ scipy<2.0.0,>=1.15.1
38
+ streamlit<2.0.0,>=1.44.0
39
+ gurobipy>=10.0.0
@@ -3,5 +3,4 @@ docs
3
3
  flixopt
4
4
  pics
5
5
  scripts
6
- site
7
6
  tests
@@ -79,12 +79,13 @@ markdown_extensions:
79
79
  - pymdownx.snippets:
80
80
  base_path: ..
81
81
 
82
-
83
82
  plugins:
84
83
  - search # Enables the search functionality in the documentation
85
84
  - table-reader # Allows including tables from external files
86
85
  - include-markdown
87
- - mike
86
+ - mike:
87
+ version_selector: true
88
+ default_version: latest
88
89
  - gen-files:
89
90
  scripts:
90
91
  - scripts/gen_ref_pages.py
@@ -33,47 +33,56 @@ classifiers = [
33
33
  "License :: OSI Approved :: MIT License",
34
34
  ]
35
35
  dependencies = [
36
- "numpy >= 1.21.5",
37
- "PyYAML >= 6.0",
38
- "linopy >= 0.5.1",
39
- "netcdf4 >= 1.6.1",
40
- "rich >= 13.0.1",
41
- "highspy >= 1.5.3", # Default solver
42
- "pandas >= 2, < 3", # Used in post-processing
43
- "matplotlib >= 3.5.2", # Used in post-processing
44
- "plotly >= 5.15", # Used in post-processing
45
- "tomli >= 2.0.1" # TOML parser (only needed until python 3.11)
36
+ # Core scientific computing
37
+ "numpy >= 1.21.5, < 3",
38
+ "pandas >= 2.0.0, < 3",
39
+
40
+ # Optimization and data handling
41
+ "linopy >= 0.5.1, < 0.6.0",
42
+ "netcdf4 >= 1.6.1, < 2",
43
+
44
+ # Utilities
45
+ "PyYAML >= 6.0.0, < 7",
46
+ "rich >= 13.0.0",
47
+ "tomli >= 2.0.1; python_version < '3.11'", #Only needed with python 3.10 or earlier
48
+
49
+ # Default solver
50
+ "highspy >= 1.5.3",
51
+
52
+ # Visualization
53
+ "matplotlib >= 3.5.2, < 4.0.0",
54
+ "plotly >= 5.15.0, < 6.0.0",
46
55
  ]
47
56
 
48
57
  [project.optional-dependencies]
49
58
  dev = [
50
- "pytest",
51
- "ruff",
52
- "pyvis == 0.3.1", # Used for visualizing the FLowSystem
53
- "tsam >= 2.3.1", # Used for time series aggregation
54
- "scipy >= 1.15.1", # Used by tsam. Prior versions have conflict with highspy. See https://github.com/scipy/scipy/issues/22257
55
- "gurobipy >= 10.0",
59
+ "pytest >= 7.0.0",
60
+ "ruff >= 0.9.0",
61
+ "pyvis == 0.3.1", # Visualizing FlowSystem
62
+ "tsam >= 2.3.1, < 3.0.0", # Time series aggregation
63
+ "scipy >= 1.15.1, < 2.0.0", # Used by tsam. Prior versions have conflict with highspy. See https://github.com/scipy/scipy/issues/22257
64
+ "gurobipy >= 10.0.0",
56
65
  ]
57
66
 
58
67
  full = [
59
- "pyvis == 0.3.1", # Used for visualizing the FLowSystem
60
- "tsam >= 2.3.1", # Used for time series aggregation
61
- "scipy >= 1.15.1", # Used by tsam. Prior versions have conflict with highspy. See https://github.com/scipy/scipy/issues/22257
62
- "streamlit >= 1.44.0",
63
- "gurobipy >= 10.0",
68
+ "pyvis == 0.3.1", # Visualizing FlowSystem Network
69
+ "tsam >= 2.3.1, < 3.0.0", # Time series aggregation
70
+ "scipy >= 1.15.1, < 2.0.0", # Used by tsam. Prior versions have conflict with highspy. See https://github.com/scipy/scipy/issues/22257
71
+ "streamlit >= 1.44.0, < 2.0.0",
72
+ "gurobipy >= 10.0.0",
64
73
  ]
65
74
 
66
75
  docs = [
67
- "mkdocs-material>=9.0.0",
68
- "mkdocstrings-python",
69
- "mkdocs-table-reader-plugin",
70
- "mkdocs-gen-files",
71
- "mkdocs-include-markdown-plugin",
72
- "mkdocs-literate-nav",
73
- "markdown-include",
74
- "pymdown-extensions",
75
- "pygments",
76
- "mike",
76
+ "mkdocs-material >= 9.0.0, < 10",
77
+ "mkdocstrings-python >= 1.0.0",
78
+ "mkdocs-table-reader-plugin >= 2.0.0",
79
+ "mkdocs-gen-files >= 0.4.0",
80
+ "mkdocs-include-markdown-plugin >= 6.0.0",
81
+ "mkdocs-literate-nav >= 0.6.0",
82
+ "markdown-include >= 0.8.0",
83
+ "pymdown-extensions >= 10.0.0",
84
+ "pygments >= 2.14.0",
85
+ "mike >= 1.1.0, < 2",
77
86
  ]
78
87
 
79
88
  [project.urls]
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Extract release notes from CHANGELOG.md for a specific version.
4
+ Usage: python extract_release_notes.py <version>
5
+ """
6
+
7
+ import re
8
+ import sys
9
+ from pathlib import Path
10
+
11
+
12
+ def extract_release_notes(version: str) -> str:
13
+ """Extract release notes for a specific version from CHANGELOG.md"""
14
+ changelog_path = Path("CHANGELOG.md")
15
+
16
+ if not changelog_path.exists():
17
+ print("❌ Error: CHANGELOG.md not found", file=sys.stderr)
18
+ sys.exit(1)
19
+
20
+ content = changelog_path.read_text(encoding='utf-8')
21
+
22
+ # Pattern to match version section: ## [2.1.2] - 2025-06-14
23
+ pattern = rf'## \[{re.escape(version)}\] - [^\n]+\n(.*?)(?=\n## \[|\n\[Unreleased\]|\Z)'
24
+ match = re.search(pattern, content, re.DOTALL)
25
+
26
+ if not match:
27
+ print(f"❌ Error: No release notes found for version '{version}'", file=sys.stderr)
28
+ sys.exit(1)
29
+
30
+ return match.group(1).strip()
31
+
32
+
33
+ def main():
34
+ if len(sys.argv) != 2:
35
+ print("Usage: python extract_release_notes.py <version>")
36
+ print("Example: python extract_release_notes.py 2.1.2")
37
+ sys.exit(1)
38
+
39
+ version = sys.argv[1]
40
+ release_notes = extract_release_notes(version)
41
+ print(release_notes)
42
+
43
+
44
+ if __name__ == "__main__":
45
+ main()
@@ -432,7 +432,7 @@ def timesteps_linopy(request):
432
432
  @pytest.fixture
433
433
  def basic_flow_system_linopy(timesteps_linopy) -> fx.FlowSystem:
434
434
  """Create basic elements for component testing"""
435
- flow_system = fx.FlowSystem(pd.date_range('2020-01-01', periods=10, freq='h', name='time'))
435
+ flow_system = fx.FlowSystem(timesteps_linopy)
436
436
  thermal_load = np.array([np.random.random() for _ in range(10)]) * 180
437
437
  p_el = (np.array([np.random.random() for _ in range(10)]) + 0.5) / 1.5 * 50
438
438