OpenPinch 0.2.4__tar.gz → 0.2.8__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.4 → openpinch-0.2.8}/OpenPinch/classes/_problem/_plot_accessor.py +24 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_problem/_target_dispatch.py +2 -37
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/pinch_problem.py +1 -1
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/value.py +2 -1
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/notebooks/01_basic_pinch_and_dtcont_sensitivity.ipynb +68 -19
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/notebooks/02_total_site_targets_and_sugcc.ipynb +19 -12
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/notebooks/03_carnot_hpr_comparison.ipynb +64 -56
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/notebooks/05_schema_service_and_output_workflows.ipynb +0 -9
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/notebooks/07_vapour_compression_mvr_cascade_hpr.ipynb +18 -14
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/sample_cases/chocolate_factory.json +1 -1
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/config.py +17 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/config_metadata.py +1 -1
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/enums.py +4 -3
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/schemas/hpr.py +8 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/common/graph_data.py +23 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/components/__init__.py +1 -1
- {openpinch-0.2.4/OpenPinch/classes → openpinch-0.2.8/OpenPinch/services/components}/process_components.py +2 -2
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/components/process_mvr.py +4 -2
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/common/__init__.py +12 -0
- openpinch-0.2.8/OpenPinch/services/heat_pump_integration/common/encoding.py +221 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/common/layout.py +52 -22
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/common/postprocessing.py +46 -15
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/common/shared.py +31 -9
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/heat_pump_and_refrigeration_entry.py +39 -24
- openpinch-0.2.8/OpenPinch/services/heat_pump_integration/targeting_services/__init__.py +29 -0
- openpinch-0.2.8/OpenPinch/services/heat_pump_integration/targeting_services/cascade_carnot.py +162 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/targeting_services/cascade_vapour_compression.py +104 -35
- openpinch-0.2.8/OpenPinch/services/heat_pump_integration/targeting_services/parallel_carnot.py +156 -0
- openpinch-0.2.4/OpenPinch/services/heat_pump_integration/targeting_services/multi_simple_vapour_compression.py → openpinch-0.2.8/OpenPinch/services/heat_pump_integration/targeting_services/parallel_vapour_compression.py +90 -34
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/targeting_services/vapour_compression_mvr.py +40 -52
- openpinch-0.2.8/OpenPinch/services/heat_pump_integration/unit_models/__init__.py +20 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/unit_models/brayton_heat_pump.py +7 -8
- openpinch-0.2.8/OpenPinch/services/heat_pump_integration/unit_models/carnot_cycles.py +470 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/unit_models/cascade_vapour_compression_cycle.py +161 -22
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/unit_models/mechanical_vapour_recompression_cycle.py +2 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/unit_models/parallel_vapour_compression_cycles.py +71 -11
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/unit_models/vapour_compression_cycle.py +4 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/unit_models/vapour_compression_mvr_cascade.py +56 -14
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/bb_optimisers/common.py +19 -1
- {openpinch-0.2.4 → openpinch-0.2.8}/PKG-INFO +1 -1
- {openpinch-0.2.4 → openpinch-0.2.8}/pyproject.toml +1 -1
- openpinch-0.2.4/OpenPinch/services/heat_pump_integration/common/encoding.py +0 -118
- openpinch-0.2.4/OpenPinch/services/heat_pump_integration/targeting_services/__init__.py +0 -29
- openpinch-0.2.4/OpenPinch/services/heat_pump_integration/targeting_services/multi_simple_carnot.py +0 -230
- openpinch-0.2.4/OpenPinch/services/heat_pump_integration/targeting_services/multi_temperature_carnot.py +0 -299
- openpinch-0.2.4/OpenPinch/services/heat_pump_integration/unit_models/__init__.py +0 -9
- {openpinch-0.2.4 → openpinch-0.2.8}/.gitignore +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/LICENSE +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/__main__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_problem/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_problem/_component_accessor.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_problem/_loading.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_problem/_output.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_problem/_result_extraction.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_problem/_target_accessor.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_problem/_validation.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_problem_table/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_problem_table/_problem_table_constants.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_stream_collection/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_stream_collection/_helpers.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_stream_collection/_numeric_view.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_workspace/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_workspace/execution.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_workspace/payloads.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/_workspace/views.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/pinch_workspace.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/problem_table.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/stream.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/stream_collection.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/classes/zone.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/notebooks/04_multistate_targeting_and_state_comparison.ipynb +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/notebooks/06_energy_transfer_analysis.ipynb +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/notebooks/08_direct_gas_stream_mvr.ipynb +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/notebooks/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/sample_cases/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/sample_cases/basic_pinch.json +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/sample_cases/crude_preheat_train.json +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/sample_cases/crude_preheat_train_multistate.json +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/sample_cases/heat_pump_targeting.json +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/sample_cases/pulp_mill.json +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/sample_cases/zonal_site.json +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/sample_cases/zonal_site_multistate.json +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/coolprop_fluids.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/problem_table_types.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/schemas/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/schemas/common.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/schemas/graphs.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/schemas/io.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/schemas/report_units.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/schemas/reporting.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/schemas/targets.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/schemas/turbine.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/schemas/workspace.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/lib/unit_system.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/main.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/resources.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/common/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/common/capital_cost_and_area_targeting.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/common/gcc_manipulation.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/common/graph_series_meta.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/common/miscellaneous.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/common/problem_table_analysis.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/common/service_orchestration.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/common/temperature_driving_force.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/common/utility_targeting.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/components/direct_mvr/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/components/direct_mvr/direct_gas_mvr.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/direct_heat_integration/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/direct_heat_integration/direct_integration_entry.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/energy_transfer_analysis/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/energy_transfer_analysis/energy_transfer_entry.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/exergy_analysis/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/exergy_analysis/exergy_targeting_entry.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/common/preprocessing.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/heat_pump_integration/targeting_services/brayton.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/indirect_heat_integration/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/indirect_heat_integration/indirect_integration_entry.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/input_data_processing/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/input_data_processing/_canonicalization.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/input_data_processing/_utility_preparation.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/input_data_processing/data_preparation.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/power_cogeneration/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/power_cogeneration/power_cogeneration_entry.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/power_cogeneration/unit_models/multi_stage_steam_turbine.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/services/services_entry.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/streamlit_webviewer/web_graphing.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/_tabular_input.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/bb_optimisers/__init__.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/bb_optimisers/bayesian_optimisation.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/bb_optimisers/cmaes.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/bb_optimisers/dual_annealing.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/bb_optimisers/rbf_surrogate.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/blackbox_minimisers.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/costing.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/csv_to_json.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/decorators.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/export.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/heat_exchanger.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/input_validation.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/plots.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/stream_linearisation.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/value_resolution.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/water_properties.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/utils/wkbook_to_json.py +0 -0
- {openpinch-0.2.4 → openpinch-0.2.8}/README.md +0 -0
|
@@ -53,6 +53,13 @@ _GRAPH_TYPE_ALIASES = {
|
|
|
53
53
|
"net_load curves": GT.NLP.value,
|
|
54
54
|
"net_load profile": GT.NLP.value,
|
|
55
55
|
"net_load profiles": GT.NLP.value,
|
|
56
|
+
"nlp_hp": GT.NLP_HP.value,
|
|
57
|
+
"net load with heat pump": GT.NLP_HP.value,
|
|
58
|
+
"net load curve with heat pump": GT.NLP_HP.value,
|
|
59
|
+
"net load curves with heat pump": GT.NLP_HP.value,
|
|
60
|
+
"net load profile with heat pump": GT.NLP_HP.value,
|
|
61
|
+
"net load profiles with heat pump": GT.NLP_HP.value,
|
|
62
|
+
"net_load_with_heat_pump": GT.NLP_HP.value,
|
|
56
63
|
"nlp_x": GT.NLP_X.value,
|
|
57
64
|
"exergy nlp": GT.NLP_X.value,
|
|
58
65
|
"exergetic net load profiles": GT.NLP_X.value,
|
|
@@ -362,6 +369,23 @@ class _PlotAccessor:
|
|
|
362
369
|
return_graph_data=return_graph_data,
|
|
363
370
|
)
|
|
364
371
|
|
|
372
|
+
def net_load_profiles_with_heat_pump(
|
|
373
|
+
self,
|
|
374
|
+
*,
|
|
375
|
+
zone_name: Optional[str] = None,
|
|
376
|
+
index: float = 0,
|
|
377
|
+
show: bool = False,
|
|
378
|
+
return_graph_data: bool = False,
|
|
379
|
+
):
|
|
380
|
+
"""Return the first matching net load profile (with Heat Pump) or figure."""
|
|
381
|
+
return self._plot_graph(
|
|
382
|
+
zone_name=zone_name,
|
|
383
|
+
graph_type=GT.NLP_HP.value,
|
|
384
|
+
index=index,
|
|
385
|
+
show=show,
|
|
386
|
+
return_graph_data=return_graph_data,
|
|
387
|
+
)
|
|
388
|
+
|
|
365
389
|
def exergetic_net_load_profiles(
|
|
366
390
|
self,
|
|
367
391
|
*,
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
import inspect
|
|
6
|
-
from functools import lru_cache
|
|
7
5
|
from typing import Callable
|
|
8
6
|
|
|
9
7
|
from ...lib.enums import ZT
|
|
@@ -31,39 +29,12 @@ def run_targeting_for_zone_and_subzones(
|
|
|
31
29
|
|
|
32
30
|
|
|
33
31
|
def _invoke_service(service_func: Callable, zone: Zone, args: dict | None = None):
|
|
34
|
-
"""Call a targeting callback with
|
|
32
|
+
"""Call a targeting callback with runtime options."""
|
|
35
33
|
if not callable(service_func):
|
|
36
34
|
return None
|
|
37
|
-
|
|
38
|
-
if args is None or not _service_accepts_args(service_func):
|
|
39
|
-
return service_func(zone)
|
|
40
|
-
|
|
41
35
|
return service_func(zone, args)
|
|
42
36
|
|
|
43
37
|
|
|
44
|
-
@lru_cache(maxsize=64)
|
|
45
|
-
def _service_accepts_args(service_func: Callable) -> bool:
|
|
46
|
-
"""Return whether a service accepts a second positional ``args`` parameter."""
|
|
47
|
-
try:
|
|
48
|
-
signature = inspect.signature(service_func)
|
|
49
|
-
except TypeError, ValueError:
|
|
50
|
-
return True
|
|
51
|
-
|
|
52
|
-
params = list(signature.parameters.values())
|
|
53
|
-
if any(param.kind == inspect.Parameter.VAR_POSITIONAL for param in params):
|
|
54
|
-
return True
|
|
55
|
-
positional_params = [
|
|
56
|
-
param
|
|
57
|
-
for param in params
|
|
58
|
-
if param.kind
|
|
59
|
-
in (
|
|
60
|
-
inspect.Parameter.POSITIONAL_ONLY,
|
|
61
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
62
|
-
)
|
|
63
|
-
]
|
|
64
|
-
return len(positional_params) >= 2
|
|
65
|
-
|
|
66
|
-
|
|
67
38
|
def _invoke_target_handler(
|
|
68
39
|
handler: Callable,
|
|
69
40
|
zone: Zone,
|
|
@@ -71,13 +42,7 @@ def _invoke_target_handler(
|
|
|
71
42
|
indirect_service_func: Callable = None,
|
|
72
43
|
args: dict | None = None,
|
|
73
44
|
):
|
|
74
|
-
"""Call nested target handlers
|
|
75
|
-
if args is None:
|
|
76
|
-
return handler(
|
|
77
|
-
zone,
|
|
78
|
-
direct_service_func=direct_service_func,
|
|
79
|
-
indirect_service_func=indirect_service_func,
|
|
80
|
-
)
|
|
45
|
+
"""Call nested target handlers with runtime options."""
|
|
81
46
|
return handler(
|
|
82
47
|
zone,
|
|
83
48
|
direct_service_func=direct_service_func,
|
|
@@ -8,7 +8,7 @@ from functools import lru_cache
|
|
|
8
8
|
from typing import Any
|
|
9
9
|
|
|
10
10
|
import numpy as np
|
|
11
|
-
from pint import UnitRegistry
|
|
11
|
+
from pint import UnitRegistry, set_application_registry
|
|
12
12
|
from pint.errors import DimensionalityError
|
|
13
13
|
|
|
14
14
|
ureg = UnitRegistry()
|
|
@@ -20,6 +20,7 @@ try:
|
|
|
20
20
|
ureg.define("NZD = [currency]")
|
|
21
21
|
except Exception:
|
|
22
22
|
pass
|
|
23
|
+
set_application_registry(ureg)
|
|
23
24
|
Q_ = ureg.Quantity # type: ignore
|
|
24
25
|
|
|
25
26
|
_SERIALIZED_SCALAR_KEYS = {"value", "unit"}
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"outputs": [],
|
|
27
27
|
"source": [
|
|
28
28
|
"import pandas as pd\n",
|
|
29
|
+
"import plotly.express as px\n",
|
|
29
30
|
"\n",
|
|
30
31
|
"from IPython.display import display\n",
|
|
31
32
|
"\n",
|
|
@@ -132,7 +133,7 @@
|
|
|
132
133
|
"metadata": {},
|
|
133
134
|
"source": [
|
|
134
135
|
"## Named `dt_cont` sensitivity with `PinchWorkspace`\n",
|
|
135
|
-
"Once the single-case picture is clear, `PinchWorkspace` becomes the right tool for named baseline-versus-variant studies. Here the baseline stays intact while
|
|
136
|
+
"Once the single-case picture is clear, `PinchWorkspace` becomes the right tool for named baseline-versus-variant studies. Here the baseline stays intact while copied cases sweep a wide range of active `dt_cont` assumptions through `set_dt_cont_multiplier(...)`.\n"
|
|
136
137
|
]
|
|
137
138
|
},
|
|
138
139
|
{
|
|
@@ -147,31 +148,32 @@
|
|
|
147
148
|
" project_name=\"crude_preheat_train\",\n",
|
|
148
149
|
")\n",
|
|
149
150
|
"\n",
|
|
150
|
-
"
|
|
151
|
-
"
|
|
152
|
-
"workspace.copy_case(\"baseline\", \"wide_dt\", activate=False)\n",
|
|
153
|
-
"workspace.set_dt_cont_multiplier(2.0, case_name=\"wide_dt\")\n",
|
|
151
|
+
"target_name = \"crude_preheat_train/Direct Integration\"\n",
|
|
152
|
+
"dt_cont_multipliers = [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 7.5, 10.0]\n",
|
|
154
153
|
"\n",
|
|
155
154
|
"case_rows = []\n",
|
|
156
|
-
"for
|
|
157
|
-
"
|
|
158
|
-
"
|
|
159
|
-
"
|
|
160
|
-
"
|
|
161
|
-
"
|
|
155
|
+
"for multiplier in dt_cont_multipliers:\n",
|
|
156
|
+
" case_name = \"baseline\" if multiplier == 1.0 else f\"dt_cont_x{str(multiplier).replace('.', '_')}\"\n",
|
|
157
|
+
" if case_name != \"baseline\":\n",
|
|
158
|
+
" workspace.copy_case(\"baseline\", case_name, activate=False)\n",
|
|
159
|
+
" workspace.set_dt_cont_multiplier(multiplier, case_name=case_name)\n",
|
|
160
|
+
"\n",
|
|
161
|
+
" detailed_summary = workspace.summary_frame(case_name=case_name, detailed=True)\n",
|
|
162
|
+
" site_row = detailed_summary.loc[detailed_summary[\"Target\"] == target_name].iloc[0]\n",
|
|
162
163
|
" case_rows.append(\n",
|
|
163
164
|
" {\n",
|
|
164
165
|
" \"case\": case_name,\n",
|
|
165
166
|
" \"dt_cont_multiplier\": multiplier,\n",
|
|
166
|
-
" \"Hot Utility Target\": site_row[\"
|
|
167
|
-
" \"Cold Utility Target\": site_row[\"
|
|
168
|
-
" \"Heat Recovery\": site_row[\"
|
|
169
|
-
" \"Hot Pinch\": site_row[\"Hot Pinch\"],\n",
|
|
170
|
-
" \"Cold Pinch\": site_row[\"Cold Pinch\"],\n",
|
|
167
|
+
" \"Hot Utility Target / kW\": site_row[\"Qh (value)\"],\n",
|
|
168
|
+
" \"Cold Utility Target / kW\": site_row[\"Qc (value)\"],\n",
|
|
169
|
+
" \"Heat Recovery / kW\": site_row[\"Qr (value)\"],\n",
|
|
170
|
+
" \"Hot Pinch / degC\": site_row[\"Hot Pinch (value)\"],\n",
|
|
171
|
+
" \"Cold Pinch / degC\": site_row[\"Cold Pinch (value)\"],\n",
|
|
171
172
|
" }\n",
|
|
172
173
|
" )\n",
|
|
173
174
|
"\n",
|
|
174
|
-
"pd.DataFrame(case_rows).sort_values(\"dt_cont_multiplier\").reset_index(drop=True)\n"
|
|
175
|
+
"dt_cont_results = pd.DataFrame(case_rows).sort_values(\"dt_cont_multiplier\").reset_index(drop=True)\n",
|
|
176
|
+
"dt_cont_results\n"
|
|
175
177
|
]
|
|
176
178
|
},
|
|
177
179
|
{
|
|
@@ -181,15 +183,62 @@
|
|
|
181
183
|
"metadata": {},
|
|
182
184
|
"outputs": [],
|
|
183
185
|
"source": [
|
|
186
|
+
"selected_dt_cases = [\"dt_cont_x0_25\", \"dt_cont_x0_5\", \"dt_cont_x2_0\", \"dt_cont_x4_0\"]\n",
|
|
187
|
+
"\n",
|
|
184
188
|
"pd.concat(\n",
|
|
185
189
|
" [\n",
|
|
186
|
-
" workspace.compare_cases(\"baseline\", case_name
|
|
187
|
-
"
|
|
190
|
+
" workspace.compare_cases(\"baseline\", case_name, target_name=target_name)\n",
|
|
191
|
+
" .loc[[\"Change\"]]\n",
|
|
192
|
+
" .assign(case=case_name)\n",
|
|
193
|
+
" for case_name in selected_dt_cases\n",
|
|
188
194
|
" ],\n",
|
|
189
195
|
" axis=0,\n",
|
|
190
196
|
").reset_index(drop=True)\n"
|
|
191
197
|
]
|
|
192
198
|
},
|
|
199
|
+
{
|
|
200
|
+
"cell_type": "markdown",
|
|
201
|
+
"id": "dt-cont-plot-md",
|
|
202
|
+
"metadata": {},
|
|
203
|
+
"source": [
|
|
204
|
+
"## Plot the target response\n",
|
|
205
|
+
"Plotting the targets across the multiplier range makes the tradeoff visible: tighter approach temperatures reduce external utility demand, while wider approach temperatures increase hot and cold utility requirements and reduce recoverable heat.\n"
|
|
206
|
+
]
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"cell_type": "code",
|
|
210
|
+
"execution_count": null,
|
|
211
|
+
"id": "dt-cont-target-plot",
|
|
212
|
+
"metadata": {},
|
|
213
|
+
"outputs": [],
|
|
214
|
+
"source": [
|
|
215
|
+
"dt_cont_plot_data = dt_cont_results.melt(\n",
|
|
216
|
+
" id_vars=[\"dt_cont_multiplier\"],\n",
|
|
217
|
+
" value_vars=[\n",
|
|
218
|
+
" \"Hot Utility Target / kW\",\n",
|
|
219
|
+
" \"Cold Utility Target / kW\",\n",
|
|
220
|
+
" \"Heat Recovery / kW\",\n",
|
|
221
|
+
" ],\n",
|
|
222
|
+
" var_name=\"Target\",\n",
|
|
223
|
+
" value_name=\"Heat Flow / kW\",\n",
|
|
224
|
+
")\n",
|
|
225
|
+
"\n",
|
|
226
|
+
"fig = px.line(\n",
|
|
227
|
+
" dt_cont_plot_data,\n",
|
|
228
|
+
" x=\"dt_cont_multiplier\",\n",
|
|
229
|
+
" y=\"Heat Flow / kW\",\n",
|
|
230
|
+
" color=\"Target\",\n",
|
|
231
|
+
" markers=True,\n",
|
|
232
|
+
" title=\"Direct-integration targets across dt_cont multipliers\",\n",
|
|
233
|
+
")\n",
|
|
234
|
+
"fig.update_layout(\n",
|
|
235
|
+
" xaxis_title=\"dt_cont multiplier\",\n",
|
|
236
|
+
" yaxis_title=\"Heat Flow / kW\",\n",
|
|
237
|
+
" legend_title_text=\"Target\",\n",
|
|
238
|
+
")\n",
|
|
239
|
+
"fig\n"
|
|
240
|
+
]
|
|
241
|
+
},
|
|
193
242
|
{
|
|
194
243
|
"cell_type": "markdown",
|
|
195
244
|
"id": "forward-reference",
|
{openpinch-0.2.4 → openpinch-0.2.8}/OpenPinch/data/notebooks/02_total_site_targets_and_sugcc.ipynb
RENAMED
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"baseline = workspace.use_case(\"baseline\")\n",
|
|
45
45
|
"baseline.target()\n",
|
|
46
46
|
"summary = baseline.summary_frame()\n",
|
|
47
|
+
"detailed_summary = baseline.summary_frame(detailed=True)\n",
|
|
47
48
|
"catalog = baseline.plot.catalog()\n",
|
|
48
49
|
"\n",
|
|
49
50
|
"{\n",
|
|
@@ -105,20 +106,20 @@
|
|
|
105
106
|
"metadata": {},
|
|
106
107
|
"outputs": [],
|
|
107
108
|
"source": [
|
|
108
|
-
"scope_index =
|
|
109
|
+
"scope_index = detailed_summary.set_index(\"Target\")\n",
|
|
109
110
|
"pd.DataFrame(\n",
|
|
110
111
|
" [\n",
|
|
111
112
|
" {\n",
|
|
112
113
|
" \"Comparison\": \"Total Process - Direct\",\n",
|
|
113
|
-
" \"Hot Utility Delta\": scope_index.loc[\"Total Process Target\", \"
|
|
114
|
-
" \"Cold Utility Delta\": scope_index.loc[\"Total Process Target\", \"
|
|
115
|
-
" \"Heat Recovery Delta\": scope_index.loc[\"Total Process Target\", \"
|
|
114
|
+
" \"Hot Utility Delta\": scope_index.loc[\"Site/Total Process Target\", \"Qh (value)\"] - scope_index.loc[\"Site/Direct Integration\", \"Qh (value)\"],\n",
|
|
115
|
+
" \"Cold Utility Delta\": scope_index.loc[\"Site/Total Process Target\", \"Qc (value)\"] - scope_index.loc[\"Site/Direct Integration\", \"Qc (value)\"],\n",
|
|
116
|
+
" \"Heat Recovery Delta\": scope_index.loc[\"Site/Total Process Target\", \"Qr (value)\"] - scope_index.loc[\"Site/Direct Integration\", \"Qr (value)\"],\n",
|
|
116
117
|
" },\n",
|
|
117
118
|
" {\n",
|
|
118
119
|
" \"Comparison\": \"Total Site - Direct\",\n",
|
|
119
|
-
" \"Hot Utility Delta\": scope_index.loc[\"Total Site Target\", \"
|
|
120
|
-
" \"Cold Utility Delta\": scope_index.loc[\"Total Site Target\", \"
|
|
121
|
-
" \"Heat Recovery Delta\": scope_index.loc[\"Total Site Target\", \"
|
|
120
|
+
" \"Hot Utility Delta\": scope_index.loc[\"Site/Total Site Target\", \"Qh (value)\"] - scope_index.loc[\"Site/Direct Integration\", \"Qh (value)\"],\n",
|
|
121
|
+
" \"Cold Utility Delta\": scope_index.loc[\"Site/Total Site Target\", \"Qc (value)\"] - scope_index.loc[\"Site/Direct Integration\", \"Qc (value)\"],\n",
|
|
122
|
+
" \"Heat Recovery Delta\": scope_index.loc[\"Site/Total Site Target\", \"Qr (value)\"] - scope_index.loc[\"Site/Direct Integration\", \"Qr (value)\"],\n",
|
|
122
123
|
" },\n",
|
|
123
124
|
" ]\n",
|
|
124
125
|
")\n"
|
|
@@ -140,10 +141,16 @@
|
|
|
140
141
|
"metadata": {},
|
|
141
142
|
"outputs": [],
|
|
142
143
|
"source": [
|
|
143
|
-
"zone_rows =
|
|
144
|
-
"
|
|
145
|
-
" [\"Target\", \"
|
|
146
|
-
"].
|
|
144
|
+
"zone_rows = detailed_summary.loc[\n",
|
|
145
|
+
" detailed_summary[\"Target\"].str.endswith(\"/Direct Integration\") & (detailed_summary[\"Target\"] != \"Site/Direct Integration\"),\n",
|
|
146
|
+
" [\"Target\", \"Qh (value)\", \"Qc (value)\", \"Qr (value)\"],\n",
|
|
147
|
+
"].rename(\n",
|
|
148
|
+
" columns={\n",
|
|
149
|
+
" \"Qh (value)\": \"Hot Utility Target\",\n",
|
|
150
|
+
" \"Qc (value)\": \"Cold Utility Target\",\n",
|
|
151
|
+
" \"Qr (value)\": \"Heat Recovery\",\n",
|
|
152
|
+
" }\n",
|
|
153
|
+
").copy()\n",
|
|
147
154
|
"zone_rows[\"Zone\"] = zone_rows[\"Target\"].str.replace(\"/Direct Integration\", \"\", regex=False)\n",
|
|
148
155
|
"\n",
|
|
149
156
|
"leader_tables = []\n",
|
|
@@ -302,7 +309,7 @@
|
|
|
302
309
|
" \"Hot Utility Target\": (cogeneration_target.hot_utility_target),\n",
|
|
303
310
|
" \"Cold Utility Target\": (cogeneration_target.cold_utility_target),\n",
|
|
304
311
|
" \"Heat Recovery\": (cogeneration_target.heat_recovery_target),\n",
|
|
305
|
-
" \"Power Cogeneration Target\": get_scalar_value.work_target),\n",
|
|
312
|
+
" \"Power Cogeneration Target\": get_scalar_value(cogeneration_target.work_target),\n",
|
|
306
313
|
" \"Turbine Efficiency Target\": (cogeneration_target.turbine_efficiency_target),\n",
|
|
307
314
|
" },\n",
|
|
308
315
|
" ]\n",
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"metadata": {},
|
|
7
7
|
"source": [
|
|
8
8
|
"# Carnot HPR Comparison\n",
|
|
9
|
-
"This notebook uses the packaged `chocolate_factory.json` case to compare four advanced workflow families on the public `problem.target.*` and `problem.plot.*` surfaces: direct heat pump, indirect heat pump, direct refrigeration, and indirect refrigeration
|
|
9
|
+
"This notebook uses the packaged `chocolate_factory.json` case to compare four advanced workflow families on the public `problem.target.*` and `problem.plot.*` surfaces: direct heat pump, indirect heat pump, direct refrigeration, and indirect refrigeration. It uses the current `HPRcycle.CascadeCarnot` option for broad screening; use `HPRcycle.ParallelCarnot` when you want explicit staged Carnot cycles."
|
|
10
10
|
]
|
|
11
11
|
},
|
|
12
12
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"metadata": {},
|
|
16
16
|
"source": [
|
|
17
17
|
"## Case context\n",
|
|
18
|
-
"`chocolate_factory.json` is a realistic multi-zone plant case with enough structure to support HPR screening across multiple load fractions. `PinchWorkspace` keeps the study bundle organized, while each named case still behaves like a real `PinchProblem
|
|
18
|
+
"`chocolate_factory.json` is a realistic multi-zone plant case with enough structure to support HPR screening across multiple load fractions. `PinchWorkspace` keeps the study bundle organized, while each named case still behaves like a real `PinchProblem`. The Carnot backends use base duty scales plus bounded split fractions internally, so trial optimiser points are clipped to process availability before cycle work is evaluated."
|
|
19
19
|
]
|
|
20
20
|
},
|
|
21
21
|
{
|
|
@@ -25,9 +25,6 @@
|
|
|
25
25
|
"metadata": {},
|
|
26
26
|
"outputs": [],
|
|
27
27
|
"source": [
|
|
28
|
-
"from pathlib import Path\n",
|
|
29
|
-
"from tempfile import TemporaryDirectory\n",
|
|
30
|
-
"\n",
|
|
31
28
|
"import pandas as pd\n",
|
|
32
29
|
"\n",
|
|
33
30
|
"from IPython.display import display\n",
|
|
@@ -41,7 +38,7 @@
|
|
|
41
38
|
" \"indirect_heat_pump\": \"Indirect Heat Pump\",\n",
|
|
42
39
|
" \"direct_refrigeration\": \"Direct Refrigeration\",\n",
|
|
43
40
|
" \"indirect_refrigeration\": \"Indirect Refrigeration\",\n",
|
|
44
|
-
"}
|
|
41
|
+
"}"
|
|
45
42
|
]
|
|
46
43
|
},
|
|
47
44
|
{
|
|
@@ -53,13 +50,15 @@
|
|
|
53
50
|
"source": [
|
|
54
51
|
"workspace = PinchWorkspace(source=\"chocolate_factory.json\", project_name=\"Site\")\n",
|
|
55
52
|
"load_fractions = [0.25, 0.5, 0.75, 1.0]\n",
|
|
53
|
+
"screening_cycle = HPRcycle.CascadeCarnot\n",
|
|
54
|
+
"staged_carnot_cycle = HPRcycle.ParallelCarnot\n",
|
|
56
55
|
"\n",
|
|
57
56
|
"for load_fraction in load_fractions:\n",
|
|
58
57
|
" load_case_name = f\"load_{int(load_fraction * 100):03d}\"\n",
|
|
59
58
|
" load_case = workspace.copy_case(\"baseline\", load_case_name, activate=False)\n",
|
|
60
59
|
" load_case.update_options(\n",
|
|
61
60
|
" {\n",
|
|
62
|
-
" \"HPR_TYPE\":
|
|
61
|
+
" \"HPR_TYPE\": screening_cycle.value,\n",
|
|
63
62
|
" \"HPR_LOAD_VALUE\": load_fraction,\n",
|
|
64
63
|
" \"MAX_HP_MULTISTART\": 10,\n",
|
|
65
64
|
" \"N_COND\": 3,\n",
|
|
@@ -75,6 +74,8 @@
|
|
|
75
74
|
" )\n",
|
|
76
75
|
"\n",
|
|
77
76
|
"{\n",
|
|
77
|
+
" \"screening_cycle\": screening_cycle.value,\n",
|
|
78
|
+
" \"staged_carnot_alternative\": staged_carnot_cycle.value,\n",
|
|
78
79
|
" \"case_count\": len(workspace.list_cases()),\n",
|
|
79
80
|
" \"example_cases\": workspace.list_cases()[:8],\n",
|
|
80
81
|
"}\n"
|
|
@@ -121,10 +122,14 @@
|
|
|
121
122
|
"direct_hp_target = profile_problem.target.direct_heat_pump()\n",
|
|
122
123
|
"\n",
|
|
123
124
|
"print({\"direct_heat_pump_cop\": direct_hp_target.hpr_cop})\n",
|
|
124
|
-
"display(
|
|
125
|
+
"display(\n",
|
|
126
|
+
" profile_problem.plot.net_load_profiles_with_heat_pump(\n",
|
|
127
|
+
" zone_name=\"Direct Heat Pump\",\n",
|
|
128
|
+
" )\n",
|
|
129
|
+
")\n",
|
|
125
130
|
"display(\n",
|
|
126
131
|
" profile_problem.plot.grand_composite_curve_with_heat_pump(\n",
|
|
127
|
-
" zone_name=\"Direct Heat Pump\"
|
|
132
|
+
" zone_name=\"Direct Heat Pump\",\n",
|
|
128
133
|
" )\n",
|
|
129
134
|
")\n"
|
|
130
135
|
]
|
|
@@ -191,22 +196,43 @@
|
|
|
191
196
|
" for workflow_name, workflow_label in WORKFLOW_LABELS.items():\n",
|
|
192
197
|
" case_name = f\"load_{int(load_fraction * 100):03d}__{workflow_name}\"\n",
|
|
193
198
|
" problem = workspace.case(case_name)\n",
|
|
194
|
-
"
|
|
195
|
-
"
|
|
196
|
-
"
|
|
197
|
-
"
|
|
198
|
-
"
|
|
199
|
-
" \
|
|
200
|
-
"
|
|
201
|
-
"
|
|
202
|
-
"
|
|
203
|
-
"
|
|
204
|
-
"
|
|
205
|
-
"
|
|
206
|
-
"
|
|
207
|
-
"
|
|
208
|
-
"
|
|
209
|
-
"
|
|
199
|
+
" try:\n",
|
|
200
|
+
" if workflow_name.startswith(\"indirect\"):\n",
|
|
201
|
+
" problem.target()\n",
|
|
202
|
+
" target = getattr(problem.target, workflow_name)()\n",
|
|
203
|
+
" rows.append(\n",
|
|
204
|
+
" {\n",
|
|
205
|
+
" \"load fraction\": load_fraction,\n",
|
|
206
|
+
" \"workflow\": workflow_label,\n",
|
|
207
|
+
" \"case\": case_name,\n",
|
|
208
|
+
" \"target\": target.name,\n",
|
|
209
|
+
" \"Qh\": get_scalar_value(getattr(target, \"Qh\", None)),\n",
|
|
210
|
+
" \"Qc\": get_scalar_value(getattr(target, \"Qc\", None)),\n",
|
|
211
|
+
" \"Qr\": get_scalar_value(getattr(target, \"Qr\", None)),\n",
|
|
212
|
+
" \"hpr_work\": get_scalar_value(getattr(target, \"hpr_work\", None)),\n",
|
|
213
|
+
" \"hpr_cop\": get_scalar_value(getattr(target, \"hpr_cop\", None)),\n",
|
|
214
|
+
" \"hpr_success\": getattr(target, \"hpr_success\", None),\n",
|
|
215
|
+
" \"graph_count\": len(problem.plot.catalog()),\n",
|
|
216
|
+
" \"error\": None,\n",
|
|
217
|
+
" }\n",
|
|
218
|
+
" )\n",
|
|
219
|
+
" except Exception as exc:\n",
|
|
220
|
+
" rows.append(\n",
|
|
221
|
+
" {\n",
|
|
222
|
+
" \"load fraction\": load_fraction,\n",
|
|
223
|
+
" \"workflow\": workflow_label,\n",
|
|
224
|
+
" \"case\": case_name,\n",
|
|
225
|
+
" \"target\": None,\n",
|
|
226
|
+
" \"Qh\": None,\n",
|
|
227
|
+
" \"Qc\": None,\n",
|
|
228
|
+
" \"Qr\": None,\n",
|
|
229
|
+
" \"hpr_work\": None,\n",
|
|
230
|
+
" \"hpr_cop\": None,\n",
|
|
231
|
+
" \"hpr_success\": False,\n",
|
|
232
|
+
" \"graph_count\": len(problem.plot.catalog()),\n",
|
|
233
|
+
" \"error\": f\"{type(exc).__name__}: {exc}\",\n",
|
|
234
|
+
" }\n",
|
|
235
|
+
" )\n",
|
|
210
236
|
"\n",
|
|
211
237
|
"comparison = pd.DataFrame(rows)\n",
|
|
212
238
|
"comparison\n"
|
|
@@ -232,7 +258,18 @@
|
|
|
232
258
|
"for workflow_name, workflow_label in WORKFLOW_LABELS.items():\n",
|
|
233
259
|
" case_name = f\"load_100__{workflow_name}\"\n",
|
|
234
260
|
" problem = workspace.case(case_name)\n",
|
|
235
|
-
"
|
|
261
|
+
" comparison_row = comparison.loc[comparison[\"case\"] == case_name].iloc[0]\n",
|
|
262
|
+
" if comparison_row[\"error\"] is not None:\n",
|
|
263
|
+
" graph_families.append(\n",
|
|
264
|
+
" {\n",
|
|
265
|
+
" \"workflow\": workflow_label,\n",
|
|
266
|
+
" \"target\": case_name,\n",
|
|
267
|
+
" \"graph families\": None,\n",
|
|
268
|
+
" \"graph count\": comparison_row[\"graph_count\"],\n",
|
|
269
|
+
" \"status\": comparison_row[\"error\"],\n",
|
|
270
|
+
" }\n",
|
|
271
|
+
" )\n",
|
|
272
|
+
" continue\n",
|
|
236
273
|
" catalog = problem.plot.catalog()\n",
|
|
237
274
|
" graph_families.append(\n",
|
|
238
275
|
" {\n",
|
|
@@ -240,42 +277,13 @@
|
|
|
240
277
|
" \"target\": case_name,\n",
|
|
241
278
|
" \"graph families\": \", \".join(sorted(catalog[\"Graph Type\"].unique())),\n",
|
|
242
279
|
" \"graph count\": len(catalog),\n",
|
|
280
|
+
" \"status\": \"ok\",\n",
|
|
243
281
|
" }\n",
|
|
244
282
|
" )\n",
|
|
245
283
|
"\n",
|
|
246
284
|
"pd.DataFrame(graph_families)\n"
|
|
247
285
|
]
|
|
248
286
|
},
|
|
249
|
-
{
|
|
250
|
-
"cell_type": "markdown",
|
|
251
|
-
"id": "bundle-md",
|
|
252
|
-
"metadata": {},
|
|
253
|
-
"source": [
|
|
254
|
-
"## Save and reload the study bundle\n",
|
|
255
|
-
"This is useful when a multi-case HPR study becomes a reusable engineering artifact rather than a one-off notebook session.\n"
|
|
256
|
-
]
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
"cell_type": "code",
|
|
260
|
-
"execution_count": null,
|
|
261
|
-
"id": "bundle",
|
|
262
|
-
"metadata": {},
|
|
263
|
-
"outputs": [],
|
|
264
|
-
"source": [
|
|
265
|
-
"bundle_workspace = TemporaryDirectory()\n",
|
|
266
|
-
"bundle_path = Path(bundle_workspace.name) / \"chocolate_factory_hpr_workspace.json\"\n",
|
|
267
|
-
"workspace.save_bundle(bundle_path)\n",
|
|
268
|
-
"reloaded = PinchWorkspace.load_bundle(bundle_path)\n",
|
|
269
|
-
"\n",
|
|
270
|
-
"{\n",
|
|
271
|
-
" \"bundle_path\": str(bundle_path),\n",
|
|
272
|
-
" \"case_count\": len(reloaded.list_cases()),\n",
|
|
273
|
-
" \"sample_heat_pump_cases\": [\n",
|
|
274
|
-
" name for name in reloaded.list_cases() if name.endswith(\"__direct_heat_pump\")\n",
|
|
275
|
-
" ][:3],\n",
|
|
276
|
-
"}\n"
|
|
277
|
-
]
|
|
278
|
-
},
|
|
279
287
|
{
|
|
280
288
|
"cell_type": "markdown",
|
|
281
289
|
"id": "interpretation",
|
|
@@ -249,15 +249,6 @@
|
|
|
249
249
|
" \"reloaded_baseline_status\": reloaded.solve_variant(\"baseline\").status,\n",
|
|
250
250
|
"}\n"
|
|
251
251
|
]
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
"cell_type": "markdown",
|
|
255
|
-
"id": "dashboard-md",
|
|
256
|
-
"metadata": {},
|
|
257
|
-
"source": [
|
|
258
|
-
"## Next step: `show_dashboard()`\n",
|
|
259
|
-
"After a case is solved, `problem.show_dashboard()` is the next step when you want the Streamlit UI. This notebook does not execute it because launching the dashboard is outside the scope of a packaged, output-free teaching asset.\n"
|
|
260
|
-
]
|
|
261
252
|
}
|
|
262
253
|
],
|
|
263
254
|
"metadata": {
|