flixopt 2.1.0__py3-none-any.whl → 2.2.0b0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of flixopt might be problematic. Click here for more details.

flixopt/structure.py CHANGED
@@ -19,7 +19,7 @@ from rich.console import Console
19
19
  from rich.pretty import Pretty
20
20
 
21
21
  from .config import CONFIG
22
- from .core import NumericData, Scalar, TimeSeries, TimeSeriesCollection, TimeSeriesData
22
+ from .core import Scalar, TimeSeries, TimeSeriesCollection, TimeSeriesData, TimestepData
23
23
 
24
24
  if TYPE_CHECKING: # for type checking and preventing circular imports
25
25
  from .effects import EffectCollectionModel
@@ -58,6 +58,7 @@ class SystemModel(linopy.Model):
58
58
  self.flow_system = flow_system
59
59
  self.time_series_collection = flow_system.time_series_collection
60
60
  self.effects: Optional[EffectCollectionModel] = None
61
+ self.scenario_weights = self._calculate_scenario_weights(flow_system.scenario_weights)
61
62
 
62
63
  def do_modeling(self):
63
64
  self.effects = self.flow_system.effects.create_model(self)
@@ -69,6 +70,24 @@ class SystemModel(linopy.Model):
69
70
  for bus_model in bus_models: # Buses after Components, because FlowModels are created in ComponentModels
70
71
  bus_model.do_modeling()
71
72
 
73
+ def _calculate_scenario_weights(self, weights: Optional[TimeSeries] = None) -> xr.DataArray:
74
+ """Calculates the weights of the scenarios. If None, all scenarios have the same weight. All weights are normalized to 1.
75
+ If no scenarios are present, s single weight of 1 is returned.
76
+ """
77
+ if weights is not None and not isinstance(weights, TimeSeries):
78
+ raise TypeError(f'Weights must be a TimeSeries or None, got {type(weights)}')
79
+ if self.time_series_collection.scenarios is None:
80
+ return xr.DataArray(1)
81
+ if weights is None:
82
+ weights = xr.DataArray(
83
+ np.ones(len(self.time_series_collection.scenarios)),
84
+ coords={'scenario': self.time_series_collection.scenarios}
85
+ )
86
+ elif isinstance(weights, TimeSeries):
87
+ weights = weights.selected_data
88
+
89
+ return weights / weights.sum()
90
+
72
91
  @property
73
92
  def solution(self):
74
93
  solution = super().solution
@@ -87,6 +106,10 @@ class SystemModel(linopy.Model):
87
106
  effect.label_full: effect.model.results_structure()
88
107
  for effect in sorted(self.flow_system.effects, key=lambda effect: effect.label_full.upper())
89
108
  },
109
+ 'Flows': {
110
+ flow.label_full: flow.model.results_structure()
111
+ for flow in sorted(self.flow_system.flows.values(), key=lambda flow: flow.label_full.upper())
112
+ },
90
113
  }
91
114
  return solution.reindex(time=self.time_series_collection.timesteps_extra)
92
115
 
@@ -98,13 +121,40 @@ class SystemModel(linopy.Model):
98
121
  def hours_of_previous_timesteps(self):
99
122
  return self.time_series_collection.hours_of_previous_timesteps
100
123
 
101
- @property
102
- def coords(self) -> Tuple[pd.DatetimeIndex]:
103
- return (self.time_series_collection.timesteps,)
124
+ def get_coords(
125
+ self, scenario_dim=True, time_dim=True, extra_timestep=False
126
+ ) -> Optional[Union[Tuple[pd.Index], Tuple[pd.Index, pd.Index]]]:
127
+ """
128
+ Returns the coordinates of the model
104
129
 
105
- @property
106
- def coords_extra(self) -> Tuple[pd.DatetimeIndex]:
107
- return (self.time_series_collection.timesteps_extra,)
130
+ Args:
131
+ scenario_dim: If True, the scenario dimension is included in the coordinates
132
+ time_dim: If True, the time dimension is included in the coordinates
133
+ extra_timestep: If True, the extra timesteps are used instead of the regular timesteps
134
+
135
+ Returns:
136
+ The coordinates of the model. Might also be None if no scenarios are present and time_dim is False
137
+ """
138
+ if not scenario_dim and not time_dim:
139
+ return None
140
+ scenarios = self.time_series_collection.scenarios
141
+ timesteps = (
142
+ self.time_series_collection.timesteps if not extra_timestep else self.time_series_collection.timesteps_extra
143
+ )
144
+
145
+ if scenario_dim and time_dim:
146
+ if scenarios is None:
147
+ return (timesteps,)
148
+ return timesteps, scenarios
149
+
150
+ if scenario_dim and not time_dim:
151
+ if scenarios is None:
152
+ return None
153
+ return (scenarios,)
154
+ if time_dim and not scenario_dim:
155
+ return (timesteps,)
156
+
157
+ raise ValueError(f'Cannot get coordinates with both {scenario_dim=} and {time_dim=}')
108
158
 
109
159
 
110
160
  class Interface:
@@ -449,8 +499,7 @@ class ElementModel(Model):
449
499
 
450
500
  def results_structure(self):
451
501
  return {
452
- 'label': self.label,
453
- 'label_full': self.label_full,
502
+ 'label': self.label_full,
454
503
  'variables': list(self.variables),
455
504
  'constraints': list(self.constraints),
456
505
  }
@@ -534,9 +583,12 @@ def copy_and_convert_datatypes(data: Any, use_numpy: bool = True, use_element_la
534
583
  return copy_and_convert_datatypes(data.tolist(), use_numpy, use_element_label)
535
584
 
536
585
  elif isinstance(data, TimeSeries):
537
- return copy_and_convert_datatypes(data.active_data, use_numpy, use_element_label)
586
+ return copy_and_convert_datatypes(data.selected_data, use_numpy, use_element_label)
538
587
  elif isinstance(data, TimeSeriesData):
539
588
  return copy_and_convert_datatypes(data.data, use_numpy, use_element_label)
589
+ elif isinstance(data, (pd.Series, pd.DataFrame)):
590
+ #TODO: This can be improved
591
+ return copy_and_convert_datatypes(data.values, use_numpy, use_element_label)
540
592
 
541
593
  elif isinstance(data, Interface):
542
594
  if use_element_label and isinstance(data, Element):
@@ -584,6 +636,8 @@ def get_compact_representation(data: Any, array_threshold: int = 50, decimals: i
584
636
 
585
637
  def normalized_center_of_mass(array: Any) -> float:
586
638
  # position in array (0 bis 1 normiert)
639
+ if array.ndim >= 2: # No good way to calculate center of mass for 2D arrays
640
+ return np.nan
587
641
  positions = np.linspace(0, 1, len(array)) # weights w_i
588
642
  # mass center
589
643
  if np.sum(array) == 0:
flixopt/utils.py CHANGED
@@ -11,15 +11,6 @@ import xarray as xr
11
11
  logger = logging.getLogger('flixopt')
12
12
 
13
13
 
14
- def is_number(number_alias: Union[int, float, str]):
15
- """Returns True is string is a number."""
16
- try:
17
- float(number_alias)
18
- return True
19
- except ValueError:
20
- return False
21
-
22
-
23
14
  def round_floats(obj, decimals=2):
24
15
  if isinstance(obj, dict):
25
16
  return {k: round_floats(v, decimals) for k, v in obj.items()}
@@ -27,6 +18,12 @@ def round_floats(obj, decimals=2):
27
18
  return [round_floats(v, decimals) for v in obj]
28
19
  elif isinstance(obj, float):
29
20
  return round(obj, decimals)
21
+ elif isinstance(obj, int):
22
+ return obj
23
+ elif isinstance(obj, np.ndarray):
24
+ return np.round(obj, decimals).tolist()
25
+ elif isinstance(obj, xr.DataArray):
26
+ return obj.round(decimals).values.tolist()
30
27
  return obj
31
28
 
32
29
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flixopt
3
- Version: 2.1.0
3
+ Version: 2.2.0b0
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>
@@ -14,10 +14,12 @@ docs/release-notes/index.md,sha256=6VslOEfF3KQQCbntguRKz7uGWd_W_KIYotP8L1fzAeI,2
14
14
  docs/release-notes/v2.0.0.md,sha256=eauxvCH3O0B054vhbP0G8GdeF2LM__J57VAGYRFQzBg,4676
15
15
  docs/release-notes/v2.0.1.md,sha256=_0oqZjogRv_x6DToWih78uhHu65-J1tat5A1asYxg50,398
16
16
  docs/release-notes/v2.1.0.md,sha256=uUnlzG61rI2PYce1SxIySYOnW55e_vnJYJN7l8lcB8A,1325
17
+ docs/release-notes/v2.2.0.md,sha256=MvIdMzmDA4d-h6UFGPU0dEqWl5PwJC8qPE5NvxxlCJ8,2022
17
18
  docs/user-guide/index.md,sha256=fxI_bMjz7czJ5aF_7D7l5rQVpc03WV2EAaBo9y3gB2g,7452
18
19
  docs/user-guide/Mathematical Notation/Bus.md,sha256=getjae_-rNTXbotO0euXwYCq2arBoayKsN9KeFb2u60,1612
19
20
  "docs/user-guide/Mathematical Notation/Effects, Penalty & Objective.md",sha256=RNqcJzNI1E-U01gaeoKu7m-7gjmtDWvjr2Y5JK9YgTA,5685
20
21
  docs/user-guide/Mathematical Notation/Flow.md,sha256=MaBsj5j5dfa1qnUYCKbrNqE2yDZSeJ60_hoq95uhWyg,1094
22
+ docs/user-guide/Mathematical Notation/Investment.md,sha256=NUs8b2Hx1ZNFxSuGqFHx5epk2-qqUQ7I_EG17X5EVPQ,4181
21
23
  docs/user-guide/Mathematical Notation/LinearConverter.md,sha256=XNkRgE8-MVNplKT3n1MyIrtgTRkbbwp7-qfapZw2kfU,1322
22
24
  docs/user-guide/Mathematical Notation/Piecewise.md,sha256=ia4rkKYrEidWIBsgLMAkt10JH-idmaavJTAMzAlMH_8,1994
23
25
  docs/user-guide/Mathematical Notation/Storage.md,sha256=PeNzk77i-81VX8I5r3zen3karF5v3wal9x2_ReUuyho,2199
@@ -25,34 +27,33 @@ docs/user-guide/Mathematical Notation/index.md,sha256=gkglBsoARhgvppXN9PgdJF33sC
25
27
  docs/user-guide/Mathematical Notation/others.md,sha256=wOUsfspAoSNTMlTNipeQ8ohoVVX2S-eI3dmlzqqrbR8,47
26
28
  flixopt/__init__.py,sha256=F49OK5QLUnMGmsaKQ-G0dXsVuKr9Ow_pjM4KMSNZ918,614
27
29
  flixopt/aggregation.py,sha256=UaAYh34C4XhDgiSs4lm31XEMLr4YO5BzLKUAx4NQuyI,17002
28
- flixopt/calculation.py,sha256=1Hs9dc6eqdJoHT6Dd3NlwdRORFO2vKdKx38o95FPxJE,20016
30
+ flixopt/calculation.py,sha256=u8O11pU-PaY57MybTG63MSa3Rm-fBUTn9OvytZI-3aY,21348
29
31
  flixopt/commons.py,sha256=ZNlUN1z-h9OGHPo-s-n5OLlJaoPZKVGcAdRyGKpMk4M,1256
30
- flixopt/components.py,sha256=igiJdIcMA7o1QEjk0QDSCjNj0ADSXayd1xrJldA2ch4,28846
32
+ flixopt/components.py,sha256=lu76ZklsG2fS7xOYYEoutFgj72DLCfqwFpRcBzBZfzs,31377
31
33
  flixopt/config.py,sha256=Kt8QYk7hX5qHcQUtfgjM862C6SQr4K2lDvtk_LLER8Y,9085
32
34
  flixopt/config.yaml,sha256=imzAnnhcJhIfKNTTXFB5Td7Pvk5ARn5j720k-oGGRug,392
33
- flixopt/core.py,sha256=JGsnw-VsNCQW2zDl0kMwhcPIzq08DJmcRQ02nLyDvIg,37633
34
- flixopt/effects.py,sha256=SGDIlo7VVIlMp-AeAyZx4CRJcUmpjFYqEq3lpBY8NEg,16662
35
- flixopt/elements.py,sha256=d3gyFbt2dwqcsf7wJK2Ex9AOTt6_sToI8cCqSb2-1Xo,26678
36
- flixopt/features.py,sha256=sEtdj7BpaYS9a0XdhRUtdDFXWLdaGABRXdi5JOoLPb0,43919
37
- flixopt/flow_system.py,sha256=4D2u2ucLig0GbC7ksCuWXuZPZdkgDzPafv-GhjAxRyk,17479
38
- flixopt/interface.py,sha256=uXf6Z29OfHpIRsS1-oZZ6SSuy8FLe13FjtqzHPqzzQE,12088
39
- flixopt/io.py,sha256=2QKdtu2-mkzSGBIqHtUcF9UaG32nq9qcIRxZghf1hLw,11284
40
- flixopt/linear_converters.py,sha256=ej5V_ML_3m1k9HbDnuey6pHEpQtguYkxBXHxWyE9sq0,10936
41
- flixopt/plotting.py,sha256=wUwBSQxxwy1uui-mi2hgj6h__O6EvxCnocIbX0ewpMk,54111
42
- flixopt/results.py,sha256=gzf8M8Ig3uPjPSFRJeF--MrijbUyGkuF-SdVNRl7gnc,35159
35
+ flixopt/core.py,sha256=IS9IN-WrHTn2U8cbrhkFw3TqLblKNDNzMXZVHatZuks,56359
36
+ flixopt/effects.py,sha256=TELgTCuzu8wYWEmRpQY5r_hBxQIk0pr_hm2Rn-hTpAA,24575
37
+ flixopt/elements.py,sha256=glEvUpHHjZZVUvafRAybNXiqJNlnhWWZ3edgoSfpslc,28630
38
+ flixopt/features.py,sha256=zcLzunoi-LAMUuG6OjJ_4j95zA3b-tptPkgvSN29Als,46725
39
+ flixopt/flow_system.py,sha256=mLEZ0blw5dNLRR8IDBjkQWob_uKeXD-aADQSUy9Vtjw,21090
40
+ flixopt/interface.py,sha256=HKYPO0J3FoEyxa6Wr-BIkEHsGpNwDobXq3zzy1CqoXo,16148
41
+ flixopt/io.py,sha256=S4Ia3lcKykXUEW8qn8pu8JOhqejp001bolCGXO7vleM,12029
42
+ flixopt/linear_converters.py,sha256=xIp0mxw2v5mVzT9ZWYUeJUbh-jYgFiRmku88vOXhtWA,10934
43
+ flixopt/plotting.py,sha256=68O330RnLBNlOcZ-P6WK1YBvRwSoG6x9ELrBcDBOrNA,54879
44
+ flixopt/results.py,sha256=1tD94E2YfOIA8nX5bXR3vnAnBwokO9O0Mlk5zuESF5Q,69189
43
45
  flixopt/solvers.py,sha256=k1bSoiXec3asWED70-erXkgtpn2C8KRBfSZj0FLviSM,2436
44
- flixopt/structure.py,sha256=QS0IFBHzdEMKYTgd6uosudhoDD4X0JcdF7LlS-XRacs,26295
45
- flixopt/utils.py,sha256=f-_vFDvvG27-c_VMpzkv3lb79Yny4rvoSmemushbzhU,1687
46
- flixopt-2.1.0.dist-info/licenses/LICENSE,sha256=HKsZnbrM_3Rvnr_u9cWSG90cBsj5_slaqI_z_qcxnGI,1118
46
+ flixopt/structure.py,sha256=Ufgu8cf1pO4UIww4Lht7I1Iabm6JUxWM-N7gGdNjIdM,28905
47
+ flixopt/utils.py,sha256=xuksGh1dXj8HNhkcjMCVIxlpAA_QSWXePFmkbJYvQwM,1712
48
+ flixopt-2.2.0b0.dist-info/licenses/LICENSE,sha256=HKsZnbrM_3Rvnr_u9cWSG90cBsj5_slaqI_z_qcxnGI,1118
47
49
  pics/architecture_flixOpt-pre2.0.0.png,sha256=9RWSA3vys588aadr2437zor-_-xBTQNQ0bAf8xGcu5g,70605
48
50
  pics/architecture_flixOpt.png,sha256=KjN1bJwESbkHmTW7UsJ7dZyiKZlTO7Dx20dg8KlR1HU,260219
49
51
  pics/flixOpt_plotting.jpg,sha256=zn7ZPAtXm5eRTxtOj86e4-PPhHpCar1jqGh7vMBgQGY,518862
50
52
  pics/flixopt-icon.svg,sha256=_1a6bk2pDOVEy233LC1nM6jZ35NdzD8Hd3UqGxW1Xpg,135341
51
53
  pics/pics.pptx,sha256=ImWeGGvjtWJ6BGruipsnZYmWtHj5sWdbw1NSFePbkC8,683344
52
54
  scripts/gen_ref_pages.py,sha256=AYRtXyz78x5I_Hn0oRtGVbTxgLLj2QNyRX6vWRefPjc,1960
53
- site/release-notes/_template.txt,sha256=j65E_FDxzimkcMXBrXyF6b2KPm0KAiQlGTxfhQHnN7c,496
54
55
  tests/ressources/Zeitreihen2020.csv,sha256=kbsDTKZS0iUsNZAS7m3DohzZI_OHHWe44s3GwLvcTLw,1918412
55
- flixopt-2.1.0.dist-info/METADATA,sha256=db6pwA2-_i00-KWJgBYbQzFQPZPZsab2oohuXjn2GHM,7155
56
- flixopt-2.1.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
57
- flixopt-2.1.0.dist-info/top_level.txt,sha256=U8aoMBkjiSFi7j4zgUOVgvgmyT5a1LnIArZI6TWdk-g,37
58
- flixopt-2.1.0.dist-info/RECORD,,
56
+ flixopt-2.2.0b0.dist-info/METADATA,sha256=0O2Ass8s06oafXxxkjUbHtWdfmeUUjCmUzjzcBE3uZI,7157
57
+ flixopt-2.2.0b0.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
58
+ flixopt-2.2.0b0.dist-info/top_level.txt,sha256=DEuo4R1z7GmEp5R3pjbQEJbaPRjKHFvNX2ceiBnVOL0,32
59
+ flixopt-2.2.0b0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (80.4.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -2,5 +2,4 @@ docs
2
2
  flixopt
3
3
  pics
4
4
  scripts
5
- site
6
5
  tests
@@ -1,32 +0,0 @@
1
- # Release v{version}
2
-
3
- **Release Date:** YYYY-MM-DD
4
-
5
- ## What's New
6
-
7
- * Feature 1 - Description
8
- * Feature 2 - Description
9
-
10
- ## Improvements
11
-
12
- * Improvement 1 - Description
13
- * Improvement 2 - Description
14
-
15
- ## Bug Fixes
16
-
17
- * Fixed issue with X
18
- * Resolved problem with Y
19
-
20
- ## Breaking Changes
21
-
22
- * Change 1 - Migration instructions
23
- * Change 2 - Migration instructions
24
-
25
- ## Deprecations
26
-
27
- * Feature X will be removed in v{next_version}
28
-
29
- ## Dependencies
30
-
31
- * Added dependency X v1.2.3
32
- * Updated dependency Y to v2.0.0