ehubx 2.3.0__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.
- ehubx/__init__.py +36 -0
- ehubx/core/__init__.py +0 -0
- ehubx/core/common.py +294 -0
- ehubx/core/ehubx.py +538 -0
- ehubx/core/exceptions.py +16 -0
- ehubx/core/logging.py +451 -0
- ehubx/core/optimizer.py +594 -0
- ehubx/core/rom.py +541 -0
- ehubx/core/solver.py +654 -0
- ehubx/data/__init__.py +0 -0
- ehubx/data/ates_data.py +1198 -0
- ehubx/data/ates_tech_data.py +2720 -0
- ehubx/data/conv_tech_data.py +1235 -0
- ehubx/data/demand_data.py +495 -0
- ehubx/data/ebm_tech_data.py +1467 -0
- ehubx/data/ec_data.py +368 -0
- ehubx/data/energy_system_data.py +648 -0
- ehubx/data/exceptions.py +136 -0
- ehubx/data/export_data.py +809 -0
- ehubx/data/hp_tech_data.py +1345 -0
- ehubx/data/hub_data.py +93 -0
- ehubx/data/import_data.py +809 -0
- ehubx/data/index.py +59 -0
- ehubx/data/load_shedding_data.py +646 -0
- ehubx/data/load_shifting_data.py +1577 -0
- ehubx/data/net_link_data.py +1012 -0
- ehubx/data/net_tech_data.py +1259 -0
- ehubx/data/pareto_front_data.py +95 -0
- ehubx/data/self_sufficiency_data.py +146 -0
- ehubx/data/solar_data.py +371 -0
- ehubx/data/solar_tech_data.py +290 -0
- ehubx/data/stage_data.py +375 -0
- ehubx/data/stor_tech_data.py +923 -0
- ehubx/data/tech_data.py +1676 -0
- ehubx/data/time_data.py +317 -0
- ehubx/data/time_series.py +256 -0
- ehubx/data/unit.py +608 -0
- ehubx/data/value.py +257 -0
- ehubx/model/__init__.py +16 -0
- ehubx/model/ates_tech_model.py +1045 -0
- ehubx/model/autonomy_model.py +490 -0
- ehubx/model/common.py +20 -0
- ehubx/model/conv_tech_model.py +569 -0
- ehubx/model/demand_model.py +357 -0
- ehubx/model/ebm_tech_model.py +502 -0
- ehubx/model/ec_model.py +73 -0
- ehubx/model/energy_system_model.py +602 -0
- ehubx/model/exceptions.py +20 -0
- ehubx/model/export_model.py +360 -0
- ehubx/model/hp_tech_model.py +390 -0
- ehubx/model/hub_model.py +43 -0
- ehubx/model/import_model.py +329 -0
- ehubx/model/load_shedding_model.py +232 -0
- ehubx/model/load_shifting_model.py +986 -0
- ehubx/model/network_model.py +1391 -0
- ehubx/model/self_sufficiency_model.py +837 -0
- ehubx/model/solar_tech_model.py +326 -0
- ehubx/model/stage_model.py +41 -0
- ehubx/model/stor_tech_model.py +543 -0
- ehubx/model/tech_model.py +649 -0
- ehubx/model/times_model.py +52 -0
- ehubx/parser/__init__.py +0 -0
- ehubx/parser/ates_parser.py +632 -0
- ehubx/parser/conv_tech_parser.py +586 -0
- ehubx/parser/csv_parser.py +167 -0
- ehubx/parser/demand_parser.py +255 -0
- ehubx/parser/ebm_tech_parser.py +318 -0
- ehubx/parser/ec_parser.py +119 -0
- ehubx/parser/energy_system_parser.py +203 -0
- ehubx/parser/exceptions.py +134 -0
- ehubx/parser/hp_tech_parser.py +308 -0
- ehubx/parser/hub_parser.py +50 -0
- ehubx/parser/import_export_parser.py +426 -0
- ehubx/parser/load_shedding_parser.py +223 -0
- ehubx/parser/load_shifting_parser.py +314 -0
- ehubx/parser/net_link_parser.py +292 -0
- ehubx/parser/net_tech_parser.py +420 -0
- ehubx/parser/self_sufficiency_parser.py +73 -0
- ehubx/parser/solar_parser.py +161 -0
- ehubx/parser/stage_parser.py +89 -0
- ehubx/parser/stor_tech_parser.py +214 -0
- ehubx/parser/tech_parser.py +651 -0
- ehubx/parser/time_parser.py +21 -0
- ehubx/parser/yaml_parser.py +1198 -0
- ehubx/writer/__init__.py +0 -0
- ehubx/writer/ates_writer.py +994 -0
- ehubx/writer/common_writer.py +396 -0
- ehubx/writer/conv_tech_writer.py +491 -0
- ehubx/writer/demand_writer.py +498 -0
- ehubx/writer/ebm_tech_writer.py +568 -0
- ehubx/writer/energy_system_writer.py +483 -0
- ehubx/writer/export_writer.py +405 -0
- ehubx/writer/hp_tech_writer.py +501 -0
- ehubx/writer/import_writer.py +642 -0
- ehubx/writer/load_shedding_writer.py +299 -0
- ehubx/writer/load_shifting_writer.py +852 -0
- ehubx/writer/network_writer.py +1284 -0
- ehubx/writer/opt_vars_writer.py +205 -0
- ehubx/writer/pareto_writer.py +98 -0
- ehubx/writer/solar_writer.py +229 -0
- ehubx/writer/stor_tech_writer.py +379 -0
- ehubx/writer/tech_writer.py +767 -0
- ehubx-2.3.0.dist-info/METADATA +113 -0
- ehubx-2.3.0.dist-info/RECORD +106 -0
- ehubx-2.3.0.dist-info/WHEEL +4 -0
- ehubx-2.3.0.dist-info/licenses/LICENSE +191 -0
ehubx/__init__.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""ehubX main module"""
|
|
2
|
+
|
|
3
|
+
# type: ignore
|
|
4
|
+
|
|
5
|
+
# ------- #
|
|
6
|
+
# Version #
|
|
7
|
+
# ------- #
|
|
8
|
+
__version__ = "2.3.0"
|
|
9
|
+
|
|
10
|
+
# ------------------------------ #
|
|
11
|
+
# Easy access to common elements #
|
|
12
|
+
# ------------------------------ #
|
|
13
|
+
from .core.common import MultiObjMethod, ObjectiveType, SolverKind # noqa: F401
|
|
14
|
+
from .core.ehubx import EhubX # noqa: F401
|
|
15
|
+
from .core.rom import RomMethod, RomSettings # noqa: F401
|
|
16
|
+
from .core.solver import Glpk, Gurobi # noqa: F401
|
|
17
|
+
from .data.ates_data import AtesScheduleId # noqa: F401
|
|
18
|
+
from .data.ec_data import EcId # noqa: F401
|
|
19
|
+
from .data.hub_data import HubId # noqa: F401
|
|
20
|
+
from .data.load_shifting_data import LoadShiftId # noqa: F401
|
|
21
|
+
from .data.net_link_data import NetLinkId # noqa: F401
|
|
22
|
+
from .data.net_tech_data import NetTechId # noqa: F401
|
|
23
|
+
from .data.stage_data import StageId # noqa: F401
|
|
24
|
+
from .data.tech_data import TechId # noqa: F401
|
|
25
|
+
from .data.time_data import TimeId, Times # noqa: F401
|
|
26
|
+
from .data.unit import (
|
|
27
|
+
CurrencyUnit, # noqa: F401
|
|
28
|
+
DimlessUnit, # noqa: F401
|
|
29
|
+
LengthUnit, # noqa: F401
|
|
30
|
+
MassUnit, # noqa: F401
|
|
31
|
+
PowerUnit, # noqa: F401
|
|
32
|
+
TemperatureUnit, # noqa: F401
|
|
33
|
+
TimeUnit, # noqa: F401
|
|
34
|
+
Unit, # noqa: F401
|
|
35
|
+
)
|
|
36
|
+
from .writer.common_writer import FileGranularity # noqa: F401
|
ehubx/core/__init__.py
ADDED
|
File without changes
|
ehubx/core/common.py
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Common module. Contains repeating functionality and centralized parameters
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from enum import Enum
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# ------------ #
|
|
10
|
+
# Enumerations #
|
|
11
|
+
# ------------ #
|
|
12
|
+
class MultiObjMethod(Enum):
|
|
13
|
+
"""Algorithms to solve a bicriterial optimization problem"""
|
|
14
|
+
|
|
15
|
+
EPSCONSTRAINT = "eps-constraint"
|
|
16
|
+
"""epsilon-constraint method"""
|
|
17
|
+
|
|
18
|
+
WEIGHTEDSUM = "weighted-sum"
|
|
19
|
+
"""Weighted-sum method"""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ObjectiveType(Enum):
|
|
23
|
+
"""Objective types that ehubX can optimize for"""
|
|
24
|
+
|
|
25
|
+
COST = "cost"
|
|
26
|
+
"""Cost (minimize)"""
|
|
27
|
+
|
|
28
|
+
CO2 = "co2"
|
|
29
|
+
"""CO2 (minimize)"""
|
|
30
|
+
|
|
31
|
+
SELFSUFFICIENCY = "self-sufficiency"
|
|
32
|
+
"""Self-sufficiency (maximize)"""
|
|
33
|
+
|
|
34
|
+
AUTONOMY = "autonomy"
|
|
35
|
+
"""Autonomy (maximize)"""
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class TimeSeriesKind(Enum):
|
|
39
|
+
"""Kinds of time series profiles"""
|
|
40
|
+
|
|
41
|
+
IMPORTPRICE = "import_price"
|
|
42
|
+
"""Import price with indices (stage, hub, ec)"""
|
|
43
|
+
|
|
44
|
+
IMPORTMIN = "import_min"
|
|
45
|
+
"""Minimal import with indices (stage, hub, ec)"""
|
|
46
|
+
|
|
47
|
+
IMPORTMAX = "import_max"
|
|
48
|
+
"""Import max with indices (stage, hub, ec)"""
|
|
49
|
+
|
|
50
|
+
IMPORTCO2 = "import_co2"
|
|
51
|
+
"""Import CO2 with indices (stage, hub, ec)"""
|
|
52
|
+
|
|
53
|
+
EXPORTPRICE = "export_price"
|
|
54
|
+
"""Export price with indices (stage, hub, ec)"""
|
|
55
|
+
|
|
56
|
+
EXPORTMIN = "export_min"
|
|
57
|
+
"""Minimal export with indices (stage, hub, ec)"""
|
|
58
|
+
|
|
59
|
+
EXPORTMAX = "export_max"
|
|
60
|
+
"""Export max with indices (stage, hub, ec)"""
|
|
61
|
+
|
|
62
|
+
EXPORTCO2 = "export_co2"
|
|
63
|
+
"""Export CO2 with indices (stage, hub, ec)"""
|
|
64
|
+
|
|
65
|
+
DEMAND = "demand"
|
|
66
|
+
"Demand with indices (stage, hub, ec)"
|
|
67
|
+
|
|
68
|
+
LOADSHEDMAXABS = "load_shedding_max_abs"
|
|
69
|
+
"""Load shedding max_abs (stage, hub, ec)"""
|
|
70
|
+
|
|
71
|
+
LOADSHEDMAXREL = "load_shedding_max_rel"
|
|
72
|
+
"""Load shedding max_rel (stage, hub, ec)"""
|
|
73
|
+
|
|
74
|
+
LOADSHEDENERGYCOST = "load_shedding_energy_cost"
|
|
75
|
+
"""Load shedding energy cost (stage, hub, ec)"""
|
|
76
|
+
|
|
77
|
+
LOADSHIFTMAXABOVEABS = "load_shifting_max_above_abs"
|
|
78
|
+
"""Load shifting max_above_abs (stage, hub, ec)"""
|
|
79
|
+
|
|
80
|
+
LOADSHIFTMAXABOVEREL = "load_shifting_max_above_rel"
|
|
81
|
+
"""Load shifting max_above_rel (stage, hub, ec)"""
|
|
82
|
+
|
|
83
|
+
LOADSHIFTMAXBELOWABS = "load_shifting_max_below_abs"
|
|
84
|
+
"""Load shifting max_below_abs (stage, hub, ec)"""
|
|
85
|
+
|
|
86
|
+
LOADSHIFTMAXBELOWREL = "load_shifting_max_below_rel"
|
|
87
|
+
"""Load shifting max_below_rel (stage, hub, ec)"""
|
|
88
|
+
|
|
89
|
+
LOADSHIFTENERGYCOSTABOVE = "load_shifting_energy_cost_above"
|
|
90
|
+
"""Load shifting energy_cost_above (stage, hub, ec)"""
|
|
91
|
+
|
|
92
|
+
LOADSHIFTENERGYCOSTBELOW = "load_shifting_energy_cost_below"
|
|
93
|
+
"""Load shifting energy_cost_below (stage, hub, ec)"""
|
|
94
|
+
|
|
95
|
+
LOADSHIFTFIXCOST = "load_shifting_fix_cost"
|
|
96
|
+
"""Load shifting fix_cost (stage, hub, ec)"""
|
|
97
|
+
|
|
98
|
+
CONVTECHOUTEFF = "conv_tech_out_eff"
|
|
99
|
+
"""Conversion technology output efficiency (stage, tech, ec)"""
|
|
100
|
+
|
|
101
|
+
CONVTECHAVAIL = "conv_tech_availability"
|
|
102
|
+
"""Conversion technology availability (stage, hub, tech)"""
|
|
103
|
+
|
|
104
|
+
EBMTECHDEMANDNOM = "ebm_tech_demand_nominal"
|
|
105
|
+
"""EBM technology nominal demand (stage, hub, tech)"""
|
|
106
|
+
|
|
107
|
+
EBMTECHAVAIL = "ebm_tech_availability"
|
|
108
|
+
"""EBM technology availability (stage, hub, tech)"""
|
|
109
|
+
|
|
110
|
+
HPTECHCOP = "hp_tech_cop"
|
|
111
|
+
"""Heat pump technology COP (stage, hub, tech)"""
|
|
112
|
+
|
|
113
|
+
HPTECHTEMPHTIN = "hp_tech_temp_ht_in"
|
|
114
|
+
"""Heat pump technology temperature of heat intake (stage, hub, tech)"""
|
|
115
|
+
|
|
116
|
+
HPTECHTEMPHTOUT = "hp_tech_temp_ht_out"
|
|
117
|
+
"""Heat pump technology temperature of heat output (stage, hub, tech)"""
|
|
118
|
+
|
|
119
|
+
HPTECHAVAIL = "hp_tech_availability"
|
|
120
|
+
"""Heat pump technology availability (stage, hub, tech)"""
|
|
121
|
+
|
|
122
|
+
SOLARIRRAD = "solar_irradiation"
|
|
123
|
+
"""Solar irradiation (stage, ec)"""
|
|
124
|
+
|
|
125
|
+
NETLINKAVAIL = "net_link_availability"
|
|
126
|
+
"""Network link availability (stage, link, net_link_direction)"""
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class SolverKind(Enum):
|
|
130
|
+
"""Third-party solvers that ehubX can interface with"""
|
|
131
|
+
|
|
132
|
+
GUROBI = "Gurobi"
|
|
133
|
+
"""Gurobi (https://www.gurobi.com/)"""
|
|
134
|
+
|
|
135
|
+
GLPK = "GLPK"
|
|
136
|
+
"""GLPK (https://www.gnu.org/software/glpk/)"""
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
# -------- #
|
|
140
|
+
# Literals #
|
|
141
|
+
# -------- #
|
|
142
|
+
EPS_ZEROCHECK: float = 1e-12
|
|
143
|
+
"""
|
|
144
|
+
Epsilon value that is used as a tolerance in numerical "almost" checks.
|
|
145
|
+
E.g.; x is considered almost 5 if abs(x-5) < EPS_ZEROCHECK
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
EPS_SOFTZEROCHECK: float = 1e-2
|
|
149
|
+
"""
|
|
150
|
+
Epsilon value that is used as a tolerance in very forgiving "zero checks".
|
|
151
|
+
E.g.; x is considered close to 5 if abs(x-5) < EPS_SOFTZEROCHECK
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
EPS_BIGM: float = 1e-5
|
|
155
|
+
"""
|
|
156
|
+
Epsilon value that is added to automatically calulated bigM values to
|
|
157
|
+
avoid bigM becoming zero accidentally.
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
EPS_WEIGHTEDSUM: float = 1e-5
|
|
161
|
+
"""
|
|
162
|
+
Epsilon value that is used for the weighted sum method in multiobjective
|
|
163
|
+
optimization. If O_1 and O_2 are the objective functions, optimizing just O_1
|
|
164
|
+
is replaced by optimizing (1 - eps) * O_1 + eps * O_2. This gives stability
|
|
165
|
+
and increases the chance to obtain a Pareto optimal solution
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
EPS_PARETOZEROCHECK_ABS: float = 1e-6
|
|
169
|
+
"""
|
|
170
|
+
Absolute epsilon value that is used together with EPS_PARETOZEROCHECK_REL to
|
|
171
|
+
check if two objective values x, y are sufficiently distinct,
|
|
172
|
+
i.e.; abs(x-y) >= eps_rel * max(abs(x), abs(y)) + eps_abs
|
|
173
|
+
"""
|
|
174
|
+
|
|
175
|
+
EPS_PARETOZEROCHECK_REL: float = 1e-3
|
|
176
|
+
"""
|
|
177
|
+
Relative epsilon value that is used together with EPS_PARETOZEROCHECK_ABS to
|
|
178
|
+
check if two objective values x, y are sufficiently distinct,
|
|
179
|
+
i.e.; abs(x-y) >= eps_rel * max(abs(x), abs(y)) + eps_abs
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
MULT_HEUR_LIMIT_FROM_DEMAND: float = 1000
|
|
183
|
+
"""Multiplier used to calculate per-ts heuristic limits from demand profiles"""
|
|
184
|
+
|
|
185
|
+
MULT_HEUR_SUM_LIMIT_FROM_DEMAND: float = 100
|
|
186
|
+
"""Multiplier used to calculate sum-type heuristic limits from demand profiles"""
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def get_iterable_filename(path: str, length_iter: int = 2) -> str:
|
|
190
|
+
"""
|
|
191
|
+
Given a file path, this method adds an iteration counter after the file
|
|
192
|
+
name, looking the first counter for which no file exists
|
|
193
|
+
|
|
194
|
+
:param path: Desired path to the filename e.g. /path/to/file.txt
|
|
195
|
+
:type path: str
|
|
196
|
+
:param length_iter: Length of the iteration counter, defaults to 2
|
|
197
|
+
:type length_iter: int, optional
|
|
198
|
+
:return: First iterated file path that is not taken yet, e.g.;
|
|
199
|
+
/path/to/file_05.txt
|
|
200
|
+
:rtype: str
|
|
201
|
+
"""
|
|
202
|
+
format_string = "{:0" + str(length_iter) + "d}"
|
|
203
|
+
raw_split = path.split(".")
|
|
204
|
+
extension = raw_split[-1]
|
|
205
|
+
full_path = ".".join(raw_split[0:-1])
|
|
206
|
+
i = -1
|
|
207
|
+
file_already_exists = True
|
|
208
|
+
max_iter = pow(10, length_iter)
|
|
209
|
+
|
|
210
|
+
def build_path(j: int):
|
|
211
|
+
str_j = "_" + format_string.format(j)
|
|
212
|
+
path = full_path + str_j + "." + extension
|
|
213
|
+
return path
|
|
214
|
+
|
|
215
|
+
while file_already_exists and (i < max_iter):
|
|
216
|
+
i = i + 1
|
|
217
|
+
try_path = build_path(i)
|
|
218
|
+
file_already_exists = os.path.isfile(try_path)
|
|
219
|
+
|
|
220
|
+
path = try_path if i < max_iter else build_path(0)
|
|
221
|
+
|
|
222
|
+
return path
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def kelvin_to_celcius(temp_k: float) -> float:
|
|
226
|
+
"""
|
|
227
|
+
Convert a temperature given in Kelving to degrees Celcius
|
|
228
|
+
|
|
229
|
+
:param temp_k: Temperature in K
|
|
230
|
+
:type temp_k: float
|
|
231
|
+
:return: Temperature in °C
|
|
232
|
+
:rtype: float
|
|
233
|
+
"""
|
|
234
|
+
return temp_k - 273.15
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def hours_to_days(timespan_h: float) -> float:
|
|
238
|
+
"""
|
|
239
|
+
Convert a timespan given in hours to days
|
|
240
|
+
|
|
241
|
+
:param timespan_h: Timespan in h
|
|
242
|
+
:type timespan_h: float
|
|
243
|
+
:return: Timespan in d
|
|
244
|
+
:rtype: float
|
|
245
|
+
"""
|
|
246
|
+
return timespan_h / 24
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def days_to_hours(timespan_d: float) -> float:
|
|
250
|
+
"""
|
|
251
|
+
Convert a timespan given in days to hours
|
|
252
|
+
|
|
253
|
+
:param timespan_d: Timespan in d
|
|
254
|
+
:type timespan_ds: float
|
|
255
|
+
:return: Timespan in h
|
|
256
|
+
:rtype: float
|
|
257
|
+
"""
|
|
258
|
+
return timespan_d * 24
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def hours_to_seconds(timespan_h: float) -> float:
|
|
262
|
+
"""
|
|
263
|
+
Convert a timespan given in hours to seconds
|
|
264
|
+
|
|
265
|
+
:param timespan_h: Timespan in h
|
|
266
|
+
:type timespan_h: float
|
|
267
|
+
:return: Timespan in s
|
|
268
|
+
:rtype: float
|
|
269
|
+
"""
|
|
270
|
+
return timespan_h * 3600
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def seconds_to_hours(timespan_s: float) -> float:
|
|
274
|
+
"""
|
|
275
|
+
Convert a timespan given in seconds to hours
|
|
276
|
+
|
|
277
|
+
:param timespan_s: Timespan in s
|
|
278
|
+
:type timespan_s: float
|
|
279
|
+
:return: Timespan in h
|
|
280
|
+
:rtype: float
|
|
281
|
+
"""
|
|
282
|
+
return timespan_s / 3600
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def joule_to_kWh(energy_j: float) -> float:
|
|
286
|
+
"""
|
|
287
|
+
Convert energy given in Joule to kWh
|
|
288
|
+
|
|
289
|
+
:param energy_j: Energy in J
|
|
290
|
+
:type energy_j: float
|
|
291
|
+
:return: Energy in kWh
|
|
292
|
+
:rtype: float
|
|
293
|
+
"""
|
|
294
|
+
return energy_j / 3600000
|