Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
345 commits
Select commit Hold shift + click to select a range
1f9ef07
Remove need for timeseries with extra timestep
FBumann Jun 26, 2025
5d88fde
Simplify IO of FLowSystem
FBumann Jun 26, 2025
1e94de3
Remove parameter timesteps from IO
FBumann Jun 26, 2025
e5828ad
Improve Exceptions and Docstrings
FBumann Jun 26, 2025
870efee
Improve isel sel and resample methods
FBumann Jun 26, 2025
e97ec5f
Change test
FBumann Jun 26, 2025
f15113e
Bugfix
FBumann Jun 26, 2025
284072e
Improve
FBumann Jun 26, 2025
ebbb5dd
Improve
FBumann Jun 26, 2025
a501e05
Add test for Storage Bounds
FBumann Jun 26, 2025
1825089
Add test for Storage Bounds
FBumann Jun 26, 2025
126b07f
CHANGELOG.md
FBumann Jun 26, 2025
94d841d
ruff check
FBumann Jun 26, 2025
c19edc8
Improve types
FBumann Jun 26, 2025
36cf47d
CHANGELOG.md
FBumann Jun 26, 2025
8f1261d
Bugfix in Storage
FBumann Jun 26, 2025
89d69f0
Revert changes in example_calculation_types.py
FBumann Jun 26, 2025
76f51a8
Revert changes in simple_example.py
FBumann Jun 26, 2025
0ff4d29
Add convenient access to Elements in FlowSystem
FBumann Jun 26, 2025
84c850b
Get Aggregated Calculation Working
FBumann Jun 27, 2025
8b9dabb
Segmented running with wrong results
FBumann Jun 27, 2025
7e72ab5
Use new persistent FLowSystem to create Calculations upfront
FBumann Jun 27, 2025
17632f3
Improve SegmentedCalcualtion
FBumann Jun 27, 2025
3c355c9
Improve SegmentedCalcualtion
FBumann Jun 27, 2025
f473ce5
Fix SegmentedResults IO
FBumann Jun 27, 2025
7869a72
ruff check
FBumann Jun 27, 2025
bb29ef2
Update example
FBumann Jun 27, 2025
8d96a49
Updated logger essages to use .label_full instead of .label
FBumann Jun 27, 2025
8240da1
Re-add parameters. Use deprecation warning instead
FBumann Jun 27, 2025
8ac2664
Update changelog
FBumann Jun 27, 2025
43a64ea
Improve warning message
FBumann Jun 27, 2025
7b67f8d
Merge branch 'unify-timesteps' into scenarios-no-ts/main
FBumann Jun 27, 2025
b3fe443
Merge
FBumann Jun 27, 2025
483ba12
Merge
FBumann Jun 28, 2025
dee1de4
Fit scenario weights to model coords when transforming
FBumann Jun 28, 2025
4ec3914
Merge
FBumann Jun 28, 2025
2554d8a
Removing logic between minimum, maximum and fixed size from InvestPar…
FBumann Jun 28, 2025
d062727
Remove selected_timesteps
FBumann Jun 28, 2025
6dc23f5
Improve TypeHints
FBumann Jun 28, 2025
e6100d6
New property on InvestParameters for min/max/fixed size
FBumann Jun 28, 2025
46f2035
Move logic for InvestParameters in Transmission to from Model to Inte…
FBumann Jun 28, 2025
6baeb8e
Make transformation of data more hierarchical (Flows after Components)
FBumann Jun 28, 2025
aeaaa83
Add scenario validation
FBumann Jun 28, 2025
15fd124
Change Transmission to have a "balanced" attribute. Change Tests acco…
FBumann Jun 28, 2025
d0b231d
Improve index validations
FBumann Jun 28, 2025
4ebe6a5
rename method in tests
FBumann Jun 29, 2025
6b56dac
Update DataConverter
FBumann Jun 29, 2025
a7ec994
Add DataFrame Support back
FBumann Jun 29, 2025
2a75ed3
Add copy() to DataConverter
FBumann Jun 29, 2025
dae9f01
Update fit_to_model_coords to take a list of coords
FBumann Jun 29, 2025
ba195ff
Make the DataConverter more universal by accepting a list of coords/dims
FBumann Jun 29, 2025
605f034
Update DataConverter for n-d arrays
FBumann Jun 29, 2025
6560006
Update DataConverter for n-d arrays
FBumann Jun 29, 2025
78132ef
Add extra tests for 3-dims
FBumann Jun 29, 2025
a53c116
Add FLowSystemDimension Type
FBumann Jun 30, 2025
2cb551b
Revert some logic about the fit_to_model coords
FBumann Jun 30, 2025
d7be766
Adjust FLowSystem IO for scenarios
FBumann Jun 30, 2025
e60dd07
BUGFIX: Raise Exception instead of logging
FBumann Jun 30, 2025
bd2f1b8
Change usage of TimeSeriesData
FBumann Jun 30, 2025
a7da9d2
Adjust logic to handle non scalars
FBumann Jun 30, 2025
b8f0e22
Adjust logic to _resolve_dataarray_reference into separate method
FBumann Jun 30, 2025
7123b6b
Update IO of FlowSystem
FBumann Jun 30, 2025
fa5475d
Improve get_coords()
FBumann Jul 2, 2025
80cb161
Adjust FlowSystem init for correct IO
FBumann Jul 2, 2025
81ad3ba
Add scenario to sel and isel methods, and dont normalize scenario wei…
FBumann Jul 2, 2025
691a45e
Improve scenario_weights_handling
FBumann Jul 2, 2025
3931ac5
Add warning for not scaled weights
FBumann Jul 2, 2025
75a45e1
Update test_scenarios.py
FBumann Jul 2, 2025
2882147
Improve util method
FBumann Jul 2, 2025
50491ff
Add objective to solution dataset.
FBumann Jul 2, 2025
4f3a798
Update handling of scenario_weights update tests
FBumann Jul 2, 2025
314aef9
Ruff check. Fix type hints
FBumann Jul 2, 2025
0302947
Fix type hints and improve None handling
FBumann Jul 3, 2025
40c437a
Fix coords in AggregatedCalculation
FBumann Jul 3, 2025
8d2d208
Improve Error Messages of DataConversion
FBumann Jul 3, 2025
9c0c95f
Allow multi dim data conversion and broadcasting by length
FBumann Jul 3, 2025
d568ad6
Improve DataConverter to handle multi-dim arrays
FBumann Jul 3, 2025
ffc196a
Rename methods and remove unused code
FBumann Jul 5, 2025
6142f44
Improve DataConverter by better splitting handling per datatype. Seri…
FBumann Jul 5, 2025
cec7367
Add test for error handling
FBumann Jul 5, 2025
eba1ec4
Update scenario example
FBumann Jul 5, 2025
5f97bf3
Fix Handling of TimeSeriesData
FBumann Jul 7, 2025
9351083
Improve DataConverter
FBumann Jul 7, 2025
99e6b19
Fix resampling of the FlowSystem
FBumann Jul 15, 2025
4981a9c
Improve Warning Message
FBumann Jul 15, 2025
516f45b
Add example that leverages resampling
FBumann Jul 15, 2025
ef0acfc
Add example that leverages resampling adn fixing of Investments
FBumann Jul 16, 2025
706c1ec
Add flag to Calculation if its modeled
FBumann Jul 16, 2025
a4cdb43
Make flag for connected_and_transformed FLowSystem public
FBumann Jul 16, 2025
148a852
Make Calcualtion Methods return themselfes to make them chainable
FBumann Jul 16, 2025
61755f9
Improve example
FBumann Jul 16, 2025
66f6a86
Improve Unreleased CHANGELOG.md
FBumann Jul 16, 2025
a757e7f
Add year coord to FlowSystem
FBumann Jul 8, 2025
941d93f
Improve dimension handling
FBumann Jul 8, 2025
745e885
Change plotting to use an indexer instead
FBumann Jul 8, 2025
c9bae2a
Change plotting to use an indexer instead
FBumann Jul 15, 2025
d1b5509
Use tuples to set dimensions in Models
FBumann Jul 16, 2025
c7568dd
Bugfix in validation logic and test
FBumann Jul 16, 2025
fc62634
Improve Errors
FBumann Jul 16, 2025
e320b9f
Improve weights handling and rescaling if None
FBumann Jul 16, 2025
33a22aa
Fix typehint
FBumann Jul 16, 2025
904211f
Update Broadcasting in Storage Bounds and improve type hints
FBumann Jul 16, 2025
3c6c08b
Make .get_model_coords() return an actual xr.Coordinates Object
FBumann Jul 16, 2025
22a1cef
Improve get_coords()
FBumann Jul 17, 2025
44dbefc
Rename SystemModel to FlowSystemModel
FBumann Jul 17, 2025
f82556a
First steps
FBumann Jul 18, 2025
33460a0
Improve Feature Patterns
FBumann Jul 18, 2025
ff70674
Improve acess to variables via short names
FBumann Jul 18, 2025
fa5e30a
Improve
FBumann Jul 18, 2025
a3511f9
Add naming options to big_m_binary_bounds()
FBumann Jul 18, 2025
404dc03
Fix and improve FLowModeling with Investment
FBumann Jul 18, 2025
1ad74ce
Improve
FBumann Jul 18, 2025
d1408a4
Tyring to improve the Methods for bounding variables in different sce…
FBumann Jul 18, 2025
ab000ca
Improve BoundingPatterns
FBumann Jul 18, 2025
2afc24e
Improve BoundingPatterns
FBumann Jul 18, 2025
b248f58
Improve BoundingPatterns
FBumann Jul 18, 2025
d34445c
Fix duration Modeling
FBumann Jul 18, 2025
bde07b4
Fix On + Size
FBumann Jul 18, 2025
5861b28
Fix InvestmentModel
FBumann Jul 19, 2025
7809ee4
Fix Models
FBumann Jul 19, 2025
2bbdb44
Update constraint names in test
FBumann Jul 19, 2025
2a01abe
Fix OnOffModel for multiple Flows
FBumann Jul 19, 2025
1f1ebb7
Update constraint names in tests
FBumann Jul 19, 2025
c7b351f
Simplify
FBumann Jul 19, 2025
5d9b591
Improve handling of vars/cons and models
FBumann Jul 19, 2025
5c56b63
Revising the basic structure of a class Model
FBumann Jul 20, 2025
9d242b6
Revising the basic structure of a class Model
FBumann Jul 20, 2025
0997843
Simplify and focus more on own Model class
FBumann Jul 21, 2025
1d6ef97
Update tests
FBumann Jul 21, 2025
972cb90
Improve state computation in ModelingUtilities
FBumann Jul 21, 2025
29bec8c
Improve handling of previous flowrates
FBumann Jul 21, 2025
370ac94
Imropove repr and submodel acess
FBumann Jul 21, 2025
0f89ff0
Update access pattern in tests
FBumann Jul 21, 2025
4781cff
Fix PiecewiseEffects and StorageModel
FBumann Jul 21, 2025
333ab83
Fix StorageModel and Remove PreventSimultaniousUseModel
FBumann Jul 21, 2025
9702303
Fix Aggregation and SegmentedCalculation
FBumann Jul 21, 2025
91bd461
Update tests
FBumann Jul 21, 2025
94314c3
Loosen precision in tests
FBumann Jul 21, 2025
50cc2cb
Update test_on_hours_computation.py and some types
FBumann Jul 21, 2025
e52f800
Rename class Model to Submodel
FBumann Jul 21, 2025
9281256
rename sub_model to submodel everywhere
FBumann Jul 21, 2025
9001c6a
rename self.model to self.submodel everywhere
FBumann Jul 21, 2025
286a8b7
Rename .model with .submodel if its only a submodel
FBumann Jul 21, 2025
ae1752b
Rename .sub_models with .submodels
FBumann Jul 21, 2025
1822384
Improve repr
FBumann Jul 22, 2025
2aa9d4b
Improve repr
FBumann Jul 22, 2025
5ca9707
Include def do_modeling() into __init__() of models
FBumann Jul 22, 2025
7e04399
Make properties private
FBumann Jul 22, 2025
4f95ebc
Improve Inheritance of Models
FBumann Jul 22, 2025
f73fe99
Merge branch 'main' into v3.0.0/main
FBumann Jul 22, 2025
2d9c920
V3.0.0/plotting (#285)
FBumann Jul 22, 2025
5fd05e3
ruff check
FBumann Jul 22, 2025
20a1964
Improve typehints
FBumann Jul 22, 2025
9b05f8f
Update CHANGELOG.md
FBumann Jul 22, 2025
4d7fd29
Bugfix from renaming to .submodel
FBumann Jul 22, 2025
3626517
Bugfix from renaming to .submodel
FBumann Jul 23, 2025
50fbb67
Improve indexer in results plotting
FBumann Jul 23, 2025
9368985
rename register_submodel() to .add_submodels() adn add SUbmodels coll…
FBumann Jul 23, 2025
e4ec410
Add nice repr to FlowSystemModel and Submodel
FBumann Jul 23, 2025
66283cb
Bugfix .variables and .constraints
FBumann Jul 23, 2025
a84dfad
Add type checks to modeling.py
FBumann Jul 23, 2025
d2182aa
Improve assertion in tests
FBumann Jul 23, 2025
75c05ee
Improve docstrings and register ElementModels directly in FlowSystemM…
FBumann Jul 23, 2025
66a6ff1
Improve __repr__()
FBumann Jul 23, 2025
e2e1f13
ruff check
FBumann Jul 23, 2025
62b18b6
Use new method to compare sets in tests
FBumann Jul 23, 2025
5f0b503
ruff check
FBumann Jul 23, 2025
15a08e9
Update Contribute.md, some dependencies and add pre-commit
FBumann Jul 23, 2025
97de53c
Pre commit hook
FBumann Jul 23, 2025
25f726e
Run Pre-Commit Hook for the first time
FBumann Jul 23, 2025
1716607
Fix link in README.md
FBumann Jul 23, 2025
b4a9236
Update Effect name in tests to be 'costs' instead of 'Costs' Everywhere
FBumann Jul 23, 2025
b7734f8
Improve some of the modeling and coord handling
FBumann Jul 23, 2025
e06692b
Add tests with years and scenarios
FBumann Jul 23, 2025
cf0186c
Update tests to run with multiple coords
FBumann Jul 23, 2025
5510297
Fix Effects dataset computation in case of empty effects
FBumann Jul 23, 2025
b694dbe
Update Test for multiple dims
FBumann Jul 24, 2025
262e8b4
Fix test with multiple dims
FBumann Jul 28, 2025
2a469f1
Fix test with multiple dims
FBumann Jul 28, 2025
159bcb3
New test
FBumann Jul 28, 2025
e764a13
New test for previous flow_rates
FBumann Jul 28, 2025
20f74f3
Merge pull request #286 from flixOpt/v3.0.0/testing
FBumann Jul 28, 2025
2c1c750
Add Model for YearAwareInvestments
FBumann Jul 29, 2025
70979fb
Add FlowSystem.years_per_year attribute and "years_of_last_year" para…
FBumann Jul 29, 2025
c9c4ddf
Add YearAwareInvestmentModel
FBumann Jul 29, 2025
85ec956
Add new Interface
FBumann Jul 29, 2025
18146c2
Improve YearAwareInvestmentModel
FBumann Jul 29, 2025
015aa1d
Rename and improve
FBumann Jul 30, 2025
e6da5ad
Move piecewise_effects
FBumann Jul 30, 2025
aafe95b
COmbine TImingInvestment into a single interface
FBumann Jul 30, 2025
9316d8a
Add model tests for investment
FBumann Jul 30, 2025
5ecb3c9
Add size_changes variables
FBumann Jul 31, 2025
b1c9b71
Add size_changes variables
FBumann Jul 31, 2025
3c98553
Improve InvestmentModel
FBumann Jul 31, 2025
5688c8f
Improve InvestmentModel
FBumann Aug 4, 2025
84c8f15
Rename parameters
FBumann Aug 4, 2025
566bcdf
remove old code
FBumann Aug 4, 2025
c334515
Add a duration_in_years to the InvestTimingParameters
FBumann Aug 4, 2025
98216e2
Improve handling of fixed_duration
FBumann Aug 5, 2025
7b45a19
Improve validation and make Investment/divestment optional by default
FBumann Aug 5, 2025
b919c0a
Rename some vars and improve previous handling
FBumann Aug 5, 2025
8e21165
Add validation for previous size
FBumann Aug 5, 2025
c2ce728
Change fit_to_model_coords to work with a Collection of dims
FBumann Aug 5, 2025
02c1f31
Improve fit_to_model_coords
FBumann Aug 5, 2025
5f85887
Improve test
FBumann Aug 5, 2025
815b8bf
Update transform_data()
FBumann Aug 6, 2025
1ffe27f
Add new "year of investment" coord to FlowSystem
FBumann Aug 7, 2025
3632965
Add 'year_of_investment' dimension to FlowSystem
FBumann Aug 7, 2025
9d78314
Improve InvestmentTiming
FBumann Aug 7, 2025
ca6fb06
Improve InvestmentTiming
FBumann Aug 7, 2025
abbe534
Add specific_effect back
FBumann Aug 7, 2025
6f550dd
add effects_by_investment_year back
FBumann Aug 7, 2025
b618578
Add year_of_investment to FLowSystem.sel()
FBumann Aug 7, 2025
4ff3e31
Improve Interface
FBumann Aug 7, 2025
98b6072
Handle selection of years properly again
FBumann Aug 7, 2025
fa4c107
Temp
FBumann Aug 7, 2025
f29dcde
Make ModelingPrimitives.consecutive_duration_tracking() dim-agnostic
FBumann Aug 13, 2025
d7574d8
Use new lifetime variable and constraining methods
FBumann Aug 13, 2025
1e61937
Improve Plausibility check
FBumann Aug 13, 2025
da3f29f
Improve InvestmentTImingParameters
FBumann Aug 13, 2025
331ed06
Improve weights
FBumann Aug 13, 2025
16c7481
Adjust test
FBumann Aug 13, 2025
e9e5e04
Remove old classes
FBumann Aug 13, 2025
1474af6
V3.0.0/main fit to model coords improve (#295)
FBumann Aug 13, 2025
d81a150
Merge branch 'v3.0.0/main' into v3.0.0/invest
FBumann Aug 13, 2025
3f03d22
ruff format
FBumann Sep 2, 2025
299f629
Merge remote-tracking branch 'origin/v3.0.0/invest' into dev
FBumann Sep 13, 2025
b9cf441
Revert changes
FBumann Sep 23, 2025
42e4f59
Revert changes
FBumann Sep 23, 2025
e1dcfb8
Update type hints
FBumann Sep 23, 2025
948f19c
Revert changes introduced by new Multiperiod Invest parameters
FBumann Sep 23, 2025
dabe87f
Improve CHnagelog and docstring of Storage
FBumann Sep 23, 2025
7d50c11
Improve Changelog
FBumann Sep 23, 2025
c90fac9
Improve InvestmentModel
FBumann Sep 23, 2025
586f55c
Improve InvestmentModel to have 2 cases. One without years and one with
FBumann Sep 23, 2025
638d531
Improve InvestmentModel to have 2 cases. One without years and one wi…
FBumann Sep 23, 2025
ea795dc
Revert some changes regarding Investments
FBumann Sep 23, 2025
9b3e24a
Typo
FBumann Sep 23, 2025
af45788
Remove Investment test file (only local testing)
FBumann Sep 23, 2025
c151f3d
More reverted changes
FBumann Sep 23, 2025
70476a8
More reverted changes
FBumann Sep 23, 2025
0c3f985
Add years_of_last_year to docstring
FBumann Sep 23, 2025
61515fa
Revert change from Investment
FBumann Sep 23, 2025
9f1a182
Revert change from Investment
FBumann Sep 23, 2025
a2985e3
Remove old todos.txt file
FBumann Sep 23, 2025
725476c
Fix typos in CHANGELOG.md
FBumann Sep 23, 2025
31e8e73
Improve usage of name_prefix to intelligently join with the label
FBumann Sep 23, 2025
ff46147
Ensure IO of years_of_last_year
FBumann Sep 24, 2025
95fa7c2
Typo
FBumann Sep 24, 2025
a9d8deb
Typo
FBumann Sep 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ Please remove all irrelevant sections before releasing.
Until here -->

## [Unreleased] - ????-??-??
Multi-Period and stochastic modeling is coming to flixopt in this release.
This Release brings Multi-year-investments and stochastic modeling to flixopt.
Further, IO methods were improved and resampling and selection of parts of the FlowSystem is now possible.
Several internal improvements were made to the codebase.

In this release, we introduce the following new features:
#### Multi-period-support

#### Multi-year-investments
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick

Fix heading levels (MD001): use h3 under h2.

Change the three h4 section headers to h3 to avoid heading‑increment violations.

Apply this diff:

-#### Multi-year-investments
+### Multi-year-investments
...
-#### Stochastic modeling
+### Stochastic modeling
...
-#### Improved Data handling: IO, resampling and more through xarray
+### Improved Data handling: IO, resampling and more through xarray

Also applies to: 42-42, 55-55

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

38-38: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4

(MD001, heading-increment)

🤖 Prompt for AI Agents
In CHANGELOG.md around lines 38, 42, and 55, the section headers currently use
h4 (####) which violates MD001; change each of those headers from h4 to h3 by
replacing the leading "####" with "###" so they are proper h3 headings under the
h2 parent; update all three instances (lines 38, 42, 55) consistently.

A flixopt model might be modeled with a "year" dimension.
This enables to model transformation pathways over multiple years.
This enables to model transformation pathways over multiple years with several investment decisions

#### Stochastic modeling
A flixopt model can be modeled with a scenario dimension.
Expand Down Expand Up @@ -67,17 +69,17 @@ The weighted sum of the total objective effect of each scenario is used as the o


### Added
* FlowSystem Restoring: The used FlowSystem will now get restired from the results (lazily). ALll Parameters can be safely acessed anytime after the solve.
* FLowResults added as a new class to store the results of Flows. They can now be accessed directly.
* FlowSystem Restoring: The used FlowSystem is now accessible directly form the results without manual restoring (lazily). All Parameters can be safely accessed anytime after the solve.
* FlowResults added as a new class to store the results of Flows. They can now be accessed directly.
Comment on lines +72 to +73
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick

Typo: “form” → “from”.

“…accessible directly form the results…” should be “…from the results…”.

Apply this diff:

-* FlowSystem Restoring: The used FlowSystem is now accessible directly form the results without manual restoring (lazily). All Parameters can be safely accessed anytime after the solve.
+* FlowSystem Restoring: The used FlowSystem is now accessible directly from the results without manual restoring (lazily). All Parameters can be safely accessed anytime after the solve.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* FlowSystem Restoring: The used FlowSystem is now accessible directly form the results without manual restoring (lazily). All Parameters can be safely accessed anytime after the solve.
* FlowResults added as a new class to store the results of Flows. They can now be accessed directly.
* FlowSystem Restoring: The used FlowSystem is now accessible directly from the results without manual restoring (lazily). All Parameters can be safely accessed anytime after the solve.
* FlowResults added as a new class to store the results of Flows. They can now be accessed directly.
🤖 Prompt for AI Agents
In CHANGELOG.md around lines 72 to 73, there is a typo: the phrase "accessible
directly form the results" should read "accessible directly from the results";
update that word ("form" → "from") in the sentence and ensure the corrected
sentence reads "...accessible directly from the results without manual restoring
(lazily)."

* Added precomputed DataArrays for `size`s, `flow_rate`s and `flow_hour`s.
* Added `effects_per_component()`-Dataset to Results that stores the direct (and indirect) effects of each component. This greatly improves the evaluation of the impact of individual Components, even with many and complex effects.
* Improved filter methods for Results
* Balanced storage - Storage charging and discharging sizes can now be forced to be equal in when optimizing their size.
* Improved filter methods in `results.py`
* Balanced storage - Storage charging and discharging sizes can now be forced to be equal when optimizing their size by the `balanced` parameter.
* Added Example for 2-stage Investment decisions leveraging the resampling of a FlowSystem
* New Storage Parameter: `relative_minimum_final_charge_state` and `relative_maximum_final_charge_state` parameter for final state control
* New Storage Parameter: `relative_minimum_final_charge_state` and `relative_maximum_final_charge_state` parameter for final state control. Default to last value of `relative_minimum_charge_state` and `relative_maximum_charge_state`, which will prevent change of behaviour for most users.

### Changed
* **BREAKING**: `relative_minimum_charge_state` and `relative_maximum_charge_state` don't have an extra timestep anymore. The final charge state can now be constrained by parameters `relative_minimum_final_charge_state` and `relative_maximum_final_charge_state` instead
* **BREAKING**: `relative_minimum_charge_state` and `relative_maximum_charge_state` don't have an extra timestep anymore.
* **BREAKING**: Renamed class `SystemModel` to `FlowSystemModel`
* **BREAKING**: Renamed class `Model` to `Submodel`
* **BREAKING**: Renamed `mode` parameter in plotting methods to `style`
Expand All @@ -87,7 +89,7 @@ The weighted sum of the total objective effect of each scenario is used as the o
* Enhanced FlowSystem interface with improved `__repr__()` and `__str__()` methods
* Improved Model Structure - Views and organisation is now divided into:
* Model: The main Model (linopy.Model) that is used to create and store the variables and constraints for the flow_system.
* Submodel: The base class for all submodels. Each is a subset of the Model, for simpler acess and clearer code.
* Submodel: The base class for all submodels. Each is a subset of the Model, for simpler access and clearer code.

### Deprecated
* The `agg_group` and `agg_weight` parameters of `TimeSeriesData` are deprecated and will be removed in a future version. Use `aggregation_group` and `aggregation_weight` instead.
Expand All @@ -103,7 +105,7 @@ The weighted sum of the total objective effect of each scenario is used as the o
* Better type consistency across all framework components

### Known issues
* IO for single Interfaces/Elemenets to Datasets might not work properly if the Interface/Element is not part of a fully transformed and connected FlowSystem. This arrises from Numeric Data not being stored as xr.DataArray by the user. To avoid this, always use the `to_dataset()` on Elements inside a FlowSystem thats connected and transformed.
* IO for single Interfaces/Elements to Datasets might not work properly if the Interface/Element is not part of a fully transformed and connected FlowSystem. This arises from Numeric Data not being stored as xr.DataArray by the user. To avoid this, always use the `to_dataset()` on Elements inside a FlowSystem that's connected and transformed.

### *Development*
* **BREAKING**: Calculation.do_modeling() now returns the Calculation object instead of its linopy.Model
Expand Down
59 changes: 30 additions & 29 deletions flixopt/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,14 @@ def _plausibility_checks(self) -> None:
f'(in {self.label_full}) and variable size is uncommon. Please check if this is intended!'
)

def transform_data(self, flow_system: FlowSystem):
super().transform_data(flow_system)
def transform_data(self, flow_system: FlowSystem, name_prefix: str = '') -> None:
super().transform_data(flow_system, name_prefix)
if self.conversion_factors:
self.conversion_factors = self._transform_conversion_factors(flow_system)
if self.piecewise_conversion:
self.piecewise_conversion.has_time_dim = True
self.piecewise_conversion.transform_data(flow_system, f'{self.label_full}|PiecewiseConversion')
prefix = '|'.join(filter(None, [name_prefix, self.label_full]))
self.piecewise_conversion.transform_data(flow_system, f'{prefix}|PiecewiseConversion')

def _transform_conversion_factors(self, flow_system: FlowSystem) -> list[dict[str, xr.DataArray]]:
"""Converts all conversion factors to internal datatypes"""
Expand Down Expand Up @@ -261,10 +262,12 @@ class Storage(Component):
initial_charge_state: Storage charge state at the beginning of the time horizon.
Can be numeric value or 'lastValueOfSim', which is recommended for if the initial start state is not known.
Default is 0.
minimal_final_charge_state: Minimum absolute charge state required at the end
of the time horizon. Useful for ensuring energy security or meeting contracts.
maximal_final_charge_state: Maximum absolute charge state allowed at the end
of the time horizon. Useful for preventing overcharge or managing inventory.
minimal_final_charge_state: Minimum absolute charge state required at the end of the time horizon.
maximal_final_charge_state: Maximum absolute charge state allowed at the end of the time horizon.
relative_minimum_final_charge_state: Minimum relative charge state required at the end of the time horizon.
Defaults to the last value of the relative_minimum_charge_state.
relative_maximum_final_charge_state: Maximum relative charge state allowed at the end of the time horizon.
Defaults to the last value of the relative_maximum_charge_state.
eta_charge: Charging efficiency factor (0-1 range). Accounts for conversion
losses during charging. Default is 1 (perfect efficiency).
eta_discharge: Discharging efficiency factor (0-1 range). Accounts for
Expand Down Expand Up @@ -420,46 +423,47 @@ def create_model(self, model: FlowSystemModel) -> StorageModel:
self.submodel = StorageModel(model, self)
return self.submodel

def transform_data(self, flow_system: FlowSystem) -> None:
super().transform_data(flow_system)
def transform_data(self, flow_system: FlowSystem, name_prefix: str = '') -> None:
super().transform_data(flow_system, name_prefix)
base = '|'.join(filter(None, [name_prefix, self.label_full]))
self.relative_minimum_charge_state = flow_system.fit_to_model_coords(
f'{self.label_full}|relative_minimum_charge_state',
f'{base}|relative_minimum_charge_state',
self.relative_minimum_charge_state,
)
self.relative_maximum_charge_state = flow_system.fit_to_model_coords(
f'{self.label_full}|relative_maximum_charge_state',
f'{base}|relative_maximum_charge_state',
self.relative_maximum_charge_state,
)
self.eta_charge = flow_system.fit_to_model_coords(f'{self.label_full}|eta_charge', self.eta_charge)
self.eta_discharge = flow_system.fit_to_model_coords(f'{self.label_full}|eta_discharge', self.eta_discharge)
self.eta_charge = flow_system.fit_to_model_coords(f'{base}|eta_charge', self.eta_charge)
self.eta_discharge = flow_system.fit_to_model_coords(f'{base}|eta_discharge', self.eta_discharge)
self.relative_loss_per_hour = flow_system.fit_to_model_coords(
f'{self.label_full}|relative_loss_per_hour', self.relative_loss_per_hour
f'{base}|relative_loss_per_hour', self.relative_loss_per_hour
)
if not isinstance(self.initial_charge_state, str):
self.initial_charge_state = flow_system.fit_to_model_coords(
f'{self.label_full}|initial_charge_state', self.initial_charge_state, dims=['year', 'scenario']
f'{base}|initial_charge_state', self.initial_charge_state, dims=['year', 'scenario']
)
self.minimal_final_charge_state = flow_system.fit_to_model_coords(
f'{self.label_full}|minimal_final_charge_state', self.minimal_final_charge_state, dims=['year', 'scenario']
f'{base}|minimal_final_charge_state', self.minimal_final_charge_state, dims=['year', 'scenario']
)
self.maximal_final_charge_state = flow_system.fit_to_model_coords(
f'{self.label_full}|maximal_final_charge_state', self.maximal_final_charge_state, dims=['year', 'scenario']
f'{base}|maximal_final_charge_state', self.maximal_final_charge_state, dims=['year', 'scenario']
)
self.relative_minimum_final_charge_state = flow_system.fit_to_model_coords(
f'{self.label_full}|relative_minimum_final_charge_state',
f'{base}|relative_minimum_final_charge_state',
self.relative_minimum_final_charge_state,
dims=['year', 'scenario'],
)
self.relative_maximum_final_charge_state = flow_system.fit_to_model_coords(
f'{self.label_full}|relative_maximum_final_charge_state',
f'{base}|relative_maximum_final_charge_state',
self.relative_maximum_final_charge_state,
dims=['year', 'scenario'],
)
if isinstance(self.capacity_in_flow_hours, InvestParameters):
self.capacity_in_flow_hours.transform_data(flow_system, f'{self.label_full}|InvestParameters')
self.capacity_in_flow_hours.transform_data(flow_system, f'{base}|InvestParameters')
else:
self.capacity_in_flow_hours = flow_system.fit_to_model_coords(
f'{self.label_full}|capacity_in_flow_hours', self.capacity_in_flow_hours, dims=['year', 'scenario']
f'{base}|capacity_in_flow_hours', self.capacity_in_flow_hours, dims=['year', 'scenario']
)

def _plausibility_checks(self) -> None:
Expand Down Expand Up @@ -691,14 +695,11 @@ def create_model(self, model) -> TransmissionModel:
self.submodel = TransmissionModel(model, self)
return self.submodel

def transform_data(self, flow_system: FlowSystem) -> None:
super().transform_data(flow_system)
self.relative_losses = flow_system.fit_to_model_coords(
f'{self.label_full}|relative_losses', self.relative_losses
)
self.absolute_losses = flow_system.fit_to_model_coords(
f'{self.label_full}|absolute_losses', self.absolute_losses
)
def transform_data(self, flow_system: FlowSystem, name_prefix: str = '') -> None:
super().transform_data(flow_system, name_prefix)
base = '|'.join(filter(None, [name_prefix, self.label_full]))
self.relative_losses = flow_system.fit_to_model_coords(f'{base}|relative_losses', self.relative_losses)
self.absolute_losses = flow_system.fit_to_model_coords(f'{base}|absolute_losses', self.absolute_losses)


class TransmissionModel(ComponentModel):
Expand Down
27 changes: 14 additions & 13 deletions flixopt/effects.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import numpy as np
import xarray as xr

from .core import Scalar, TemporalData, TemporalDataUser
from .core import NonTemporalDataUser, Scalar, TemporalData, TemporalDataUser
from .features import ShareAllocationModel
from .structure import Element, ElementModel, FlowSystemModel, Submodel, register_class_for_io

Expand Down Expand Up @@ -174,41 +174,42 @@ def __init__(
self.minimum_total = minimum_total
self.maximum_total = maximum_total

def transform_data(self, flow_system: FlowSystem):
def transform_data(self, flow_system: FlowSystem, name_prefix: str = '') -> None:
base = '|'.join(filter(None, [name_prefix, self.label_full]))
self.minimum_operation_per_hour = flow_system.fit_to_model_coords(
f'{self.label_full}|minimum_operation_per_hour', self.minimum_operation_per_hour
f'{base}|minimum_operation_per_hour', self.minimum_operation_per_hour
)

self.maximum_operation_per_hour = flow_system.fit_to_model_coords(
f'{self.label_full}|maximum_operation_per_hour', self.maximum_operation_per_hour
f'{base}|maximum_operation_per_hour', self.maximum_operation_per_hour
)

self.specific_share_to_other_effects_operation = flow_system.fit_effects_to_model_coords(
f'{self.label_full}|operation->', self.specific_share_to_other_effects_operation, 'operation'
f'{base}|operation->', self.specific_share_to_other_effects_operation, 'operation'
)

self.minimum_operation = flow_system.fit_to_model_coords(
f'{self.label_full}|minimum_operation', self.minimum_operation, dims=['year', 'scenario']
f'{base}|minimum_operation', self.minimum_operation, dims=['year', 'scenario']
)
self.maximum_operation = flow_system.fit_to_model_coords(
f'{self.label_full}|maximum_operation', self.maximum_operation, dims=['year', 'scenario']
f'{base}|maximum_operation', self.maximum_operation, dims=['year', 'scenario']
)
self.minimum_invest = flow_system.fit_to_model_coords(
f'{self.label_full}|minimum_invest', self.minimum_invest, dims=['year', 'scenario']
f'{base}|minimum_invest', self.minimum_invest, dims=['year', 'scenario']
)
self.maximum_invest = flow_system.fit_to_model_coords(
f'{self.label_full}|maximum_invest', self.maximum_invest, dims=['year', 'scenario']
f'{base}|maximum_invest', self.maximum_invest, dims=['year', 'scenario']
)
self.minimum_total = flow_system.fit_to_model_coords(
f'{self.label_full}|minimum_total',
f'{base}|minimum_total',
self.minimum_total,
dims=['year', 'scenario'],
)
self.maximum_total = flow_system.fit_to_model_coords(
f'{self.label_full}|maximum_total', self.maximum_total, dims=['year', 'scenario']
f'{base}|maximum_total', self.maximum_total, dims=['year', 'scenario']
)
self.specific_share_to_other_effects_invest = flow_system.fit_effects_to_model_coords(
f'{self.label_full}|invest->',
f'{base}|invest->',
self.specific_share_to_other_effects_invest,
'invest',
dims=['year', 'scenario'],
Expand Down Expand Up @@ -275,7 +276,7 @@ def _do_modeling(self):
TemporalEffectsUser = TemporalDataUser | dict[str, TemporalDataUser] # User-specified Shares to Effects
""" This datatype is used to define a temporal share to an effect by a certain attribute. """

NonTemporalEffectsUser = Scalar | dict[str, Scalar] # User-specified Shares to Effects
NonTemporalEffectsUser = NonTemporalDataUser | dict[str, NonTemporalDataUser] # User-specified Shares to Effects
""" This datatype is used to define a scalar share to an effect by a certain attribute. """

TemporalEffects = dict[str, TemporalData] # User-specified Shares to Effects
Expand Down
Loading