OpenPinch 0.2.0__tar.gz → 0.2.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.
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_problem/_target_accessor.py +6 -7
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/pinch_problem.py +47 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/__init__.py +2 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/enums.py +19 -1
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/power_cogeneration/power_cogeneration_analysis.py +14 -14
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/services_entry.py +121 -43
- {openpinch-0.2.0 → openpinch-0.2.1}/PKG-INFO +1 -1
- {openpinch-0.2.0 → openpinch-0.2.1}/pyproject.toml +1 -1
- openpinch-0.2.0/OpenPinch/services/power_cogeneration_analysis/power_cogeneration_analysis.py +0 -139
- {openpinch-0.2.0 → openpinch-0.2.1}/.gitignore +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/LICENSE +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/__main__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_problem/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_problem/_loading.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_problem/_output.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_problem/_plot_accessor.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_problem/_validation.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_problem_table/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_problem_table/_problem_table_constants.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_stream_collection/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_stream_collection/_helpers.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_workspace/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_workspace/execution.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_workspace/payloads.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_workspace/views.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/pinch_workspace.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/problem_table.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/stream.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/stream_collection.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/value.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/zone.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/data/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/data/notebooks/01_basic_pinch_and_dtcont_sensitivity.ipynb +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/data/notebooks/02_total_site_targets_and_sugcc.ipynb +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/data/notebooks/03_carnot_hpr_comparison.ipynb +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/data/notebooks/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/data/sample_cases/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/data/sample_cases/basic_pinch.json +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/data/sample_cases/chocolate_factory.json +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/data/sample_cases/crude_preheat_train.json +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/data/sample_cases/heat_pump_targeting.json +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/data/sample_cases/pulp_mill.json +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/data/sample_cases/zonal_site.json +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/config.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/config_metadata.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/problem_table_types.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/schemas/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/schemas/common.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/schemas/graphs.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/schemas/hpr.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/schemas/io.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/schemas/reporting.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/schemas/targets.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/schemas/turbine.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/lib/schemas/workspace.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/main.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/resources.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/common/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/common/capital_cost_and_area_targeting.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/common/gcc_manipulation.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/common/graph_data.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/common/graph_series_meta.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/common/problem_table_analysis.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/common/temperature_driving_force.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/common/utility_targeting.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/direct_heat_integration/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/direct_heat_integration/direct_integration_entry.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/exergy_analysis/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/exergy_analysis/exergy_targeting_entry.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/common/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/common/encoding.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/common/layout.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/common/postprocessing.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/common/preprocessing.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/common/shared.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/cycles/brayton.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/heat_pump_and_refrigeration_entry.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/targeting_services/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/targeting_services/brayton.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/targeting_services/cascade_vapour_compression.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/targeting_services/multi_simple_carnot.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/targeting_services/multi_simple_vapour_compression.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/targeting_services/multi_temperature_carnot.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/unit_models/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/unit_models/brayton_heat_pump.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/unit_models/cascade_vapour_compression_cycle.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/unit_models/parallel_vapour_compression_cycles.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/unit_models/vapour_compression_cycle.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/indirect_heat_integration/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/indirect_heat_integration/indirect_integration_entry.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/input_data_processing/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/input_data_processing/_canonicalization.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/input_data_processing/_utility_preparation.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/input_data_processing/data_preparation.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/power_cogeneration/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/power_cogeneration/unit_models/multi_stage_steam_turbine.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/streamlit_webviewer/web_graphing.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/_tabular_input.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/bb_optimisers/__init__.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/bb_optimisers/bayesian_optimisation.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/bb_optimisers/cmaes.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/bb_optimisers/common.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/bb_optimisers/dual_annealing.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/bb_optimisers/rbf_surrogate.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/blackbox_minimisers.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/costing.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/csv_to_json.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/decorators.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/export.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/heat_exchanger.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/input_validation.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/miscellaneous.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/multiscale_targeting.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/plots.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/stream_linearisation.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/water_properties.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/utils/wkbook_to_json.py +0 -0
- {openpinch-0.2.0 → openpinch-0.2.1}/README.md +0 -0
|
@@ -164,19 +164,18 @@ class _TargetAccessor:
|
|
|
164
164
|
include_subzones: bool = False,
|
|
165
165
|
state_id: Optional[str] = None,
|
|
166
166
|
) -> BaseTargetModel:
|
|
167
|
-
"""
|
|
168
|
-
|
|
167
|
+
"""
|
|
168
|
+
Run cogeneration on `TS -> IHP -> IR -> DHP -> DR -> DI`
|
|
169
|
+
unless overridden.
|
|
170
|
+
"""
|
|
169
171
|
runtime_options = dict(options or {})
|
|
170
172
|
if state_id is not None:
|
|
171
173
|
runtime_options["state_id"] = state_id
|
|
172
|
-
|
|
173
|
-
target_id = str(runtime_options["base_target_type"])
|
|
174
|
-
return self._problem._execute_targeting(
|
|
175
|
-
target_id=target_id,
|
|
174
|
+
return self._problem._execute_cogeneration_targeting(
|
|
176
175
|
application_zone=zone_name,
|
|
177
176
|
options=runtime_options,
|
|
178
177
|
include_subzones=include_subzones,
|
|
179
|
-
|
|
178
|
+
service_func=power_cogeneration_service,
|
|
180
179
|
)
|
|
181
180
|
|
|
182
181
|
def area_cost(
|
|
@@ -179,6 +179,53 @@ class PinchProblem:
|
|
|
179
179
|
f"for zone {zone.name!r}."
|
|
180
180
|
) from exc
|
|
181
181
|
|
|
182
|
+
def _execute_cogeneration_targeting(
|
|
183
|
+
self,
|
|
184
|
+
*,
|
|
185
|
+
application_zone: Optional[str | Zone],
|
|
186
|
+
options: Optional[dict[str, Any]],
|
|
187
|
+
include_subzones: bool,
|
|
188
|
+
service_func: Optional[ZoneService] = None,
|
|
189
|
+
sid: str = None,
|
|
190
|
+
) -> BaseTargetModel:
|
|
191
|
+
"""Run cogeneration targeting and return the family selected at runtime."""
|
|
192
|
+
execution_master_zone = self._build_execution_master_zone()
|
|
193
|
+
runtime_options, sid = self._resolve_runtime_state_options(
|
|
194
|
+
options,
|
|
195
|
+
zone=execution_master_zone,
|
|
196
|
+
)
|
|
197
|
+
zone = self._resolve_target_zone(
|
|
198
|
+
application_zone, master_zone=execution_master_zone
|
|
199
|
+
)
|
|
200
|
+
if include_subzones:
|
|
201
|
+
self._run_targeting_for_zone_and_subzones(
|
|
202
|
+
zone=zone,
|
|
203
|
+
direct_service_func=service_func,
|
|
204
|
+
options=runtime_options,
|
|
205
|
+
sid=sid,
|
|
206
|
+
)
|
|
207
|
+
else:
|
|
208
|
+
if service_func is not None:
|
|
209
|
+
service_func(zone, runtime_options)
|
|
210
|
+
self._results = TargetOutput.model_validate(
|
|
211
|
+
extract_results(execution_master_zone, state_id=sid)
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
selected_target_type = getattr(zone, "_selected_cogeneration_target_type", None)
|
|
215
|
+
if not isinstance(selected_target_type, str):
|
|
216
|
+
raise RuntimeError(
|
|
217
|
+
"Cogeneration did not select a compatible target "
|
|
218
|
+
f"for zone {zone.name!r}."
|
|
219
|
+
)
|
|
220
|
+
try:
|
|
221
|
+
return zone.targets[selected_target_type]
|
|
222
|
+
except KeyError as exc:
|
|
223
|
+
raise RuntimeError(
|
|
224
|
+
"Cogeneration selected target "
|
|
225
|
+
f"{selected_target_type!r} for zone {zone.name!r}, "
|
|
226
|
+
"but that target was not available on the zone."
|
|
227
|
+
) from exc
|
|
228
|
+
|
|
182
229
|
def _resolve_target_zone(
|
|
183
230
|
self,
|
|
184
231
|
application_zone: Optional[str] = None,
|
|
@@ -18,6 +18,7 @@ from .enums import (
|
|
|
18
18
|
ZT,
|
|
19
19
|
ArrowHead,
|
|
20
20
|
BB_Minimiser,
|
|
21
|
+
CogenerationTarget,
|
|
21
22
|
GraphType,
|
|
22
23
|
HeatExchangerTypes,
|
|
23
24
|
HeatFlowUnits,
|
|
@@ -113,6 +114,7 @@ __all__ = [
|
|
|
113
114
|
"schemas",
|
|
114
115
|
"ACTIVATE_TIMING",
|
|
115
116
|
"C_to_K",
|
|
117
|
+
"CogenerationTarget",
|
|
116
118
|
"Configuration",
|
|
117
119
|
"LOG_TIMING",
|
|
118
120
|
"T_CRIT",
|
|
@@ -1,10 +1,27 @@
|
|
|
1
|
-
"""Enumerations
|
|
1
|
+
"""Enumerations and lightweight typed contracts used across OpenPinch.
|
|
2
2
|
|
|
3
3
|
These enums standardize zone types, stream classifications, Problem Table
|
|
4
4
|
column names, graph labels, and options keys used by configuration and schemas.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
7
9
|
from enum import Enum
|
|
10
|
+
from typing import TYPE_CHECKING, Protocol
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from ..classes.stream_collection import StreamCollection
|
|
14
|
+
from .config import Configuration
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CogenerationTarget(Protocol):
|
|
18
|
+
"""Compatible target surface required by cogeneration analysis helpers."""
|
|
19
|
+
|
|
20
|
+
config: Configuration
|
|
21
|
+
hot_utilities: StreamCollection
|
|
22
|
+
work_target: float | None
|
|
23
|
+
turbine_efficiency_target: float | None
|
|
24
|
+
state_ids: dict[str, int] | None
|
|
8
25
|
|
|
9
26
|
|
|
10
27
|
class ZoneType(Enum):
|
|
@@ -286,6 +303,7 @@ class BB_Minimiser(str, Enum):
|
|
|
286
303
|
__all__ = [
|
|
287
304
|
"ArrowHead",
|
|
288
305
|
"BB_Minimiser",
|
|
306
|
+
"CogenerationTarget",
|
|
289
307
|
"GraphType",
|
|
290
308
|
"GT",
|
|
291
309
|
"HeatExchangerTypes",
|
|
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
|
|
9
9
|
from ...lib.config import T_CRIT, Configuration, tol
|
|
10
|
+
from ...lib.enums import CogenerationTarget
|
|
10
11
|
from ...utils.miscellaneous import get_state_index
|
|
11
12
|
from ...utils.water_properties import psat_T
|
|
12
13
|
from .unit_models.multi_stage_steam_turbine import MultiStageSteamTurbine
|
|
@@ -15,7 +16,6 @@ if TYPE_CHECKING:
|
|
|
15
16
|
import numpy as np
|
|
16
17
|
|
|
17
18
|
from ...classes.stream import Stream
|
|
18
|
-
from ...classes.zone import Zone
|
|
19
19
|
|
|
20
20
|
__all__ = [
|
|
21
21
|
"get_power_cogeneration_above_pinch",
|
|
@@ -24,18 +24,18 @@ __all__ = [
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def get_power_cogeneration_above_pinch(
|
|
27
|
-
|
|
27
|
+
target: CogenerationTarget,
|
|
28
28
|
args: dict | None = None,
|
|
29
|
-
) ->
|
|
30
|
-
"""Calculate
|
|
31
|
-
turbine_params = _prepare_turbine_parameters(
|
|
29
|
+
) -> CogenerationTarget:
|
|
30
|
+
"""Calculate above-Pinch cogeneration for a compatible thermal target object."""
|
|
31
|
+
turbine_params = _prepare_turbine_parameters(target.config)
|
|
32
32
|
idx, sid = get_state_index(
|
|
33
|
-
state_ids=getattr(
|
|
33
|
+
state_ids=getattr(target, "state_ids", None),
|
|
34
34
|
args=args,
|
|
35
35
|
)
|
|
36
|
-
utility_data = _preprocess_utilities(
|
|
36
|
+
utility_data = _preprocess_utilities(target, turbine_params, idx=idx)
|
|
37
37
|
if utility_data is None:
|
|
38
|
-
return
|
|
38
|
+
return target
|
|
39
39
|
|
|
40
40
|
turbine = MultiStageSteamTurbine()
|
|
41
41
|
total_work, details = turbine.solve(
|
|
@@ -51,9 +51,9 @@ def get_power_cogeneration_above_pinch(
|
|
|
51
51
|
is_high_p_cond_flash=turbine_params["is_high_p_cond_flash"],
|
|
52
52
|
)
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return
|
|
54
|
+
target.work_target = total_work
|
|
55
|
+
target.turbine_efficiency_target = details["overall_efficiency"]
|
|
56
|
+
return target
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
def get_power_cogeneration_below_pinch(
|
|
@@ -96,18 +96,18 @@ def _prepare_turbine_parameters(zone_config: Configuration) -> dict:
|
|
|
96
96
|
|
|
97
97
|
|
|
98
98
|
def _preprocess_utilities(
|
|
99
|
-
|
|
99
|
+
target: CogenerationTarget,
|
|
100
100
|
turbine_params: dict,
|
|
101
101
|
*,
|
|
102
102
|
idx: int | None = None,
|
|
103
103
|
) -> dict | None:
|
|
104
|
-
"""Translate hot-utility demands into turbine stage temperatures
|
|
104
|
+
"""Translate target hot-utility demands into turbine stage temperatures."""
|
|
105
105
|
stage_temperatures: list[float] = []
|
|
106
106
|
stage_heat_flows: list[float] = []
|
|
107
107
|
source_indices: list[int] = []
|
|
108
108
|
|
|
109
109
|
u: Stream
|
|
110
|
-
for i, u in enumerate(
|
|
110
|
+
for i, u in enumerate(target.hot_utilities):
|
|
111
111
|
t_supply = float(u.t_supply[idx])
|
|
112
112
|
t_target = float(u.t_target[idx])
|
|
113
113
|
heat_flow = float(u.heat_flow[idx])
|
|
@@ -30,6 +30,15 @@ __all__ = [
|
|
|
30
30
|
"area_cost_targeting_service",
|
|
31
31
|
]
|
|
32
32
|
|
|
33
|
+
_COGENERATION_TARGET_ORDER = (
|
|
34
|
+
TT.TS.value,
|
|
35
|
+
TT.IHP.value,
|
|
36
|
+
TT.IR.value,
|
|
37
|
+
TT.DHP.value,
|
|
38
|
+
TT.DR.value,
|
|
39
|
+
TT.DI.value,
|
|
40
|
+
)
|
|
41
|
+
|
|
33
42
|
|
|
34
43
|
def _record_selected_state(zone: Zone, args: dict | None) -> tuple[int, str | None]:
|
|
35
44
|
"""Persist the selected state metadata on a prepared zone."""
|
|
@@ -78,6 +87,86 @@ def _apply_zone_config_overrides(zone: Zone, args: dict | None) -> None:
|
|
|
78
87
|
setattr(zone.config, key, value)
|
|
79
88
|
|
|
80
89
|
|
|
90
|
+
def _normalize_cogeneration_base_target_type(
|
|
91
|
+
base_target_type: object | None,
|
|
92
|
+
) -> str | None:
|
|
93
|
+
"""Validate an explicit cogeneration base target override."""
|
|
94
|
+
if base_target_type is None:
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
normalized = str(base_target_type)
|
|
98
|
+
if normalized not in _COGENERATION_TARGET_ORDER:
|
|
99
|
+
supported = ", ".join(_COGENERATION_TARGET_ORDER)
|
|
100
|
+
raise ValueError(
|
|
101
|
+
"Unsupported cogeneration base_target_type "
|
|
102
|
+
f"{normalized!r}. Supported types: {supported}."
|
|
103
|
+
)
|
|
104
|
+
return normalized
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _get_cogeneration_candidate_order(
|
|
108
|
+
base_target_type: str | None,
|
|
109
|
+
) -> tuple[str, ...]:
|
|
110
|
+
"""Return the exact cogeneration target search order for this call."""
|
|
111
|
+
if base_target_type is not None:
|
|
112
|
+
return (base_target_type,)
|
|
113
|
+
return _COGENERATION_TARGET_ORDER
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _get_cogeneration_refresh_services():
|
|
117
|
+
"""Map compatible cogeneration target families to their prerequisite service."""
|
|
118
|
+
return {
|
|
119
|
+
TT.DI.value: direct_heat_integration_service,
|
|
120
|
+
TT.TS.value: indirect_heat_integration_service,
|
|
121
|
+
TT.DHP.value: direct_heat_pump_service,
|
|
122
|
+
TT.DR.value: direct_refrigeration_service,
|
|
123
|
+
TT.IHP.value: indirect_heat_pump_service,
|
|
124
|
+
TT.IR.value: indirect_refrigeration_service,
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _ensure_cogeneration_target(
|
|
129
|
+
zone: Zone,
|
|
130
|
+
*,
|
|
131
|
+
target_type: str,
|
|
132
|
+
refresh_args: dict | None,
|
|
133
|
+
compare_args: dict | None,
|
|
134
|
+
):
|
|
135
|
+
"""Ensure one compatible target family exists for the requested state."""
|
|
136
|
+
target = zone.targets.get(target_type)
|
|
137
|
+
if _target_matches_requested_state(
|
|
138
|
+
target,
|
|
139
|
+
args=compare_args,
|
|
140
|
+
state_ids=getattr(zone, "state_ids", None),
|
|
141
|
+
):
|
|
142
|
+
return target
|
|
143
|
+
|
|
144
|
+
refresh_service = _get_cogeneration_refresh_services().get(target_type)
|
|
145
|
+
if refresh_service is None:
|
|
146
|
+
return None
|
|
147
|
+
|
|
148
|
+
refresh_service(zone, refresh_args)
|
|
149
|
+
refreshed_target = zone.targets.get(target_type)
|
|
150
|
+
if _target_matches_requested_state(
|
|
151
|
+
refreshed_target,
|
|
152
|
+
args=compare_args,
|
|
153
|
+
state_ids=getattr(zone, "state_ids", None),
|
|
154
|
+
):
|
|
155
|
+
return refreshed_target
|
|
156
|
+
return None
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def _format_cogeneration_state_suffix(args: dict | None) -> str:
|
|
160
|
+
"""Render the selected state into cogeneration error messages."""
|
|
161
|
+
if not isinstance(args, dict):
|
|
162
|
+
return ""
|
|
163
|
+
if args.get("state_id") is not None:
|
|
164
|
+
return f" for state_id {str(args['state_id'])!r}"
|
|
165
|
+
if args.get("idx") is not None:
|
|
166
|
+
return f" for idx {int(args['idx'])}"
|
|
167
|
+
return ""
|
|
168
|
+
|
|
169
|
+
|
|
81
170
|
def data_preprocessing_service(
|
|
82
171
|
input_data: TargetInput,
|
|
83
172
|
project_name: str = "Site",
|
|
@@ -203,56 +292,45 @@ def indirect_refrigeration_service(zone: Zone, args: dict | None = None) -> Zone
|
|
|
203
292
|
|
|
204
293
|
|
|
205
294
|
def power_cogeneration_service(zone: Zone, args: dict | None = None) -> Zone:
|
|
206
|
-
"""Post-process
|
|
295
|
+
"""Post-process one compatible target in
|
|
296
|
+
TS -> IHP -> IR -> DHP -> DR -> DI order."""
|
|
207
297
|
_apply_zone_config_overrides(zone, args)
|
|
208
|
-
target_type = [
|
|
209
|
-
TT.IHP.value,
|
|
210
|
-
TT.IR.value,
|
|
211
|
-
TT.TS.value,
|
|
212
|
-
TT.DHP.value,
|
|
213
|
-
TT.DR.value,
|
|
214
|
-
TT.DI.value,
|
|
215
|
-
]
|
|
216
298
|
runtime_args = dict(args or {})
|
|
299
|
+
explicit_target_type = _normalize_cogeneration_base_target_type(
|
|
300
|
+
runtime_args.get("base_target_type")
|
|
301
|
+
)
|
|
217
302
|
idx, sid = _record_selected_state(zone, runtime_args)
|
|
218
303
|
runtime_args["idx"] = idx
|
|
219
304
|
if sid is not None:
|
|
220
305
|
runtime_args["state_id"] = sid
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
existing_target = zone.targets.get(tt)
|
|
239
|
-
if existing_target is None and not should_refresh_missing_target:
|
|
306
|
+
compare_args = dict(args or {}) if isinstance(args, dict) else {}
|
|
307
|
+
zone._selected_cogeneration_target_type = None
|
|
308
|
+
|
|
309
|
+
for target_type in _get_cogeneration_candidate_order(explicit_target_type):
|
|
310
|
+
target = _ensure_cogeneration_target(
|
|
311
|
+
zone,
|
|
312
|
+
target_type=target_type,
|
|
313
|
+
refresh_args=runtime_args,
|
|
314
|
+
compare_args=compare_args,
|
|
315
|
+
)
|
|
316
|
+
if target is None:
|
|
317
|
+
if explicit_target_type is not None:
|
|
318
|
+
raise RuntimeError(
|
|
319
|
+
"Cogeneration could not produce target "
|
|
320
|
+
f"{target_type!r} for zone {zone.name!r}"
|
|
321
|
+
f"{_format_cogeneration_state_suffix(runtime_args)}."
|
|
322
|
+
)
|
|
240
323
|
continue
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
get_power_cogeneration_above_pinch(zone.targets[tt], args=runtime_args)
|
|
252
|
-
else:
|
|
253
|
-
get_power_cogeneration_above_pinch(zone.targets[tt])
|
|
254
|
-
return zone
|
|
255
|
-
raise ValueError("Load data before running pinch analysis services.")
|
|
324
|
+
|
|
325
|
+
get_power_cogeneration_above_pinch(target, args=runtime_args)
|
|
326
|
+
zone._selected_cogeneration_target_type = target_type
|
|
327
|
+
return zone
|
|
328
|
+
|
|
329
|
+
raise RuntimeError(
|
|
330
|
+
"Cogeneration could not find a compatible target for zone "
|
|
331
|
+
f"{zone.name!r}{_format_cogeneration_state_suffix(runtime_args)} "
|
|
332
|
+
f"using implicit order {' -> '.join(_COGENERATION_TARGET_ORDER)}."
|
|
333
|
+
)
|
|
256
334
|
|
|
257
335
|
|
|
258
336
|
def area_cost_targeting_service(zone: Zone, args: dict | None = None) -> Zone:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: OpenPinch
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: An advanced pinch analysis and total site integration toolkit
|
|
5
5
|
Project-URL: Homepage, https://github.com/waikato-ahuora-smart-energy-systems/OpenPinch
|
|
6
6
|
Project-URL: Issues, https://github.com/waikato-ahuora-smart-energy-systems/OpenPinch/issues
|
openpinch-0.2.0/OpenPinch/services/power_cogeneration_analysis/power_cogeneration_analysis.py
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
"""Utility routines for estimating turbine cogeneration targets."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
6
|
-
|
|
7
|
-
import numpy as np
|
|
8
|
-
|
|
9
|
-
from ...lib.config import T_CRIT, Configuration, tol
|
|
10
|
-
from ...utils.miscellaneous import get_state_index
|
|
11
|
-
from ...utils.water_properties import psat_T
|
|
12
|
-
from ..power_cogeneration.unit_models.multi_stage_steam_turbine import (
|
|
13
|
-
MultiStageSteamTurbine,
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
if TYPE_CHECKING:
|
|
17
|
-
import numpy as np
|
|
18
|
-
|
|
19
|
-
from ...classes.stream import Stream
|
|
20
|
-
from ...classes.zone import Zone
|
|
21
|
-
|
|
22
|
-
__all__ = [
|
|
23
|
-
"get_power_cogeneration_above_pinch",
|
|
24
|
-
"get_power_cogeneration_below_pinch",
|
|
25
|
-
]
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def get_power_cogeneration_above_pinch(
|
|
29
|
-
zone: Zone,
|
|
30
|
-
args: dict | None = None,
|
|
31
|
-
) -> Zone:
|
|
32
|
-
"""Calculate the power cogeneration potential above pinch for a given zone."""
|
|
33
|
-
turbine_params = _prepare_turbine_parameters(zone.config)
|
|
34
|
-
idx, sid = get_state_index(
|
|
35
|
-
state_ids=getattr(zone, "state_ids", None),
|
|
36
|
-
args=args,
|
|
37
|
-
)
|
|
38
|
-
utility_data = _preprocess_utilities(zone, turbine_params, idx=idx)
|
|
39
|
-
if utility_data is None:
|
|
40
|
-
return zone
|
|
41
|
-
|
|
42
|
-
turbine = MultiStageSteamTurbine()
|
|
43
|
-
total_work, details = turbine.solve(
|
|
44
|
-
utility_data["stage_temperatures"],
|
|
45
|
-
utility_data["stage_heat_flows"],
|
|
46
|
-
mode="above_pinch",
|
|
47
|
-
T_in=turbine_params["T_in"],
|
|
48
|
-
P_in=turbine_params["P_in"],
|
|
49
|
-
model=turbine_params["model"],
|
|
50
|
-
min_eff=turbine_params["min_eff"],
|
|
51
|
-
load_frac=turbine_params["load_frac"],
|
|
52
|
-
mech_eff=turbine_params["mech_eff"],
|
|
53
|
-
is_high_p_cond_flash=turbine_params["is_high_p_cond_flash"],
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
zone.work_target = total_work
|
|
57
|
-
zone.turbine_efficiency_target = details["overall_efficiency"]
|
|
58
|
-
return zone
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def get_power_cogeneration_below_pinch(
|
|
62
|
-
temperatures: np.ndarray,
|
|
63
|
-
heat_flows: np.ndarray,
|
|
64
|
-
*,
|
|
65
|
-
zone_config: Configuration | None = None,
|
|
66
|
-
T_sink: float | None = None,
|
|
67
|
-
) -> tuple[float, dict]:
|
|
68
|
-
"""Solve a below Pinch turbine target against an environmental sink."""
|
|
69
|
-
zone_config = zone_config or Configuration()
|
|
70
|
-
turbine_params = _prepare_turbine_parameters(zone_config)
|
|
71
|
-
sink_temperature = zone_config.T_ENV if T_sink is None else float(T_sink)
|
|
72
|
-
|
|
73
|
-
turbine = MultiStageSteamTurbine()
|
|
74
|
-
return turbine.solve(
|
|
75
|
-
temperatures,
|
|
76
|
-
heat_flows,
|
|
77
|
-
mode="below_pinch",
|
|
78
|
-
T_sink=sink_temperature,
|
|
79
|
-
model=turbine_params["model"],
|
|
80
|
-
min_eff=turbine_params["min_eff"],
|
|
81
|
-
load_frac=turbine_params["load_frac"],
|
|
82
|
-
mech_eff=turbine_params["mech_eff"],
|
|
83
|
-
is_high_p_cond_flash=turbine_params["is_high_p_cond_flash"],
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
def _prepare_turbine_parameters(zone_config: Configuration) -> dict:
|
|
88
|
-
"""Load and sanitize turbine parameters from ``zone_config``."""
|
|
89
|
-
return {
|
|
90
|
-
"P_in": float(zone_config.TURB_P_IN),
|
|
91
|
-
"T_in": float(zone_config.TURB_T_IN),
|
|
92
|
-
"min_eff": float(zone_config.MIN_EFF),
|
|
93
|
-
"model": zone_config.TURB_MODEL,
|
|
94
|
-
"load_frac": min(max(float(zone_config.LOAD_FRACTION), 0.0), 1.0),
|
|
95
|
-
"mech_eff": min(max(float(zone_config.ETA_MECH), 0.0), 1.0),
|
|
96
|
-
"is_high_p_cond_flash": bool(zone_config.IS_HIGH_P_COND_FLASH),
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def _preprocess_utilities(
|
|
101
|
-
zone: Zone,
|
|
102
|
-
turbine_params: dict,
|
|
103
|
-
*,
|
|
104
|
-
idx: int | None = None,
|
|
105
|
-
) -> dict | None:
|
|
106
|
-
"""Translate hot-utility demands into turbine stage temperatures and duties."""
|
|
107
|
-
stage_temperatures: list[float] = []
|
|
108
|
-
stage_heat_flows: list[float] = []
|
|
109
|
-
source_indices: list[int] = []
|
|
110
|
-
|
|
111
|
-
u: Stream
|
|
112
|
-
for i, u in enumerate(zone.hot_utilities):
|
|
113
|
-
t_supply = float(u.t_supply[idx])
|
|
114
|
-
t_target = float(u.t_target[idx])
|
|
115
|
-
heat_flow = float(u.heat_flow[idx])
|
|
116
|
-
dt_cont_act = float(u.dt_cont_act[idx])
|
|
117
|
-
if t_supply >= T_CRIT or heat_flow <= tol:
|
|
118
|
-
continue
|
|
119
|
-
|
|
120
|
-
T_stage = (
|
|
121
|
-
t_target
|
|
122
|
-
if abs(t_supply - t_target) < 1.0 + tol
|
|
123
|
-
else t_target + dt_cont_act * 2
|
|
124
|
-
)
|
|
125
|
-
if turbine_params["P_in"] + tol < psat_T(T_stage):
|
|
126
|
-
continue
|
|
127
|
-
|
|
128
|
-
stage_temperatures.append(float(T_stage))
|
|
129
|
-
stage_heat_flows.append(float(heat_flow))
|
|
130
|
-
source_indices.append(i)
|
|
131
|
-
|
|
132
|
-
if not stage_temperatures:
|
|
133
|
-
return None
|
|
134
|
-
|
|
135
|
-
return {
|
|
136
|
-
"stage_temperatures": np.asarray(stage_temperatures, dtype=float),
|
|
137
|
-
"stage_heat_flows": np.asarray(stage_heat_flows, dtype=float),
|
|
138
|
-
"source_indices": np.asarray(source_indices, dtype=int),
|
|
139
|
-
}
|
|
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
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/classes/_problem_table/_problem_table_constants.py
RENAMED
|
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
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/data/notebooks/02_total_site_targets_and_sugcc.ipynb
RENAMED
|
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
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/common/capital_cost_and_area_targeting.py
RENAMED
|
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
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/exergy_analysis/exergy_targeting_entry.py
RENAMED
|
File without changes
|
|
File without changes
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/common/__init__.py
RENAMED
|
File without changes
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/common/encoding.py
RENAMED
|
File without changes
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/common/layout.py
RENAMED
|
File without changes
|
|
File without changes
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/common/preprocessing.py
RENAMED
|
File without changes
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/common/shared.py
RENAMED
|
File without changes
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/cycles/brayton.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/heat_pump_integration/unit_models/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/indirect_heat_integration/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/input_data_processing/_canonicalization.py
RENAMED
|
File without changes
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/input_data_processing/_utility_preparation.py
RENAMED
|
File without changes
|
{openpinch-0.2.0 → openpinch-0.2.1}/OpenPinch/services/input_data_processing/data_preparation.py
RENAMED
|
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
|