flixopt 2.1.8__tar.gz → 2.1.10__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 (105) hide show
  1. {flixopt-2.1.8 → flixopt-2.1.10}/.github/workflows/python-app.yaml +41 -7
  2. flixopt-2.1.10/CHANGELOG.md +286 -0
  3. {flixopt-2.1.8/flixopt.egg-info → flixopt-2.1.10}/PKG-INFO +2 -1
  4. {flixopt-2.1.8 → flixopt-2.1.10}/docs/SUMMARY.md +1 -1
  5. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/network_app.py +3 -5
  6. {flixopt-2.1.8 → flixopt-2.1.10/flixopt.egg-info}/PKG-INFO +2 -1
  7. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt.egg-info/SOURCES.txt +1 -0
  8. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt.egg-info/requires.txt +1 -0
  9. {flixopt-2.1.8 → flixopt-2.1.10}/pyproject.toml +8 -0
  10. {flixopt-2.1.8 → flixopt-2.1.10}/renovate.json +10 -2
  11. flixopt-2.1.10/scripts/extract_changelog.py +148 -0
  12. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_examples.py +1 -1
  13. flixopt-2.1.8/CHANGELOG.md +0 -181
  14. {flixopt-2.1.8 → flixopt-2.1.10}/.github/CONTRIBUTING.md +0 -0
  15. {flixopt-2.1.8 → flixopt-2.1.10}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  16. {flixopt-2.1.8 → flixopt-2.1.10}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  17. {flixopt-2.1.8 → flixopt-2.1.10}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  18. {flixopt-2.1.8 → flixopt-2.1.10}/.github/ISSUE_TEMPLATE/general_issue.yml +0 -0
  19. {flixopt-2.1.8 → flixopt-2.1.10}/.github/pull_request_template.md +0 -0
  20. {flixopt-2.1.8 → flixopt-2.1.10}/.gitignore +0 -0
  21. {flixopt-2.1.8 → flixopt-2.1.10}/.pre-commit-config.yaml +0 -0
  22. {flixopt-2.1.8 → flixopt-2.1.10}/LICENSE +0 -0
  23. {flixopt-2.1.8 → flixopt-2.1.10}/README.md +0 -0
  24. {flixopt-2.1.8 → flixopt-2.1.10}/docs/contribute.md +0 -0
  25. {flixopt-2.1.8 → flixopt-2.1.10}/docs/examples/00-Minimal Example.md +0 -0
  26. {flixopt-2.1.8 → flixopt-2.1.10}/docs/examples/01-Basic Example.md +0 -0
  27. {flixopt-2.1.8 → flixopt-2.1.10}/docs/examples/02-Complex Example.md +0 -0
  28. {flixopt-2.1.8 → flixopt-2.1.10}/docs/examples/03-Calculation Modes.md +0 -0
  29. {flixopt-2.1.8 → flixopt-2.1.10}/docs/examples/index.md +0 -0
  30. {flixopt-2.1.8 → flixopt-2.1.10}/docs/faq/contribute.md +0 -0
  31. {flixopt-2.1.8 → flixopt-2.1.10}/docs/faq/index.md +0 -0
  32. {flixopt-2.1.8 → flixopt-2.1.10}/docs/getting-started.md +0 -0
  33. {flixopt-2.1.8 → flixopt-2.1.10}/docs/images/architecture_flixOpt-pre2.0.0.png +0 -0
  34. {flixopt-2.1.8 → flixopt-2.1.10}/docs/images/architecture_flixOpt.png +0 -0
  35. {flixopt-2.1.8 → flixopt-2.1.10}/docs/images/flixopt-icon.svg +0 -0
  36. {flixopt-2.1.8 → flixopt-2.1.10}/docs/index.md +0 -0
  37. {flixopt-2.1.8 → flixopt-2.1.10}/docs/javascripts/mathjax.js +0 -0
  38. {flixopt-2.1.8 → flixopt-2.1.10}/docs/user-guide/Mathematical Notation/Bus.md +0 -0
  39. {flixopt-2.1.8 → flixopt-2.1.10}/docs/user-guide/Mathematical Notation/Effects, Penalty & Objective.md +0 -0
  40. {flixopt-2.1.8 → flixopt-2.1.10}/docs/user-guide/Mathematical Notation/Flow.md +0 -0
  41. {flixopt-2.1.8 → flixopt-2.1.10}/docs/user-guide/Mathematical Notation/InvestParameters.md +0 -0
  42. {flixopt-2.1.8 → flixopt-2.1.10}/docs/user-guide/Mathematical Notation/LinearConverter.md +0 -0
  43. {flixopt-2.1.8 → flixopt-2.1.10}/docs/user-guide/Mathematical Notation/OnOffParameters.md +0 -0
  44. {flixopt-2.1.8 → flixopt-2.1.10}/docs/user-guide/Mathematical Notation/Piecewise.md +0 -0
  45. {flixopt-2.1.8 → flixopt-2.1.10}/docs/user-guide/Mathematical Notation/Storage.md +0 -0
  46. {flixopt-2.1.8 → flixopt-2.1.10}/docs/user-guide/Mathematical Notation/index.md +0 -0
  47. {flixopt-2.1.8 → flixopt-2.1.10}/docs/user-guide/Mathematical Notation/others.md +0 -0
  48. {flixopt-2.1.8 → flixopt-2.1.10}/docs/user-guide/index.md +0 -0
  49. {flixopt-2.1.8 → flixopt-2.1.10}/examples/00_Minmal/minimal_example.py +0 -0
  50. {flixopt-2.1.8 → flixopt-2.1.10}/examples/01_Simple/simple_example.py +0 -0
  51. {flixopt-2.1.8 → flixopt-2.1.10}/examples/02_Complex/complex_example.py +0 -0
  52. {flixopt-2.1.8 → flixopt-2.1.10}/examples/02_Complex/complex_example_results.py +0 -0
  53. {flixopt-2.1.8 → flixopt-2.1.10}/examples/03_Calculation_types/Zeitreihen2020.csv +0 -0
  54. {flixopt-2.1.8 → flixopt-2.1.10}/examples/03_Calculation_types/example_calculation_types.py +0 -0
  55. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/__init__.py +0 -0
  56. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/aggregation.py +0 -0
  57. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/calculation.py +0 -0
  58. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/commons.py +0 -0
  59. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/components.py +0 -0
  60. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/config.py +0 -0
  61. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/config.yaml +0 -0
  62. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/core.py +0 -0
  63. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/effects.py +0 -0
  64. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/elements.py +0 -0
  65. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/features.py +0 -0
  66. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/flow_system.py +0 -0
  67. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/interface.py +0 -0
  68. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/io.py +0 -0
  69. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/linear_converters.py +0 -0
  70. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/plotting.py +0 -0
  71. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/results.py +0 -0
  72. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/solvers.py +0 -0
  73. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/structure.py +0 -0
  74. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt/utils.py +0 -0
  75. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt.egg-info/dependency_links.txt +0 -0
  76. {flixopt-2.1.8 → flixopt-2.1.10}/flixopt.egg-info/top_level.txt +0 -0
  77. {flixopt-2.1.8 → flixopt-2.1.10}/mkdocs.yml +0 -0
  78. {flixopt-2.1.8 → flixopt-2.1.10}/pics/architecture_flixOpt-pre2.0.0.png +0 -0
  79. {flixopt-2.1.8 → flixopt-2.1.10}/pics/architecture_flixOpt.png +0 -0
  80. {flixopt-2.1.8 → flixopt-2.1.10}/pics/flixOpt_plotting.jpg +0 -0
  81. {flixopt-2.1.8 → flixopt-2.1.10}/pics/flixopt-icon.svg +0 -0
  82. {flixopt-2.1.8 → flixopt-2.1.10}/pics/pics.pptx +0 -0
  83. {flixopt-2.1.8 → flixopt-2.1.10}/scripts/extract_release_notes.py +0 -0
  84. {flixopt-2.1.8 → flixopt-2.1.10}/scripts/gen_ref_pages.py +0 -0
  85. {flixopt-2.1.8 → flixopt-2.1.10}/setup.cfg +0 -0
  86. {flixopt-2.1.8 → flixopt-2.1.10}/tests/__init__.py +0 -0
  87. {flixopt-2.1.8 → flixopt-2.1.10}/tests/conftest.py +0 -0
  88. {flixopt-2.1.8 → flixopt-2.1.10}/tests/ressources/Zeitreihen2020.csv +0 -0
  89. {flixopt-2.1.8 → flixopt-2.1.10}/tests/run_all_tests.py +0 -0
  90. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_bus.py +0 -0
  91. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_component.py +0 -0
  92. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_dataconverter.py +0 -0
  93. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_effect.py +0 -0
  94. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_flow.py +0 -0
  95. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_functional.py +0 -0
  96. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_integration.py +0 -0
  97. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_io.py +0 -0
  98. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_linear_converter.py +0 -0
  99. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_network_app.py +0 -0
  100. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_on_hours_computation.py +0 -0
  101. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_plots.py +0 -0
  102. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_results_plots.py +0 -0
  103. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_storage.py +0 -0
  104. {flixopt-2.1.8 → flixopt-2.1.10}/tests/test_timeseries.py +0 -0
  105. {flixopt-2.1.8 → flixopt-2.1.10}/tests/todos.txt +0 -0
@@ -85,11 +85,40 @@ jobs:
85
85
 
86
86
  - name: Install dependencies
87
87
  run: |
88
- uv pip install --system .[dev] "pytest-xdist==3.*"
88
+ uv pip install --system .[dev]
89
89
 
90
90
  - name: Run tests
91
91
  run: pytest -v -p no:warnings --numprocesses=auto
92
92
 
93
+ test-examples:
94
+ runs-on: ubuntu-24.04
95
+ timeout-minutes: 45
96
+ needs: lint
97
+ # Only run examples on releases (tags)
98
+ if: startsWith(github.ref, 'refs/tags/v')
99
+
100
+ steps:
101
+ - name: Check out code
102
+ uses: actions/checkout@v5
103
+
104
+ - name: Set up uv
105
+ uses: astral-sh/setup-uv@v6
106
+ with:
107
+ version: "0.8.19"
108
+ enable-cache: true
109
+
110
+ - name: Set up Python ${{ env.PYTHON_VERSION }}
111
+ uses: actions/setup-python@v6
112
+ with:
113
+ python-version: ${{ env.PYTHON_VERSION }}
114
+
115
+ - name: Install dependencies
116
+ run: |
117
+ uv pip install --system .[dev]
118
+
119
+ - name: Run example tests
120
+ run: pytest -v -p no:warnings -m examples
121
+
93
122
  security:
94
123
  name: Security Scan
95
124
  runs-on: ubuntu-24.04
@@ -129,7 +158,7 @@ jobs:
129
158
  runs-on: ubuntu-24.04
130
159
  permissions:
131
160
  contents: write
132
- needs: [lint, test, security]
161
+ needs: [lint, test, test-examples, security]
133
162
  if: startsWith(github.ref, 'refs/tags/v')
134
163
 
135
164
  steps:
@@ -168,7 +197,7 @@ jobs:
168
197
  publish-testpypi:
169
198
  name: Publish to TestPyPI
170
199
  runs-on: ubuntu-24.04
171
- needs: [test, create-release] # Run after tests and release creation
200
+ needs: [test, test-examples, create-release] # Run after tests and release creation
172
201
  if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') # Only on tag push
173
202
  environment:
174
203
  name: testpypi
@@ -313,7 +342,7 @@ jobs:
313
342
 
314
343
  # Wait and retry while PyPI indexes the package
315
344
  INSTALL_SUCCESS=false
316
- for d in 10 20 40 80 120; do
345
+ for d in 10 20 40 80 120 240 480; do
317
346
  sleep "$d"
318
347
  echo "Attempting to install $PACKAGE_NAME==$VERSION from PyPI (retry after ${d}s)..."
319
348
 
@@ -363,10 +392,15 @@ jobs:
363
392
  with:
364
393
  python-version: ${{ env.PYTHON_VERSION }}
365
394
 
366
- - name: Sync changelog to docs
395
+ - name: Extract changelog to docs
367
396
  run: |
368
- cp CHANGELOG.md docs/changelog.md
369
- echo "✅ Synced changelog to docs"
397
+ # Install packaging dependency for changelog extraction
398
+ uv pip install --system packaging
399
+
400
+ # Extract individual release files
401
+ python scripts/extract_changelog.py
402
+
403
+ echo "✅ Extracted changelog to docs/changelog/"
370
404
 
371
405
  - name: Install documentation dependencies
372
406
  run: |
@@ -0,0 +1,286 @@
1
+ # Changelog
2
+
3
+ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
+ Formatting is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) & [Gitmoji](https://gitmoji.dev).
5
+ For more details regarding the individual PRs and contributors, please refer to our [GitHub releases](https://github.com/flixOpt/flixopt/releases).
6
+
7
+ <!-- This text won't be rendered
8
+ Note: The CI will automatically append a "What's Changed" section to the changelog for github releases.
9
+ This contains all commits, PRs, and contributors.
10
+ Therefore, the Changelog should focus on the user-facing changes.
11
+
12
+ Please remove all irrelevant sections before releasing.
13
+ Please keep the format of the changelog consistent with the other releases, so the extraction for mkdocs works.
14
+ ---
15
+
16
+ ## [Template] - ????-??-??
17
+
18
+ ### ✨ Added
19
+
20
+ ### 💥 Breaking Changes
21
+
22
+ ### ♻️ Changed
23
+
24
+ ### 🗑️ Deprecated
25
+
26
+ ### 🔥 Removed
27
+
28
+ ### 🐛 Fixed
29
+
30
+ ### 🔒 Security
31
+
32
+ ### 📦 Dependencies
33
+
34
+ ### 📝 Docs
35
+
36
+ ### 👷 Development
37
+
38
+ ### 🚧 Known Issues
39
+
40
+ ---
41
+
42
+ ## [Unreleased] - ????-??-??
43
+
44
+ ### ✨ Added
45
+
46
+ ### 💥 Breaking Changes
47
+
48
+ ### ♻️ Changed
49
+
50
+ ### 🗑️ Deprecated
51
+
52
+ ### 🔥 Removed
53
+
54
+ ### 🐛 Fixed
55
+
56
+ ### 🔒 Security
57
+
58
+ ### 📦 Dependencies
59
+
60
+ ### 📝 Docs
61
+ - Improved CHANGELOG.md formatting by adding better categories and formating by Gitmoji.
62
+ - Added a script to extract the release notes from the CHANGELOG.md file for better organized documentation.
63
+
64
+ ### 👷 Development
65
+
66
+ ### 🚧 Known Issues
67
+
68
+ Until here -->
69
+ ---
70
+
71
+ ## [2.1.10] - 2025-09-29
72
+ **Summary:** This release is a Documentation and Development release.
73
+
74
+ ### 📝 Docs
75
+ - Improved CHANGELOG.md formatting by adding better categories and formating by Gitmoji.
76
+ - Added a script to extract the release notes from the CHANGELOG.md file for better organized documentation.
77
+
78
+ ### 👷 Development
79
+ - Improved `renovate.config`
80
+ - Sped up CI by not running examples in every run and using `pytest-xdist`
81
+
82
+ ---
83
+
84
+ ## [2.1.9] - 2025-09-23
85
+
86
+ **Summary:** Small bugfix release addressing network visualization error handling.
87
+
88
+ ### 🐛 Fixed
89
+ - Fix error handling in network visualization if `networkx` is not installed
90
+
91
+ ---
92
+
93
+ ## [2.1.8] - 2025-09-22
94
+
95
+ **Summary:** Code quality improvements, enhanced documentation, and bug fixes for heat pump components and visualization features.
96
+
97
+ ### ✨ Added
98
+ - Extra Check for HeatPumpWithSource.COP to be strictly > 1 to avoid division by zero
99
+ - Apply deterministic color assignment by using sorted() in `plotting.py`
100
+ - Add missing args in docstrings in `plotting.py`, `solvers.py`, and `core.py`.
101
+
102
+ ### ♻️ Changed
103
+ - Greatly improved docstrings and documentation of all public classes
104
+ - Make path handling to be gentle about missing .html suffix in `plotting.py`
105
+ - Default for `relative_losses` in `Transmission` is now 0 instead of None
106
+ - Setter of COP in `HeatPumpWithSource` now completely overwrites the conversion factors, which is safer.
107
+ - Fix some docstrings in plotting.py
108
+ - Change assertions to raise Exceptions in `plotting.py`
109
+
110
+ ### 🐛 Fixed
111
+
112
+ **Core Components:**
113
+ - Fix COP getter and setter of `HeatPumpWithSource` returning and setting wrong conversion factors
114
+ - Fix custom compression levels in `io.save_dataset_to_netcdf`
115
+ - Fix `total_max` did not work when total min was not used
116
+
117
+ **Visualization:**
118
+ - Fix color scheme selection in network_app; color pickers now update when a scheme is selected
119
+
120
+ ### 📝 Docs
121
+ - Fix broken links in docs
122
+ - Fix some docstrings in plotting.py
123
+
124
+ ### 👷 Development
125
+ - Pin dev dependencies to specific versions
126
+ - Improve CI workflows to run faster and smarter
127
+
128
+ ---
129
+
130
+ ## [2.1.7] - 2025-09-13
131
+
132
+ **Summary:** Maintenance release to improve Code Quality, CI and update the dependencies. There are no changes or new features.
133
+
134
+ ### ✨ Added
135
+ - Added `__version__` to flixopt
136
+
137
+ ### 👷 Development
138
+ - ruff format the whole Codebase
139
+ - Added renovate config
140
+ - Added pre-commit
141
+ - lint and format in CI
142
+ - improved CI
143
+ - Updated Dependencies
144
+ - Updated Issue Templates
145
+
146
+ ---
147
+
148
+ ## [2.1.6] - 2025-09-02
149
+
150
+ **Summary:** Enhanced Sink/Source components with multi-flow support and new interactive network visualization.
151
+
152
+ ### ✨ Added
153
+ - **Network Visualization**: 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
154
+ - *Note: This is still experimental and might change in the future*
155
+
156
+ ### ♻️ Changed
157
+ - **Multi-Flow Support**: `Sink`, `Source`, and `SourceAndSink` now accept multiple `flows` as `inputs` and `outputs` instead of just one. This enables modeling more use cases with these classes
158
+ - **Flow Control**: Both `Sink` and `Source` now have a `prevent_simultaneous_flow_rates` argument to prevent simultaneous flow rates of more than one of their flows
159
+
160
+ ### 🗑️ Deprecated
161
+ - 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`
162
+
163
+ ### 🐛 Fixed
164
+ - Fixed testing issue with new `linopy` version 0.5.6
165
+
166
+ ### 👷 Development
167
+ - Added dependency "nbformat>=4.2.0" to dev dependencies to resolve issue with plotly CI
168
+
169
+ ---
170
+
171
+ ## [2.1.5] - 2025-07-08
172
+
173
+ ### 🐛 Fixed
174
+ - Fixed Docs deployment
175
+
176
+ ---
177
+
178
+ ## [2.1.4] - 2025-07-08
179
+
180
+ ### 🐛 Fixed
181
+ - Fixing release notes of 2.1.3, as well as documentation build.
182
+
183
+ ---
184
+
185
+ ## [2.1.3] - 2025-07-08
186
+
187
+ ### 🐛 Fixed
188
+ - Using `Effect.maximum_operation_per_hour` raised an error, needing an extra timestep. This has been fixed thanks to @PRse4.
189
+
190
+ ---
191
+
192
+ ## [2.1.2] - 2025-06-14
193
+
194
+ ### 🐛 Fixed
195
+ - Storage losses per hour were not calculated correctly, as mentioned by @brokenwings01. This might have led to issues when modeling large losses and long timesteps.
196
+ - Old implementation: $c(\text{t}_{i}) \cdot (1-\dot{\text{c}}_\text{rel,loss}(\text{t}_i)) \cdot \Delta \text{t}_{i}$
197
+ - Correct implementation: $c(\text{t}_{i}) \cdot (1-\dot{\text{c}}_\text{rel,loss}(\text{t}_i)) ^{\Delta \text{t}_{i}}$
198
+
199
+ ### 🚧 Known Issues
200
+ - 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.
201
+
202
+ ---
203
+
204
+ ## [2.1.1] - 2025-05-08
205
+
206
+ ### ♻️ Changed
207
+ - Improved docstring and tests
208
+
209
+ ### 🐛 Fixed
210
+ - Fixed bug in the `_ElementResults.constraints` not returning the constraints but rather the variables
211
+
212
+ ---
213
+ ## [2.1.0] - 2025-04-11
214
+
215
+ ### ✨ Added
216
+ - Python 3.13 support added
217
+ - Logger warning if relative_minimum is used without on_off_parameters in Flow
218
+ - Greatly improved internal testing infrastructure by leveraging linopy's testing framework
219
+
220
+ ### 💥 Breaking Changes
221
+ - Restructured the modeling of the On/Off state of Flows or Components
222
+ - Variable renaming: `...|consecutive_on_hours` → `...|ConsecutiveOn|hours`
223
+ - Variable renaming: `...|consecutive_off_hours` → `...|ConsecutiveOff|hours`
224
+ - Constraint renaming: `...|consecutive_on_hours_con1` → `...|ConsecutiveOn|con1`
225
+ - Similar pattern for all consecutive on/off constraints
226
+
227
+ ### 🐛 Fixed
228
+ - Fixed the lower bound of `flow_rate` when using optional investments without OnOffParameters
229
+ - Fixed bug that prevented divest effects from working
230
+ - Added lower bounds of 0 to two unbounded vars (numerical improvement)
231
+
232
+ ---
233
+
234
+ ## [2.0.1] - 2025-04-10
235
+
236
+ ### ✨ Added
237
+ - Logger warning if relative_minimum is used without on_off_parameters in Flow
238
+
239
+ ### 🐛 Fixed
240
+ - Replace "|" with "__" in filenames when saving figures (Windows compatibility)
241
+ - Fixed bug that prevented the load factor from working without InvestmentParameters
242
+
243
+ ## [2.0.0] - 2025-03-29
244
+
245
+ **Summary:** 💥 **MAJOR RELEASE** - Complete framework migration from Pyomo to Linopy with redesigned architecture.
246
+
247
+ ### ✨ Added
248
+
249
+ **Model Capabilities:**
250
+ - Full model serialization support - save and restore unsolved Models
251
+ - Enhanced model documentation with YAML export containing human-readable mathematical formulations
252
+ - Extend flixopt models with native linopy language support
253
+ - Full Model Export/Import capabilities via linopy.Model
254
+
255
+ **Results & Data:**
256
+ - Unified solution exploration through `Calculation.results` attribute
257
+ - Compression support for result files
258
+ - `to_netcdf/from_netcdf` methods for FlowSystem and core components
259
+ - xarray integration for TimeSeries with improved datatypes support
260
+
261
+ ### 💥 Breaking Changes
262
+
263
+ **Framework Migration:**
264
+ - **Optimization Engine**: Complete migration from Pyomo to Linopy optimization framework
265
+ - **Package Import**: Framework renamed from flixOpt to flixopt (`import flixopt as fx`)
266
+ - **Data Architecture**: Redesigned data handling to rely on xarray.Dataset throughout the package
267
+ - **Results System**: Results handling completely redesigned with new `CalculationResults` class
268
+
269
+ **Variable Structure:**
270
+ - Restructured the modeling of the On/Off state of Flows or Components
271
+ - Variable renaming: `...|consecutive_on_hours` → `...|ConsecutiveOn|hours`
272
+ - Variable renaming: `...|consecutive_off_hours` → `...|ConsecutiveOff|hours`
273
+ - Constraint renaming: `...|consecutive_on_hours_con1` → `...|ConsecutiveOn|con1`
274
+ - Similar pattern for all consecutive on/off constraints
275
+
276
+ ### 🔥 Removed
277
+ - **Pyomo dependency** (replaced by linopy)
278
+ - **Period concepts** in time management (simplified to timesteps)
279
+
280
+ ### 🐛 Fixed
281
+ - Improved infeasible model detection and reporting
282
+ - Enhanced time series management and serialization
283
+ - Reduced file size through improved compression
284
+
285
+ ### 📝 Docs
286
+ - Google Style Docstrings throughout the codebase
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flixopt
3
- Version: 2.1.8
3
+ Version: 2.1.10
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>
@@ -53,6 +53,7 @@ Requires-Dist: werkzeug<4,>=3.0.0; extra == "full"
53
53
  Requires-Dist: flask<4,>=3.0.0; extra == "full"
54
54
  Provides-Extra: dev
55
55
  Requires-Dist: pytest==8.4.2; extra == "dev"
56
+ Requires-Dist: pytest-xdist==3.8.0; extra == "dev"
56
57
  Requires-Dist: nbformat==5.10.4; extra == "dev"
57
58
  Requires-Dist: ruff==0.13.0; extra == "dev"
58
59
  Requires-Dist: pre-commit==4.3.0; extra == "dev"
@@ -4,4 +4,4 @@
4
4
  - [Examples](examples/)
5
5
  - [Contribute](contribute.md)
6
6
  - [API Reference](api-reference/)
7
- - [Release Notes](changelog.md)
7
+ - [Release Notes](changelog/)
@@ -18,14 +18,12 @@ except ImportError as e:
18
18
  DASH_CYTOSCAPE_AVAILABLE = False
19
19
  VISUALIZATION_ERROR = str(e)
20
20
 
21
- if TYPE_CHECKING:
22
- from .flow_system import FlowSystem
23
-
24
- import networkx as nx
25
-
26
21
  from .components import LinearConverter, Sink, Source, SourceAndSink, Storage
27
22
  from .elements import Bus
28
23
 
24
+ if TYPE_CHECKING:
25
+ from .flow_system import FlowSystem
26
+
29
27
  logger = logging.getLogger('flixopt')
30
28
 
31
29
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flixopt
3
- Version: 2.1.8
3
+ Version: 2.1.10
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>
@@ -53,6 +53,7 @@ Requires-Dist: werkzeug<4,>=3.0.0; extra == "full"
53
53
  Requires-Dist: flask<4,>=3.0.0; extra == "full"
54
54
  Provides-Extra: dev
55
55
  Requires-Dist: pytest==8.4.2; extra == "dev"
56
+ Requires-Dist: pytest-xdist==3.8.0; extra == "dev"
56
57
  Requires-Dist: nbformat==5.10.4; extra == "dev"
57
58
  Requires-Dist: ruff==0.13.0; extra == "dev"
58
59
  Requires-Dist: pre-commit==4.3.0; extra == "dev"
@@ -76,6 +76,7 @@ pics/architecture_flixOpt.png
76
76
  pics/flixOpt_plotting.jpg
77
77
  pics/flixopt-icon.svg
78
78
  pics/pics.pptx
79
+ scripts/extract_changelog.py
79
80
  scripts/extract_release_notes.py
80
81
  scripts/gen_ref_pages.py
81
82
  tests/__init__.py
@@ -14,6 +14,7 @@ tomli<3,>=2.0.1
14
14
 
15
15
  [dev]
16
16
  pytest==8.4.2
17
+ pytest-xdist==3.8.0
17
18
  nbformat==5.10.4
18
19
  ruff==0.13.0
19
20
  pre-commit==4.3.0
@@ -80,6 +80,7 @@ full = [
80
80
  # Development tools and testing
81
81
  dev = [
82
82
  "pytest==8.4.2",
83
+ "pytest-xdist==3.8.0",
83
84
  "nbformat==5.10.4",
84
85
  "ruff==0.13.0",
85
86
  "pre-commit==4.3.0",
@@ -176,6 +177,13 @@ docstring-code-format = true
176
177
  [tool.ruff.lint.pyupgrade]
177
178
  keep-runtime-typing = false # Allow pyupgrade to drop runtime typing; prefer postponed annotations
178
179
 
180
+ [tool.pytest.ini_options]
181
+ markers = [
182
+ "slow: marks tests as slow",
183
+ "examples: marks example tests (run only on releases)",
184
+ ]
185
+ addopts = "-m 'not examples'" # Skip examples by default
186
+
179
187
  [tool.bandit]
180
188
  skips = ["B101", "B506"] # assert_used and yaml_load
181
189
  exclude_dirs = ["tests/"]
@@ -14,10 +14,18 @@
14
14
  "automerge": false,
15
15
  "labels": ["dependencies"],
16
16
  "rangeStrategy": "widen",
17
+ "minimumReleaseAge": "7 days",
17
18
  "packageRules": [
18
19
  {
19
- "matchDepTypes": ["dev-dependencies", "devDependencies"],
20
- "rangeStrategy": "pin"
20
+ "matchDepTypes": ["dev", "docs"],
21
+ "rangeStrategy": "pin",
22
+ "minimumReleaseAge": "14 days"
23
+ },
24
+ {
25
+ "matchUpdateTypes": ["patch"],
26
+ "matchCurrentVersion": "!/^0/",
27
+ "automerge": true,
28
+ "automergeType": "pr"
21
29
  }
22
30
  ]
23
31
  }
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Extract individual releases from CHANGELOG.md to docs/changelog/
4
+ Simple script to create one file per release.
5
+ """
6
+
7
+ import os
8
+ import re
9
+ from pathlib import Path
10
+
11
+ from packaging.version import InvalidVersion, Version
12
+ from packaging.version import parse as parse_version
13
+
14
+
15
+ def extract_releases():
16
+ """Extract releases from CHANGELOG.md and save to individual files."""
17
+
18
+ changelog_path = Path('CHANGELOG.md')
19
+ output_dir = Path('docs/changelog')
20
+
21
+ if not changelog_path.exists():
22
+ print('❌ CHANGELOG.md not found')
23
+ return
24
+
25
+ # Create output directory
26
+ output_dir.mkdir(parents=True, exist_ok=True)
27
+
28
+ # Read changelog
29
+ with open(changelog_path, encoding='utf-8') as f:
30
+ content = f.read()
31
+
32
+ # Remove template section (HTML comments)
33
+ content = re.sub(r'<!-- This text won\'t be rendered.*?Until here -->', '', content, flags=re.DOTALL)
34
+
35
+ # Split by release headers
36
+ sections = re.split(r'^## \[', content, flags=re.MULTILINE)
37
+
38
+ releases = []
39
+ for section in sections[1:]: # Skip first empty section
40
+ # Extract version and date from start of section
41
+ match = re.match(r'([^\]]+)\] - ([^\n]+)\n(.*)', section, re.DOTALL)
42
+ if match:
43
+ version, date, release_content = match.groups()
44
+ releases.append((version, date.strip(), release_content.strip()))
45
+
46
+ print(f'🔍 Found {len(releases)} releases')
47
+
48
+ # Sort releases by version (oldest first) to keep existing file prefixes stable.
49
+ def version_key(release):
50
+ try:
51
+ return parse_version(release[0])
52
+ except InvalidVersion:
53
+ return parse_version('0.0.0') # fallback for invalid versions
54
+
55
+ releases.sort(key=version_key, reverse=False)
56
+
57
+ # Show what we captured for debugging
58
+ if releases:
59
+ print(f'🔧 First release content length: {len(releases[0][2])}')
60
+
61
+ for i, (version_str, date, release_content) in enumerate(releases):
62
+ # Clean up version for filename with numeric prefix (newest first)
63
+ index = 99999 - i # Newest first, while keeping the same file names for old releases
64
+ prefix = f'{index:05d}' # Zero-padded 5-digit number
65
+ filename = f'{prefix}-v{version_str.replace(" ", "-")}.md'
66
+ filepath = output_dir / filename
67
+
68
+ # Clean up content - remove trailing --- separators and emojis from headers
69
+ cleaned_content = re.sub(r'\s*---\s*$', '', release_content.strip())
70
+
71
+ # Generate navigation links
72
+ nav_links = []
73
+
74
+ # Previous version (older release)
75
+ if i > 0:
76
+ prev_index = 99999 - (i - 1)
77
+ prev_version = releases[i - 1][0]
78
+ prev_filename = f'{prev_index:05d}-v{prev_version.replace(" ", "-")}.md'
79
+ nav_links.append(f'← [Previous: {prev_version}]({prev_filename})')
80
+
81
+ # Next version (newer release)
82
+ if i < len(releases) - 1:
83
+ next_index = 99999 - (i + 1)
84
+ next_version = releases[i + 1][0]
85
+ next_filename = f'{next_index:05d}-v{next_version.replace(" ", "-")}.md'
86
+ nav_links.append(f'[Next: {next_version}]({next_filename}) →')
87
+
88
+ # Always add link back to index
89
+ nav_links.append('[📋 All Releases](index.md)')
90
+ # Add GitHub tag link only for valid PEP 440 versions (skip e.g. "Unreleased")
91
+ ver_obj = parse_version(version_str)
92
+ if isinstance(ver_obj, Version):
93
+ nav_links.append(f'[🏷️ GitHub Release](https://github.com/flixOpt/flixopt/releases/tag/v{version_str})')
94
+ # Create content with navigation
95
+ content_lines = [
96
+ f'# {version_str} - {date.strip()}',
97
+ '',
98
+ ' | '.join(nav_links),
99
+ '',
100
+ '---',
101
+ '',
102
+ cleaned_content,
103
+ '',
104
+ '---',
105
+ '',
106
+ ' | '.join(nav_links),
107
+ ]
108
+
109
+ # Write file
110
+ with open(filepath, 'w', encoding='utf-8') as f:
111
+ f.write('\n'.join(content_lines))
112
+
113
+ print(f'✅ Created {filename}')
114
+
115
+ print(f'🎉 Extracted {len(releases)} releases to docs/changelog/')
116
+
117
+
118
+ def extract_index():
119
+ changelog_path = Path('CHANGELOG.md')
120
+ output_dir = Path('docs/changelog')
121
+ index_path = output_dir / 'index.md'
122
+
123
+ if not changelog_path.exists():
124
+ print('❌ CHANGELOG.md not found')
125
+ return
126
+
127
+ # Create output directory
128
+ output_dir.mkdir(parents=True, exist_ok=True)
129
+
130
+ # Read changelog
131
+ with open(changelog_path, encoding='utf-8') as f:
132
+ content = f.read()
133
+
134
+ intro_match = re.search(r'# Changelog\s+([\s\S]*?)(?=<!--)', content)
135
+ if not intro_match:
136
+ raise ValueError('Intro section not found before comment block')
137
+ final_content = intro_match.group(1).strip()
138
+
139
+ # Write file
140
+ with open(index_path, 'w', encoding='utf-8') as f:
141
+ f.write('\n'.join(['# Changelog\n', final_content]))
142
+
143
+ print('✅ Created index.md')
144
+
145
+
146
+ if __name__ == '__main__':
147
+ extract_releases()
148
+ extract_index()
@@ -16,7 +16,7 @@ EXAMPLES_DIR = Path(__file__).parent.parent / 'examples'
16
16
  ), # Sort by parent and script name
17
17
  ids=lambda path: str(path.relative_to(EXAMPLES_DIR)), # Show relative file paths
18
18
  )
19
- @pytest.mark.slow
19
+ @pytest.mark.examples
20
20
  def test_example_scripts(example_script):
21
21
  """
22
22
  Test all example scripts in the examples directory.
@@ -1,181 +0,0 @@
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
- <!-- This text won't be rendered
9
- Note: The CI will automatically append a "What's Changed" section to the changelog.
10
- This contains all commits, PRs, and contributors.
11
- Therefore, the Changelog should focus on the user-facing changes.
12
- Please remove all irrelevant sections before releasing.
13
-
14
- ## [Unreleased] - ????-??-??
15
-
16
- ### Added
17
-
18
- ### Changed
19
-
20
- ### Deprecated
21
-
22
- ### Removed
23
-
24
- ### Fixed
25
-
26
- ### Known issues
27
-
28
- ### *Development*
29
-
30
- Until here -->
31
-
32
- ## [2.1.8] - 2025-09-22
33
- This release focuses on code quality improvements, enhanced documentation, and bug fixes for heat pump components and visualization features.
34
-
35
- ### Added
36
- - Extra Check for HeatPumpWithSource.COP to be strictly > 1 to avoid division by zero
37
- - Apply deterministic color assignment by using sorted() in `plotting.py`
38
- - Add missing args in docstrings in `plotting.py`, `solvers.py`, and `core.py`.
39
-
40
- ### Changed
41
- - Greatly improved docstrings and documentation of all public classes
42
- - Make path handling to be gentle about missing .html suffix in `plotting.py`
43
- - Default for `relative_losses` in `Transmission` is now 0 instead of None
44
- - Setter of COP in `HeatPumpWithSource` now completely overwrites the conversion factors, which is safer.
45
- - Fix some docstrings in plotting.py
46
- - Change assertions to raise Exceptions in `plotting.py`
47
-
48
- ### Fixed
49
- - Fix color scheme selection in network_app; color pickers now update when a scheme is selected.
50
- - Fix error handling in network visualization if networkx is not installed.
51
- - Fix broken links in docs.
52
- - Fix COP getter and setter of `HeatPumpWithSource` returning and setting wrong conversion factors.
53
- - Fix custom compression levels in `io.save_dataset_to_netcdf`
54
- - Fix `total_max` did not work when total min was not used.
55
-
56
- ### *Development*
57
- - Pin dev dependencies to specific versions
58
- - Improve CI workflows to run faster and smarter
59
-
60
- ## [2.1.7] - 2025-09-13
61
-
62
- This update is a maintenance release to improve Code Quality, CI and update the dependencies.
63
- There are no changes or new features.
64
-
65
- ### Added
66
- - Added __version__ to flixopt
67
-
68
- ### *Development*
69
- - ruff format the whole Codebase
70
- - Added renovate config
71
- - Added pre-commit
72
- - lint and format in CI
73
- - improved CI
74
- - Updated Dependencies
75
- - Updated Issue Templates
76
-
77
-
78
- ## [2.1.6] - 2025-09-02
79
-
80
- ### Changed
81
- - `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)]
82
- - 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)]
83
-
84
- ### Added
85
- - 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)]
86
-
87
- ### Deprecated
88
- - 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)]
89
-
90
- ### Fixed
91
- - Fixed testing issue with new `linopy` version 0.5.6 [[#296](https://github.com/flixOpt/flixopt/pull/296) by [@FBumann](https://github.com/FBumann)]
92
-
93
- ## [2.1.5] - 2025-07-08
94
-
95
- ### Fixed
96
- - Fixed Docs deployment
97
-
98
- ## [2.1.4] - 2025-07-08
99
-
100
- ### Fixed
101
- - Fixing release notes of 2.1.3, as well as documentation build.
102
-
103
-
104
- ## [2.1.3] - 2025-07-08
105
-
106
- ### Fixed
107
- - Using `Effect.maximum_operation_per_hour` raised an error, needing an extra timestep. This has been fixed thanks to @PRse4.
108
-
109
- ## [2.1.2] - 2025-06-14
110
-
111
- ### Fixed
112
- - 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.
113
- - Old implementation: $c(\text{t}_{i}) \cdot (1-\dot{\text{c}}_\text{rel,loss}(\text{t}_i)) \cdot \Delta \text{t}_{i}$
114
- - Correct implementation: $c(\text{t}_{i}) \cdot (1-\dot{\text{c}}_\text{rel,loss}(\text{t}_i)) ^{\Delta \text{t}_{i}}$
115
-
116
- ### Known issues
117
- - 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.
118
-
119
- ## [2.1.1] - 2025-05-08
120
-
121
- ### Fixed
122
- - Fixed bug in the `_ElementResults.constraints` not returning the constraints but rather the variables
123
-
124
- ### Changed
125
- - Improved docstring and tests
126
-
127
- ## [2.1.0] - 2025-04-11
128
-
129
- ### Added
130
- - Python 3.13 support added
131
- - Logger warning if relative_minimum is used without on_off_parameters in Flow
132
- - Greatly improved internal testing infrastructure by leveraging linopy's testing framework
133
-
134
- ### Fixed
135
- - Fixed the lower bound of `flow_rate` when using optional investments without OnOffParameters
136
- - Fixed bug that prevented divest effects from working
137
- - Added lower bounds of 0 to two unbounded vars (numerical improvement)
138
-
139
- ### Changed
140
- - **BREAKING**: Restructured the modeling of the On/Off state of Flows or Components
141
- - Variable renaming: `...|consecutive_on_hours` → `...|ConsecutiveOn|hours`
142
- - Variable renaming: `...|consecutive_off_hours` → `...|ConsecutiveOff|hours`
143
- - Constraint renaming: `...|consecutive_on_hours_con1` → `...|ConsecutiveOn|con1`
144
- - Similar pattern for all consecutive on/off constraints
145
-
146
- ## [2.0.1] - 2025-04-10
147
-
148
- ### Added
149
- - Logger warning if relative_minimum is used without on_off_parameters in Flow
150
-
151
- ### Fixed
152
- - Replace "|" with "__" in filenames when saving figures (Windows compatibility)
153
- - Fixed bug that prevented the load factor from working without InvestmentParameters
154
-
155
- ## [2.0.0] - 2025-03-29
156
-
157
- ### Changed
158
- - **BREAKING**: Complete migration from Pyomo to Linopy optimization framework
159
- - **BREAKING**: Redesigned data handling to rely on xarray.Dataset throughout the package
160
- - **BREAKING**: Framework renamed from flixOpt to flixopt (`import flixopt as fx`)
161
- - **BREAKING**: Results handling completely redesigned with new `CalculationResults` class
162
-
163
- ### Added
164
- - Full model serialization support - save and restore unsolved Models
165
- - Enhanced model documentation with YAML export containing human-readable mathematical formulations
166
- - Extend flixopt models with native linopy language support
167
- - Full Model Export/Import capabilities via linopy.Model
168
- - Unified solution exploration through `Calculation.results` attribute
169
- - Compression support for result files
170
- - `to_netcdf/from_netcdf` methods for FlowSystem and core components
171
- - xarray integration for TimeSeries with improved datatypes support
172
- - Google Style Docstrings throughout the codebase
173
-
174
- ### Fixed
175
- - Improved infeasible model detection and reporting
176
- - Enhanced time series management and serialization
177
- - Reduced file size through improved compression
178
-
179
- ### Removed
180
- - **BREAKING**: Pyomo dependency (replaced by linopy)
181
- - Period concepts in time management (simplified to timesteps)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes