flixopt 3.1.0__tar.gz → 3.1.1__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 (33) hide show
  1. {flixopt-3.1.0 → flixopt-3.1.1}/CHANGELOG.md +39 -0
  2. {flixopt-3.1.0/flixopt.egg-info → flixopt-3.1.1}/PKG-INFO +1 -1
  3. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/components.py +12 -10
  4. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/effects.py +11 -13
  5. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/results.py +30 -14
  6. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/structure.py +3 -6
  7. {flixopt-3.1.0 → flixopt-3.1.1/flixopt.egg-info}/PKG-INFO +1 -1
  8. {flixopt-3.1.0 → flixopt-3.1.1}/LICENSE +0 -0
  9. {flixopt-3.1.0 → flixopt-3.1.1}/MANIFEST.in +0 -0
  10. {flixopt-3.1.0 → flixopt-3.1.1}/README.md +0 -0
  11. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/__init__.py +0 -0
  12. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/aggregation.py +0 -0
  13. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/calculation.py +0 -0
  14. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/commons.py +0 -0
  15. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/config.py +0 -0
  16. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/core.py +0 -0
  17. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/elements.py +0 -0
  18. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/features.py +0 -0
  19. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/flow_system.py +0 -0
  20. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/interface.py +0 -0
  21. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/io.py +0 -0
  22. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/linear_converters.py +0 -0
  23. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/modeling.py +0 -0
  24. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/network_app.py +0 -0
  25. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/plotting.py +0 -0
  26. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/solvers.py +0 -0
  27. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt/utils.py +0 -0
  28. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt.egg-info/SOURCES.txt +0 -0
  29. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt.egg-info/dependency_links.txt +0 -0
  30. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt.egg-info/requires.txt +0 -0
  31. {flixopt-3.1.0 → flixopt-3.1.1}/flixopt.egg-info/top_level.txt +0 -0
  32. {flixopt-3.1.0 → flixopt-3.1.1}/pyproject.toml +0 -0
  33. {flixopt-3.1.0 → flixopt-3.1.1}/setup.cfg +0 -0
@@ -50,8 +50,47 @@ If upgrading from v2.x, see the [v3.0.0 release notes](https://github.com/flixOp
50
50
 
51
51
  ## [Unreleased] - ????-??-??
52
52
 
53
+ If upgrading from v2.x, see the [v3.0.0 release notes](https://github.com/flixOpt/flixOpt/releases/tag/v3.0.0) and [Migration Guide](https://flixopt.github.io/flixopt/latest/user-guide/migration-guide-v3/).
54
+
55
+ ### ✨ Added
56
+
57
+ ### 💥 Breaking Changes
58
+
59
+ ### ♻️ Changed
60
+
61
+ ### 🗑️ Deprecated
62
+
63
+ ### 🔥 Removed
64
+
65
+ ### 🐛 Fixed
66
+
67
+ ### 🔒 Security
68
+
69
+ ### 📦 Dependencies
70
+
71
+ ### 📝 Docs
72
+
73
+ ### 👷 Development
74
+
75
+ ### 🚧 Known Issues
76
+
77
+ ---
78
+
53
79
  Until here -->
54
80
 
81
+ ## [3.1.1] - 2025-10-20
82
+ **Summary**: Fixed a bug when acessing the `effects_per_component` dataset in results without periodic effects.
83
+
84
+ If upgrading from v2.x, see the [v3.0.0 release notes](https://github.com/flixOpt/flixOpt/releases/tag/v3.0.0) and [Migration Guide](https://flixopt.github.io/flixopt/latest/user-guide/migration-guide-v3/).
85
+
86
+ ### 🐛 Fixed
87
+ - Fixed ValueError in effects_per_component when all periodic effects are scalars/NaN by explicitly creating mode-specific templates (via _create_template_for_mode) with correct dimensions
88
+
89
+ ### 👷 Development
90
+ - Converted all remaining numpy style docstrings to google style
91
+
92
+ ---
93
+
55
94
  ## [3.1.0] - 2025-10-19
56
95
 
57
96
  **Summary**: This release adds faceting and animation support for multidimensional plots and redesigns the documentation website. Plotting results across scenarios or periods is now significantly simpler (Plotly only).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flixopt
3
- Version: 3.1.0
3
+ Version: 3.1.1
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>
@@ -1304,16 +1304,18 @@ class Sink(Component):
1304
1304
  prevent_simultaneous_flow_rates: bool = False,
1305
1305
  **kwargs,
1306
1306
  ):
1307
- """
1308
- Initialize a Sink (consumes flow from the system).
1309
-
1310
- Supports legacy `sink=` keyword for backward compatibility (deprecated): if `sink` is provided it is used as the single input flow and a DeprecationWarning is issued; specifying both `inputs` and `sink` raises ValueError.
1311
-
1312
- Parameters:
1313
- label (str): Unique element label.
1314
- inputs (list[Flow], optional): Input flows for the sink.
1315
- meta_data (dict, optional): Arbitrary metadata attached to the element.
1316
- prevent_simultaneous_flow_rates (bool, optional): If True, prevents simultaneous nonzero flow rates across the element's inputs by wiring that restriction into the base Component setup.
1307
+ """Initialize a Sink (consumes flow from the system).
1308
+
1309
+ Supports legacy `sink=` keyword for backward compatibility (deprecated): if `sink` is provided
1310
+ it is used as the single input flow and a DeprecationWarning is issued; specifying both
1311
+ `inputs` and `sink` raises ValueError.
1312
+
1313
+ Args:
1314
+ label: Unique element label.
1315
+ inputs: Input flows for the sink.
1316
+ meta_data: Arbitrary metadata attached to the element.
1317
+ prevent_simultaneous_flow_rates: If True, prevents simultaneous nonzero flow rates
1318
+ across the element's inputs by wiring that restriction into the base Component setup.
1317
1319
 
1318
1320
  Note:
1319
1321
  The deprecated `sink` kwarg is accepted for compatibility but will be removed in future releases.
@@ -480,19 +480,17 @@ class EffectCollection:
480
480
  def create_effect_values_dict(
481
481
  self, effect_values_user: PeriodicEffectsUser | TemporalEffectsUser
482
482
  ) -> dict[str, Scalar | TemporalDataUser] | None:
483
- """
484
- Converts effect values into a dictionary. If a scalar is provided, it is associated with a default effect type.
485
-
486
- Examples
487
- --------
488
- effect_values_user = 20 -> {'<standard_effect_label>': 20}
489
- effect_values_user = {None: 20} -> {'<standard_effect_label>': 20}
490
- effect_values_user = None -> None
491
- effect_values_user = {'effect1': 20, 'effect2': 0.3} -> {'effect1': 20, 'effect2': 0.3}
492
-
493
- Returns
494
- -------
495
- dict or None
483
+ """Converts effect values into a dictionary. If a scalar is provided, it is associated with a default effect type.
484
+
485
+ Examples:
486
+ ```python
487
+ effect_values_user = 20 -> {'<standard_effect_label>': 20}
488
+ effect_values_user = {None: 20} -> {'<standard_effect_label>': 20}
489
+ effect_values_user = None -> None
490
+ effect_values_user = {'effect1': 20, 'effect2': 0.3} -> {'effect1': 20, 'effect2': 0.3}
491
+ ```
492
+
493
+ Returns:
496
494
  A dictionary keyed by effect label, or None if input is None.
497
495
  Note: a standard effect must be defined when passing scalars or None labels.
498
496
  """
@@ -230,6 +230,7 @@ class CalculationResults:
230
230
  self.timesteps_extra = self.solution.indexes['time']
231
231
  self.hours_per_timestep = FlowSystem.calculate_hours_per_timestep(self.timesteps_extra)
232
232
  self.scenarios = self.solution.indexes['scenario'] if 'scenario' in self.solution.indexes else None
233
+ self.periods = self.solution.indexes['period'] if 'period' in self.solution.indexes else None
233
234
 
234
235
  self._effect_share_factors = None
235
236
  self._flow_system = None
@@ -619,6 +620,30 @@ class CalculationResults:
619
620
  total = xr.DataArray(np.nan)
620
621
  return total.rename(f'{element}->{effect}({mode})')
621
622
 
623
+ def _create_template_for_mode(self, mode: Literal['temporal', 'periodic', 'total']) -> xr.DataArray:
624
+ """Create a template DataArray with the correct dimensions for a given mode.
625
+
626
+ Args:
627
+ mode: The calculation mode ('temporal', 'periodic', or 'total').
628
+
629
+ Returns:
630
+ A DataArray filled with NaN, with dimensions appropriate for the mode.
631
+ """
632
+ coords = {}
633
+ if mode == 'temporal':
634
+ coords['time'] = self.timesteps_extra
635
+ if self.periods is not None:
636
+ coords['period'] = self.periods
637
+ if self.scenarios is not None:
638
+ coords['scenario'] = self.scenarios
639
+
640
+ # Create template with appropriate shape
641
+ if coords:
642
+ shape = tuple(len(coords[dim]) for dim in coords)
643
+ return xr.DataArray(np.full(shape, np.nan, dtype=float), coords=coords, dims=list(coords.keys()))
644
+ else:
645
+ return xr.DataArray(np.nan)
646
+
622
647
  def _create_effects_dataset(self, mode: Literal['temporal', 'periodic', 'total']) -> xr.Dataset:
623
648
  """Creates a dataset containing effect totals for all components (including their flows).
624
649
  The dataset does contain the direct as well as the indirect effects of each component.
@@ -629,32 +654,23 @@ class CalculationResults:
629
654
  Returns:
630
655
  An xarray Dataset with components as dimension and effects as variables.
631
656
  """
657
+ # Create template with correct dimensions for this mode
658
+ template = self._create_template_for_mode(mode)
659
+
632
660
  ds = xr.Dataset()
633
661
  all_arrays = {}
634
- template = None # Template is needed to determine the dimensions of the arrays. This handles the case of no shares for an effect
635
-
636
662
  components_list = list(self.components)
637
663
 
638
- # First pass: collect arrays and find template
664
+ # Collect arrays for all effects and components
639
665
  for effect in self.effects:
640
666
  effect_arrays = []
641
667
  for component in components_list:
642
668
  da = self._compute_effect_total(element=component, effect=effect, mode=mode, include_flows=True)
643
669
  effect_arrays.append(da)
644
670
 
645
- if template is None and (da.dims or not da.isnull().all()):
646
- template = da
647
-
648
671
  all_arrays[effect] = effect_arrays
649
672
 
650
- # Ensure we have a template
651
- if template is None:
652
- raise ValueError(
653
- f"No template with proper dimensions found for mode '{mode}'. "
654
- f'All computed arrays are scalars, which indicates a data issue.'
655
- )
656
-
657
- # Second pass: process all effects (guaranteed to include all)
673
+ # Process all effects: expand scalar NaN arrays to match template dimensions
658
674
  for effect in self.effects:
659
675
  dataarrays = all_arrays[effect]
660
676
  component_arrays = []
@@ -880,13 +880,10 @@ class Element(Interface):
880
880
 
881
881
  @staticmethod
882
882
  def _valid_label(label: str) -> str:
883
- """
884
- Checks if the label is valid. If not, it is replaced by the default label
883
+ """Checks if the label is valid. If not, it is replaced by the default label.
885
884
 
886
- Raises
887
- ------
888
- ValueError
889
- If the label is not valid
885
+ Raises:
886
+ ValueError: If the label is not valid.
890
887
  """
891
888
  not_allowed = ['(', ')', '|', '->', '\\', '-slash-'] # \\ is needed to check for \
892
889
  if any([sign in label for sign in not_allowed]):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flixopt
3
- Version: 3.1.0
3
+ Version: 3.1.1
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>
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