OpenPinch 0.8.2__tar.gz → 0.8.3__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.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/README.md +2 -2
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/README.md +1 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/executor.py +8 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/README.md +6 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/README.md +5 -1
- openpinch-0.8.3/OpenPinch/analysis/heat_pumps/common/compressor_efficiency.py +136 -0
- openpinch-0.8.3/OpenPinch/analysis/heat_pumps/common/load_kinks.py +127 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/preprocessing.py +21 -4
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/README.md +4 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/cascade_vapour_compression_cycle.py +4 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/mechanical_vapour_recompression_cycle.py +10 -3
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/parallel_vapour_compression_cycles.py +5 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/vapour_compression_cycle.py +57 -7
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/vapour_compression_mvr_cascade.py +12 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/README.md +4 -4
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/generation.py +4 -2
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/target_basis.py +9 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/target_records.py +45 -3
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/targeting.py +6 -0
- openpinch-0.8.3/OpenPinch/analysis/heat_pumps/refrigerant_screen.py +178 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/README.md +2 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/cascade_vapour_compression.py +6 -3
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/parallel_vapour_compression.py +1 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/vapour_compression_mvr.py +2 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/README.md +7 -3
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/accessors/README.md +5 -4
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/accessors/target.py +73 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/README.md +2 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/catalog.py +7 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/heat_recovery_dt_min.py +2 -1
- openpinch-0.8.3/OpenPinch/application/hpr_load_kinks.py +182 -0
- openpinch-0.8.3/OpenPinch/application/hpr_refrigerant_screen.py +155 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/workspace.py +34 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/README.md +7 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/hpr.py +6 -2
- openpinch-0.8.3/OpenPinch/contracts/hpr_load_kinks.py +133 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/hpr_performance_map.py +8 -2
- openpinch-0.8.3/OpenPinch/contracts/hpr_refrigerant_screen.py +115 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/hpr_performance_map/heat-pump-1.0.json +1 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/hpr_performance_map/refrigeration-1.0.json +1 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/hpr_performance_map/schema-1.0.json +7 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/schema.py +4 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/units.py +28 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/README.md +4 -2
- openpinch-0.8.3/OpenPinch/domain/compressor_model.py +35 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/configuration.py +12 -6
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/configuration_fields.py +30 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/fluids.py +24 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/configuration_text.py +39 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/README.md +1 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/specialist.py +4 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/06_multiperiod_heat_integration.ipynb +8 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/08_carnot_heat_pump_and_refrigeration.ipynb +92 -13
- {openpinch-0.8.2 → openpinch-0.8.3}/PKG-INFO +1 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/pyproject.toml +1 -1
- {openpinch-0.8.2 → openpinch-0.8.3}/.gitignore +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/LICENSE +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/__main__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/csv.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/file_exports.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/json.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/problem_sources.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/records.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/tabular.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/workbook.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/workspace_bundles.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/optional_dependencies.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/economics.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/cascade.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/diagram.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/selection.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/serialization.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/service.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/exergy/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/exergy/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/exergy/service.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/composite.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/grand_composite.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/metadata.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/primitives.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/service.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/specifications.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/context.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/controllability.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/duty_optimisation.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/errors.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/fake_executor.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/fallbacks.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/pathways.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/settings.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/task_builders.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/metadata.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/period_state.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/recovery.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/segment_area.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/service.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/utility.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/indexing.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/alpha.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/approach.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/area.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/costing.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/execution.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/parameters.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/piecewise.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/superstructure.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_pinch_design/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_pinch_design/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_pinch_design/amalgamation.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_pinch_design/equations.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_pinch_design/postprocess.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_pinch_design/preprocessing.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/equations.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/evolution.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/objectives.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/postprocess.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/setup.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/verification.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/warm_start.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/base.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/fixed_structure.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/packed_pinch_design.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/packed_stagewise.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/pinch_decomposition.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/problem.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/stage_packing.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/stagewise.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/thermal_profiles.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/prepared_problem.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/reporting/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/reporting/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/reporting/exports.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/reporting/ranking.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/reporting/verification.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/results/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/results/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/results/assembly.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/results/seeds.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/results/selection.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/service.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/arrays.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/backend.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/dependencies.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/piecewise.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/pinch_design_decomposition.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/_stage.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/network_evolution_method.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/open_hens_method.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/pinch_design_method.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/thermal_derivative_method.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/topology.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/aggregation.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/execution.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/preparation.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/setup.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/state.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/membership.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/replacement_streams.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/selection.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/state.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/values.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/work.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/_shared/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/_shared/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/_shared/air.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/_shared/plotting.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/_shared/streams.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/encoding.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/layout.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/load_selection.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/multi_vc_objective.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/postprocessing.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/shared.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/units.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/components.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/_multi_cycle_base.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/brayton_heat_pump.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/carnot_cycles.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/direct_mvr/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/direct_mvr/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/direct_mvr/execution.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/direct_mvr/models.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/direct_mvr/thermodynamics.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/direct_mvr/units.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/optimisation_adapter.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/adapters/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/adapters/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/adapters/coolprop.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/adapters/tespy.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/characteristics/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/characteristics/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/characteristics/openpinch-single-stage-compressor-v1.json +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/context.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/coolprop_preflight.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/errors.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/factory.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/fluids.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/models.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/points.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/protocols.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/provenance.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/resources.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/settings.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/targeting_models.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/process_mvr.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/service.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/_carnot_common.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/brayton.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/cascade_carnot.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/parallel_carnot.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_transfer.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/numerics.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/carnot.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/costing.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/cycle.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/inputs.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/profile.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/search.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/service.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/simulated.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/parallelism.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/power/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/power/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/power/service.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/power/steam_turbine.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/area_cost.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/cascade.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/context.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/direct.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/grand_composite.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/heat_recovery_dt_min.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/indirect.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/residual.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/temperature_driving_force.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/utilities.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/thermodynamics/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/thermodynamics/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/thermodynamics/water.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/allocation.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/bounds.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/codec.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/context.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/errors.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/evaluation.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/normalization.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/optimisation.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/penalties.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/profiles.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/replay.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/service.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/start_points.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/thermodynamics.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/units.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/accessors/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/accessors/component.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/accessors/design.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/accessors/plot.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/arguments.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/canonicalization.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/construction.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/loading.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/segments.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/semantics.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/utilities.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/validation.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/output/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/output/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/output/reporting.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/output/result_extraction.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/periods/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/periods/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/periods/aggregation.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/dispatch.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/execution.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/provenance.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/state.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_workspace/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_workspace/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_workspace/case_inputs.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_workspace/state.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/case_derivation.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/commands.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/hpr_selection.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/problem.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/residual_utility.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/targeting.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/utility_placement.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/common.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/controllability.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/graphs.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/heat_recovery_dt_min.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/input.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/output.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/report_metrics.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/report_units.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/reporting.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/hpr_performance_map/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/hpr_performance_map/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/common.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/method.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/result.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/task.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/topology.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/view.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/turbine.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/utility_placement.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/workspace.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger/area.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger/period_state.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger/rules.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger_network/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger_network/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger_network/types.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_problem_table/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_problem_table/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_problem_table/constants.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_problem_table/equality.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_problem_table/intervals.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_problem_table/types.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/linearisation.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/profile.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/segment.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/segments.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/thermodynamics.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/value_state.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream_collection/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream_collection/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream_collection/filters.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream_collection/numeric_view.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream_collection/serialization.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream_collection/sorting.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_validation.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_value/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_value/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_value/coercion.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_value/resolution.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_value/units.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/analysis.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/enums.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/heat_exchanger.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/heat_exchanger_network.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/hpr.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/problem_table.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/progress.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/solver_options.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/stream.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/stream_collection.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/targets.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/value.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/zone.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/_multistart.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/_surrogate.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/bayesian.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/cma_es.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/dual_annealing.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/protocol.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/rbf.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/candidates.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/errors.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/execution.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/feasibility.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/models.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/service.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/configuration.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/dashboard.css +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/dependencies.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/exports.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/rendering.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/state.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/graphs/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/graphs/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/graphs/plotly.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/graphs/problem.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/graphs/simple.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/_constants.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/dependencies.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/geometry.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/labels.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/layout.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/plotly.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/rendering.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/results.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/service.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/state.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/temperatures.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/view.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/adapters.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/excel_text.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/hpr.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/problem_table.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/results.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/stream_collection.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/thermal.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/workbook.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/resources.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/01_first_solve_and_core_curves.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/02_focused_direct_and_total_site.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/03_multisegment_streams.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/04_workspace_cases_and_scenarios.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/05_workspace_persistence.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/07_area_cost_and_exergy.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/09_vapour_compression.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/10_multiperiod_heat_pumps.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/11_process_mvr_and_cascade.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/12_cogeneration.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/13_multiperiod_cogeneration.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/14_energy_transfer.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/15_hen_synthesis_and_selection.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/16_advanced_hen_methods.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/17_multiperiod_hen_synthesis.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/18_results_plots_reports_exports.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/19_utility_placement_optimisation.ipynb +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/Four-stream-Yee-and-Grossmann-1990-1.json +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/README.md +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/__init__.py +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/basic_pinch.json +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/chocolate_factory.json +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/crude_preheat_train.json +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/crude_preheat_train_multiperiod.json +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/dairy_chilling_multiperiod.json +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/process_mvr.json +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/pulp_mill.json +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/zonal_site.json +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/zonal_site_multiperiod.json +0 -0
- {openpinch-0.8.2 → openpinch-0.8.3}/README.md +0 -0
|
@@ -21,7 +21,7 @@ Heat exchanger network (HEN) synthesis, fixed-structure duty optimisation and co
|
|
|
21
21
|
- [targeting](./targeting/README.md): method orchestration and topology helpers.
|
|
22
22
|
|
|
23
23
|
## Invariants
|
|
24
|
-
- Runtime options must be a dict or `None` and must not contain `HENS_` keys; persistent controls are loaded with the problem [context.py:normalise_runtime_options].
|
|
24
|
+
- Runtime options reaching this package must be a dict or `None` and must not contain `HENS_` keys; persistent controls are loaded with the problem. The `problem.design` accessors move `HENS_` keys from a call's `options` into that call's configuration before this check, so users may pass them there [context.py:normalise_runtime_options].
|
|
25
25
|
- Open-HENS and PDM reject `initial_networks`; `method=None` runs tier 0 and `OpenHENS` runs tier 1 [service.py:heat_exchanger_network_synthesis_service].
|
|
26
26
|
- The call-local quality tier of the OpenHENS entry points must be an integer from 0 to 5; the standalone method services use the configured tier [service.py:_validate_quality_tier].
|
|
27
27
|
- An accepted design is ranked, selected and verified; verification failures raise `RuntimeError` [context.py:finalise_design_result].
|
|
@@ -33,7 +33,7 @@ Heat exchanger network (HEN) synthesis, fixed-structure duty optimisation and co
|
|
|
33
33
|
## Side Effects
|
|
34
34
|
- `finalise_design_result` assigns `problem._results` with the design attached [context.py:finalise_design_result].
|
|
35
35
|
- `ensure_target_results` runs direct heat integration through `problem.target` when no matching targets are cached [context.py:ensure_target_results].
|
|
36
|
-
- Synthesis runs solver models in a `ProcessPoolExecutor` through `LocalSynthesisExecutor` when more than one worker is available; duty optimisation solves serially in-process through `FixedStructureDutyExecutor`. Both launch external solver executables via GEKKO/Pyomo [execution/executor.py:LocalSynthesisExecutor, duty_optimisation.py:FixedStructureDutyExecutor].
|
|
36
|
+
- Synthesis runs solver models in a `ProcessPoolExecutor` through `LocalSynthesisExecutor` when more than one worker is available and the main script has a main guard (or the start method is fork); duty optimisation solves serially in-process through `FixedStructureDutyExecutor`. Both launch external solver executables via GEKKO/Pyomo [execution/executor.py:LocalSynthesisExecutor, duty_optimisation.py:FixedStructureDutyExecutor].
|
|
37
37
|
- Controllability and indexing are pure.
|
|
38
38
|
|
|
39
39
|
## Verification
|
{openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/README.md
RENAMED
|
@@ -31,7 +31,7 @@ Resolves synthesis settings from a prepared problem, plans the quality-tier path
|
|
|
31
31
|
- The fake executor requires successful parents for downstream tasks [fake_executor.py:FakeSynthesisExecutor.execute].
|
|
32
32
|
|
|
33
33
|
## Side Effects
|
|
34
|
-
- Spawns solver worker processes through `ProcessPoolExecutor`, falling back to serial when the pool raises `NotImplementedError` [executor.py:_process_pool, LocalSynthesisExecutor._map].
|
|
34
|
+
- Spawns solver worker processes through `ProcessPoolExecutor`, falling back to serial when the pool raises `NotImplementedError`. The default pool raises it, after logging a warning, when the start method is not fork and the `__main__` script has no main guard, so it reads and parses that script [executor.py:_process_pool, LocalSynthesisExecutor._map] [../../../optimisation/execution.py:_main_module_reruns_in_workers].
|
|
35
35
|
- Emits progress events [executor.py:LocalSynthesisExecutor._report_progress].
|
|
36
36
|
- Mutates its own bookkeeping (`executed_tasks`, `stage_order`, `problems_by_task_id`, `best_objective`) [executor.py:LocalSynthesisExecutor].
|
|
37
37
|
- Emits a `RuntimeWarning` when the Couenne fallback is taken [fallbacks.py:_warn_couenne_fallback].
|
{openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/executor.py
RENAMED
|
@@ -12,6 +12,7 @@ from ....contracts.synthesis.task import (
|
|
|
12
12
|
)
|
|
13
13
|
from ....domain.enums import HeatExchangerNetworkDesignMethod
|
|
14
14
|
from ....domain.progress import emit as emit_progress
|
|
15
|
+
from ....optimisation.execution import _main_module_reruns_in_workers
|
|
15
16
|
from ...parallelism import supported_workers
|
|
16
17
|
from ..errors import WorkflowContractError
|
|
17
18
|
from ..models.problem import InternalHeatExchangerNetworkProblem
|
|
@@ -23,7 +24,13 @@ logger = logging.getLogger(__name__)
|
|
|
23
24
|
|
|
24
25
|
def _process_pool(max_workers: int) -> ProcessPoolExecutor:
|
|
25
26
|
"""Create solver workers with the interpreter's default process context."""
|
|
26
|
-
|
|
27
|
+
if _main_module_reruns_in_workers():
|
|
28
|
+
logger.warning(
|
|
29
|
+
"Solving HEN tasks serially: the main script has no main guard, "
|
|
30
|
+
"so every worker process would rerun it. Put the script's entry "
|
|
31
|
+
'code under `if __name__ == "__main__":` to use worker processes.'
|
|
32
|
+
)
|
|
33
|
+
raise NotImplementedError("the main script has no main guard")
|
|
27
34
|
return ProcessPoolExecutor(max_workers=max_workers)
|
|
28
35
|
|
|
29
36
|
|
|
@@ -18,6 +18,7 @@ a docstring.
|
|
|
18
18
|
- `build_hpr_accounting`, `calc_hpr_obj`, `relative_feasibility_penalty`, `normalise_hpr_penalty_terms`, `normalise_initial_points`, `initialise_hpr_seed` (`optimisation_adapter.py`): objective, penalty and seed helpers (`initialise_hpr_seed` is public but not in `__all__`).
|
|
19
19
|
- `ProcessComponent`, `ProcessComponentHost` (`components.py`): component base record and the protocol it needs from the problem object.
|
|
20
20
|
- `ProcessMVRComponent`, `create_process_mvr_component`, `replay_process_components`, `restore_process_components` (`process_mvr.py`): direct process MVR component with replacement streams, its factory, its re-solve on a rebuilt zone tree, and its rebuild from saved records.
|
|
21
|
+
- `screen_refrigerants`, `screen_refrigerant`, `resolve_refrigerants`, `RefrigerantScreenThresholds`, `RefrigerantScreenEntry`, `NATURAL_REFRIGERANTS` (`refrigerant_screen.py`): screen candidate fluids as single-stage cycles between evaporating and condensing saturation levels, and resolve a candidate group (`all` CoolProp fluids, `natural`) or a list of names.
|
|
21
22
|
- Subdirectories:
|
|
22
23
|
- [_multiperiod](./_multiperiod/README.md): shared-design preparation, execution and aggregation across periods (documented elsewhere).
|
|
23
24
|
- [_process_mvr](./_process_mvr/README.md): private helpers for process MVR selection, membership, replacement streams and work.
|
|
@@ -52,6 +53,11 @@ a docstring.
|
|
|
52
53
|
- A saved record names each source by its owning zone's path below the root and its stream name, so a name selector that matched several streams saves all of them and a renamed project still resolves; the `options` and `period_id` of the original call only check the call and are not saved. A missing source raises `ValueError`. [process_mvr.py:ProcessMVRComponent._to_record] [process_mvr.py:restore_process_components]
|
|
53
54
|
- `original_streams`, `replacement_streams` and `stage_results_by_period` return deep copies. [process_mvr.py:ProcessMVRComponent]
|
|
54
55
|
|
|
56
|
+
- A refrigerant screen judges each fluid in this order: condensing within `dt_cont` of the critical point is above critical; evaporating below CoolProp's minimum temperature is below the triple point; then, from saturation properties, a pressure ratio above `max_pressure_ratio`, a suction pressure below `min_suction_pressure` and condensing within `critical_margin` of the critical point; otherwise practical. Fluids without a saturation state carry no pressures or capacity. [refrigerant_screen.py:screen_refrigerant]
|
|
57
|
+
- A screen covers every evaporating and condensing level pair with positive lift, in level order, and raises `ValueError` when none has; within a pair the practical fluids come first, ranked from 1 by descending suction volumetric heating capacity, then the others in candidate order. [refrigerant_screen.py:screen_refrigerants]
|
|
58
|
+
- `RefrigerantScreenThresholds.from_configuration` reads `HPR_DT_CONT`, `HPR_MAX_PRESSURE_RATIO`, `HPR_SCREEN_MIN_SUCTION_PRESSURE` (bar, held in Pa) and `HPR_SCREEN_CRITICAL_MARGIN`. [refrigerant_screen.py:RefrigerantScreenThresholds]
|
|
59
|
+
- Candidate lists are validated by name and mixtures are rejected; `all` is whatever the installed CoolProp lists, so it differs between CoolProp versions. [refrigerant_screen.py:resolve_refrigerants]
|
|
60
|
+
|
|
55
61
|
## Side Effects
|
|
56
62
|
- Deep-copies the base target's problem table and mutates the copy with HPR, air and residual columns. [service.py:_compute_single_period_hpr_target] [service.py:_calc_hpr_cascade]
|
|
57
63
|
- Emits progress events for `hpr_targeting` through `domain.progress`. [optimisation_adapter.py:solve_hpr_placement] [optimisation_adapter.py:_CachedHPRScalarObjective]
|
|
@@ -11,6 +11,7 @@ multi-stage vapour-compression objective, and residual utility accounting.
|
|
|
11
11
|
## Interface
|
|
12
12
|
- `construct_HPRTargetInputs`, `default_refrigeration_to_power_ratio` (`preprocessing.py`): build `HeatPumpTargetInputs` (shifted, simplified background profiles, ambient flags, cost and cycle settings) from a zone's cascades and `Configuration`; default refrigeration electricity ratio.
|
|
13
13
|
- `resolve_hpr_target_load` (`load_selection.py`): requested HPR duty from `config.hpr.load_mode` (`fraction`, `duty`, `period_values`), capped by the available cascade duty in `duty` and `period_values` modes only.
|
|
14
|
+
- `find_hpr_load_kinks`, `HprLoadKinkProfile`, `LoadKinkVertex` (`load_kinks.py`): classify every interior vertex of the heat pump sink (`H_NET_COLD`) or refrigeration source (`H_NET_HOT`) net load profile as step, steepens, flattens or minor, and list the logical load fractions (step and steepens vertices, then 1.0).
|
|
14
15
|
- `HPRoptVectorLayout`, `clip_to_bounds` (`layout.py`): named sections of a flat optimisation vector (`pack`, `unpack`, `build_bounds`) and clipping of seeds into bounds.
|
|
15
16
|
- Duty and temperature encoding (`encoding.py`): `decode_available_fractions`, `encode_available_fractions`, `limit_available_duty`, `allocate_stage_duties`, `require_stage_duty_allocation`, `DutyAllocation`, `StageDutyRequest`, `DutyAllocationRequest` (with `from_state`), and the `map_*_to_*_arr` pairs between optimisation fractions and temperatures, temperature differences or duties.
|
|
16
17
|
- Costing and results (`shared.py`): `HPRCostUnit`, `calc_hpr_capital_cost`, `calc_hpr_machine_capital_costs`, `calc_simulated_hpr_annualized_costs`, `hpr_penalty_cost_scale`, `refrigeration_allowance`, `evaluate_carnot_hpr_result`, `evaluate_vapour_hpr_result`, `post_solve_error`; `limit_parallel_pressure_ratios` raises evaporating temperatures and `limit_cascade_pressure_ratios` raises each lower level (condensing or evaporating) to meet `hpr.max_pressure_ratio`, and both do nothing for TESPy or when no refrigerants are set; constants `EVAPORATING_FLOOR_MARGIN_K`, `NEGLIGIBLE_STAGE_WORK_FRACTION`.
|
|
@@ -18,6 +19,7 @@ multi-stage vapour-compression objective, and residual utility accounting.
|
|
|
18
19
|
- Thermodynamic helpers (`shared.py`): `calc_carnot_heat_pump_cop`, `calc_carnot_heat_engine_eta`, `compute_entropic_mean_temperature`, and `satisfies_second_law` (public but not in `__all__`).
|
|
19
20
|
- `_evaluate_multi_vc_objective` (`multi_vc_objective.py`): shared objective for cascade and parallel vapour-compression targeting (parse vector, solve, build streams, account, attach CoolProp record).
|
|
20
21
|
- `value_at_index`, `to_kelvin`, `to_degrees_celsius`, `to_kilopascal` (`units.py`): period-indexed value and unit conversion.
|
|
22
|
+
- Compressor efficiency (`compressor_efficiency.py`): `CompressorConditions` (refrigerant, suction and discharge pressures in kPa, `pressure_ratio`, suction temperature and dew points in degC, suction and saturated vapour densities in kg/m3), `compressor_efficiency_model` (a model name or function to a constant or a function of the conditions), `evaluate_compressor_model`, `CompressorModelError`, and the HeatPumpLab correlations `pareto_front_efficiency`, `wang_cleland_efficiency`, `brendel_efficiency`.
|
|
21
23
|
- `postprocessing.py`: only private functions; `_get_hpr_residual_utility_summary` is the one the service imports, retargeting utilities against the residual cascade after the HPR.
|
|
22
24
|
- Subdirectories: [_shared](./_shared/README.md): private air, stream and plotting helpers behind `shared.py`.
|
|
23
25
|
|
|
@@ -27,6 +29,7 @@ multi-stage vapour-compression objective, and residual utility accounting.
|
|
|
27
29
|
- A zero target raises `ValueError` for heat pumping [preprocessing.py:_get_reduced_bckgrd_cascade_till_Q_target] and, when the cooling profile exceeds the target, for refrigeration [preprocessing.py:_split_cooling_profile_at_coldest_Q_target].
|
|
28
30
|
- The default refrigeration price ratio is never below the cooling-water ratio. [preprocessing.py:default_refrigeration_to_power_ratio]
|
|
29
31
|
- Stage duties are decoded as fractions in [0, 1] of each stage's available duty, so no stage can request more than it can deliver. [encoding.py:decode_available_fractions]
|
|
32
|
+
- Load kinks walk the sink profile up from the pinch and the source profile down from it, after dropping repeated rows; slopes are `|dT| / d(Q/Q_max)`. A vertex followed by no duty is a step, and the step's top row is not listed again. Otherwise it steepens when `slope_after >= steepening * slope_before` (and `slope_after > 0`), flattens on the mirror condition, and is minor otherwise. `steepening <= 1` and a profile with no duty raise `ValueError`. Duty below `1e-9 * Q_max` and temperature change below `1e-9` K count as zero. [load_kinks.py:find_hpr_load_kinks]
|
|
30
33
|
- `HPRoptVectorLayout` section order is cond, evap, subcool, heat_split, cool_split, ihx, misc, and counts must be non-negative. [layout.py:HPRoptVectorLayout]
|
|
31
34
|
- The load is `Q_max * load_fraction` in `fraction` mode and is capped at the available duty `Q_max` in `duty` and `period_values` modes; an unknown mode, a missing `config` or a missing period key raises `ValueError`. [load_selection.py:resolve_hpr_target_load]
|
|
32
35
|
- Machine capital is `F_inst * C_eq * (Q_cap/MW)^exp * stage factor * temperature factor`, per machine, and zero for a machine with no capacity. [shared.py:calc_hpr_machine_capital_costs]
|
|
@@ -36,6 +39,7 @@ multi-stage vapour-compression objective, and residual utility accounting.
|
|
|
36
39
|
- Ambient air and cooling water are applied through `cascade_with_air` on the condenser and evaporator cascades; cooling water applies on the evaporator side only. Air is left out when `args.ambient_air_enabled` is false (`HPR_AMBIENT_AIR_ENABLED`). [shared.py:_cascade_air_duties]
|
|
37
40
|
- `calc_carnot_heat_pump_cop` and `calc_carnot_heat_engine_eta` take absolute temperatures (K); `satisfies_second_law` takes degC and adds 273.15 internally, and `compute_entropic_mean_temperature` takes degC by default and returns K. [shared.py:calc_carnot_heat_pump_cop] [shared.py:satisfies_second_law]
|
|
38
41
|
- Residual loads below `max(tol, 1e-7 * largest)` are treated as rounding noise and set to zero; duplicate residual temperatures with conflicting values raise `ValueError`. [postprocessing.py:_residual_noise_floor] [postprocessing.py:_deduplicate_residual_profile_rows]
|
|
42
|
+
- `HPR_COMPRESSOR_MODEL` and `HPR_MVR_COMPRESSOR_MODEL` `"constant"` pass `HPR_ETA_COMP` and `HPR_MVR_ETA_COMP` through as floats, so the default cycles are unchanged; only the vapour compression cycle types take a `HPR_COMPRESSOR_MODEL` model, and other types (Brayton passes `eta_comp` to TESPy) keep `HPR_ETA_COMP`; the named models are HeatPumpLab's correlations bounded to [0.4, 1.0] and pickle. [preprocessing.py:construct_HPRTargetInputs] [compressor_efficiency.py:compressor_efficiency_model]
|
|
39
43
|
- `common` imports the parent's `optimisation_adapter` and `performance_maps.targeting` for accounting and backend names. [shared.py] [preprocessing.py]
|
|
40
44
|
|
|
41
45
|
## Side Effects
|
|
@@ -47,4 +51,4 @@ multi-stage vapour-compression objective, and residual utility accounting.
|
|
|
47
51
|
|
|
48
52
|
## Verification
|
|
49
53
|
- Run: `uv run --no-sync pytest tests/analysis/heat_pumps/test_shared.py tests/analysis/heat_pumps/test_encoding.py tests/analysis/heat_pumps/test_layout.py tests/analysis/heat_pumps/test_preprocessing.py`
|
|
50
|
-
- `postprocessing.py` is covered by `tests/analysis/heat_pumps/test_hpr_residual_regressions.py`; `load_selection.py` by `tests/analysis/heat_pumps/test_targeting.py`. `multi_vc_objective.py` and `units.py` have no direct test; they are exercised through the cascade and parallel vapour-compression tests.
|
|
54
|
+
- `postprocessing.py` is covered by `tests/analysis/heat_pumps/test_hpr_residual_regressions.py`; `load_selection.py` by `tests/analysis/heat_pumps/test_targeting.py`. `load_kinks.py` by `tests/analysis/heat_pumps/test_load_kinks.py`. `multi_vc_objective.py` and `units.py` have no direct test; they are exercised through the cascade and parallel vapour-compression tests.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""Compressor isentropic efficiency models for vapour compression HPR cycles.
|
|
2
|
+
|
|
3
|
+
The correlations follow HeatPumpLab (Apache-2.0,
|
|
4
|
+
https://github.com/waikato-ahuora-smart-energy-systems/HeatPumpLab,
|
|
5
|
+
``HeatPumpLab.components.compressor``).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import math
|
|
11
|
+
from collections.abc import Callable
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
|
|
14
|
+
# Pareto front of design compressor efficiency against pressure ratio (HeatPumpLab,
|
|
15
|
+
# October 2026): eta(PR) = eta_1 - a ln(PR)^b - d / (1 + exp(-(ln(PR) - L0) / w)),
|
|
16
|
+
# a lower envelope of the best published shaft-basis isentropic efficiency for
|
|
17
|
+
# 1 <= PR <= 20.
|
|
18
|
+
_PARETO_FRONT_COEFFS = (0.8695, 0.025392, 1.476, 0.29915, 2.9599, 0.2)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def pareto_front_efficiency(pressure_ratio: float) -> float:
|
|
22
|
+
"""Return the shaft-basis isentropic efficiency on the Pareto front."""
|
|
23
|
+
log_pr = math.log(max(float(pressure_ratio), 1.0))
|
|
24
|
+
eta_1, a, b, d, L0, w = _PARETO_FRONT_COEFFS
|
|
25
|
+
return eta_1 - a * log_pr**b - d / (1.0 + math.exp(-(log_pr - L0) / w))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def wang_cleland_efficiency(pressure_ratio: float) -> float:
|
|
29
|
+
"""Return the shaft-basis isentropic efficiency of Wang and Cleland (2018).
|
|
30
|
+
|
|
31
|
+
The overall efficiency polynomial is divided by a motor efficiency of 0.96.
|
|
32
|
+
"""
|
|
33
|
+
pr = float(pressure_ratio)
|
|
34
|
+
return (0.65 + 0.015 * pr - 0.0015 * pr**2) / 0.96
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def brendel_efficiency(pressure_ratio: float, suction_pressure: float) -> float:
|
|
38
|
+
"""Return the isentropic efficiency of Brendel et al.; pressure in kPa.
|
|
39
|
+
|
|
40
|
+
The correlation takes the suction pressure in MPa; without compression
|
|
41
|
+
(pressure ratio at most 1) it returns 0.4.
|
|
42
|
+
"""
|
|
43
|
+
pr = float(pressure_ratio)
|
|
44
|
+
if pr <= 1.0:
|
|
45
|
+
return 0.4
|
|
46
|
+
P_mpa = float(suction_pressure) / 1000.0
|
|
47
|
+
return 0.66981 - 0.6 / (pr - 0.01466) ** (8.38 * P_mpa) - 0.00102 * pr**1.8
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@dataclass(frozen=True)
|
|
51
|
+
class CompressorConditions:
|
|
52
|
+
"""Operating point handed to a compressor efficiency model.
|
|
53
|
+
|
|
54
|
+
Pressures are in kPa, temperatures in degC and densities in kg/m3. The dew
|
|
55
|
+
points are those of the refrigerant at the suction and discharge pressures,
|
|
56
|
+
the basis of manufacturer maps in evaporating and condensing temperature.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
refrigerant: str
|
|
60
|
+
P_suction: float
|
|
61
|
+
P_discharge: float
|
|
62
|
+
T_suction: float
|
|
63
|
+
T_evap_dew: float
|
|
64
|
+
T_cond_dew: float
|
|
65
|
+
rho_suction: float
|
|
66
|
+
rho_evap_dew: float
|
|
67
|
+
rho_cond_dew: float
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def pressure_ratio(self) -> float:
|
|
71
|
+
"""Discharge over suction pressure."""
|
|
72
|
+
return self.P_discharge / self.P_suction
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
CompressorEfficiencyFunction = Callable[[CompressorConditions], float]
|
|
76
|
+
|
|
77
|
+
# HeatPumpLab bounds every correlation to this range.
|
|
78
|
+
_CORRELATION_BOUNDS = (0.4, 1.0)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass(frozen=True)
|
|
82
|
+
class _Correlation:
|
|
83
|
+
"""A built-in correlation by name; a plain class so it pickles."""
|
|
84
|
+
|
|
85
|
+
name: str
|
|
86
|
+
|
|
87
|
+
def __call__(self, conditions: CompressorConditions) -> float:
|
|
88
|
+
pr = conditions.pressure_ratio
|
|
89
|
+
if self.name == "pareto_front":
|
|
90
|
+
eta = pareto_front_efficiency(pr)
|
|
91
|
+
elif self.name == "wang_cleland":
|
|
92
|
+
eta = wang_cleland_efficiency(pr)
|
|
93
|
+
else:
|
|
94
|
+
eta = brendel_efficiency(pr, conditions.P_suction)
|
|
95
|
+
lo, hi = _CORRELATION_BOUNDS
|
|
96
|
+
return min(max(eta, lo), hi)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def compressor_efficiency_model(
|
|
100
|
+
model: str | CompressorEfficiencyFunction, eta_constant: float
|
|
101
|
+
) -> float | CompressorEfficiencyFunction:
|
|
102
|
+
"""Return a constant efficiency or a function of ``CompressorConditions``.
|
|
103
|
+
|
|
104
|
+
``"constant"`` gives ``eta_constant``; a built-in name gives its bounded
|
|
105
|
+
correlation; a function is returned as given.
|
|
106
|
+
"""
|
|
107
|
+
if callable(model):
|
|
108
|
+
return model
|
|
109
|
+
if model == "constant":
|
|
110
|
+
return float(eta_constant)
|
|
111
|
+
return _Correlation(model)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class CompressorModelError(RuntimeError):
|
|
115
|
+
"""A compressor model returned an unusable efficiency."""
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def evaluate_compressor_model(
|
|
119
|
+
model: CompressorEfficiencyFunction, conditions: CompressorConditions
|
|
120
|
+
) -> float:
|
|
121
|
+
"""Return the model's isentropic efficiency, which must lie in (0, 1].
|
|
122
|
+
|
|
123
|
+
A ``ValueError`` raised by the model marks the operating point infeasible
|
|
124
|
+
for the targeting search; an efficiency out of range raises
|
|
125
|
+
``CompressorModelError``, which stops it.
|
|
126
|
+
"""
|
|
127
|
+
eta = float(model(conditions))
|
|
128
|
+
if not 0.0 < eta <= 1.0:
|
|
129
|
+
name = getattr(model, "name", None) or getattr(
|
|
130
|
+
model, "__name__", type(model).__name__
|
|
131
|
+
)
|
|
132
|
+
raise CompressorModelError(
|
|
133
|
+
f"Compressor model {name} returned an isentropic efficiency of {eta}; "
|
|
134
|
+
"it must lie in (0, 1]."
|
|
135
|
+
)
|
|
136
|
+
return eta
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"""Logical heat pump and refrigeration loads from net load profile kinks."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
from ....contracts.hpr_load_kinks import LOGICAL_LOAD_KINDS, HprLoadKinkKind
|
|
10
|
+
|
|
11
|
+
__all__ = ["HprLoadKinkProfile", "LoadKinkVertex", "find_hpr_load_kinks"]
|
|
12
|
+
|
|
13
|
+
# Duty below this fraction of the profile's total, or a temperature change
|
|
14
|
+
# below this many kelvin, is treated as zero.
|
|
15
|
+
_DUTY_RELATIVE_TOLERANCE = 1e-9
|
|
16
|
+
_TEMPERATURE_TOLERANCE = 1e-9
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass(frozen=True)
|
|
20
|
+
class LoadKinkVertex:
|
|
21
|
+
"""One interior vertex in canonical units (kW, shifted degC, K)."""
|
|
22
|
+
|
|
23
|
+
load_fraction: float
|
|
24
|
+
duty: float
|
|
25
|
+
temperature: float
|
|
26
|
+
slope_before: float
|
|
27
|
+
slope_after: float | None
|
|
28
|
+
kind: HprLoadKinkKind
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass(frozen=True)
|
|
32
|
+
class HprLoadKinkProfile:
|
|
33
|
+
"""Every interior vertex of one net load profile and its logical loads."""
|
|
34
|
+
|
|
35
|
+
maximum_duty: float
|
|
36
|
+
vertices: tuple[LoadKinkVertex, ...]
|
|
37
|
+
logical_load_fractions: tuple[float, ...]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def find_hpr_load_kinks(
|
|
41
|
+
T_vals: np.ndarray,
|
|
42
|
+
H_net_cold: np.ndarray,
|
|
43
|
+
H_net_hot: np.ndarray,
|
|
44
|
+
*,
|
|
45
|
+
is_refrigeration: bool = False,
|
|
46
|
+
steepening: float = 2.0,
|
|
47
|
+
) -> HprLoadKinkProfile:
|
|
48
|
+
"""Classify the vertices of the sink (or source) net load profile.
|
|
49
|
+
|
|
50
|
+
Rows run from the hottest temperature down, as in a problem table. A heat
|
|
51
|
+
pump walks the sink profile up from the pinch; refrigeration walks the
|
|
52
|
+
source profile down from it. The slope is the temperature change per unit
|
|
53
|
+
load fraction. A vertex is a logical load when the profile steps (changes
|
|
54
|
+
temperature with no duty) or its slope after is at least ``steepening``
|
|
55
|
+
times its slope before. The full load, 1.0, is always a logical load.
|
|
56
|
+
"""
|
|
57
|
+
if not steepening > 1.0:
|
|
58
|
+
raise ValueError("steepening must be greater than 1.")
|
|
59
|
+
temperatures = np.asarray(T_vals, dtype=float)
|
|
60
|
+
if is_refrigeration:
|
|
61
|
+
duties = np.abs(np.asarray(H_net_hot, dtype=float))
|
|
62
|
+
else:
|
|
63
|
+
duties = np.abs(np.asarray(H_net_cold, dtype=float))[::-1]
|
|
64
|
+
temperatures = temperatures[::-1]
|
|
65
|
+
maximum_duty = float(np.nanmax(duties, initial=0.0))
|
|
66
|
+
if not 0.0 < maximum_duty < np.inf:
|
|
67
|
+
profile = "refrigeration source" if is_refrigeration else "heat pump sink"
|
|
68
|
+
raise ValueError(f"The net load profile has no {profile} duty.")
|
|
69
|
+
duty_tolerance = _DUTY_RELATIVE_TOLERANCE * maximum_duty
|
|
70
|
+
|
|
71
|
+
start = int(np.flatnonzero(duties <= duty_tolerance)[-1])
|
|
72
|
+
end = int(np.flatnonzero(duties >= maximum_duty - duty_tolerance)[0])
|
|
73
|
+
points = [(duties[start], temperatures[start])]
|
|
74
|
+
for duty, temperature in zip(
|
|
75
|
+
duties[start + 1 : end + 1], temperatures[start + 1 : end + 1]
|
|
76
|
+
):
|
|
77
|
+
last_duty, last_temperature = points[-1]
|
|
78
|
+
if (
|
|
79
|
+
duty - last_duty > duty_tolerance
|
|
80
|
+
or abs(temperature - last_temperature) > _TEMPERATURE_TOLERANCE
|
|
81
|
+
):
|
|
82
|
+
points.append((duty, temperature))
|
|
83
|
+
|
|
84
|
+
vertices = []
|
|
85
|
+
for before, vertex, after in zip(points, points[1:], points[2:]):
|
|
86
|
+
if vertex[0] - before[0] <= duty_tolerance:
|
|
87
|
+
# The top of a step is the same load as its foot.
|
|
88
|
+
continue
|
|
89
|
+
slope_before = _slope(before, vertex, maximum_duty)
|
|
90
|
+
slope_after = (
|
|
91
|
+
None
|
|
92
|
+
if after[0] - vertex[0] <= duty_tolerance
|
|
93
|
+
else _slope(vertex, after, maximum_duty)
|
|
94
|
+
)
|
|
95
|
+
vertices.append(
|
|
96
|
+
LoadKinkVertex(
|
|
97
|
+
load_fraction=float(vertex[0] / maximum_duty),
|
|
98
|
+
duty=float(vertex[0]),
|
|
99
|
+
temperature=float(vertex[1]),
|
|
100
|
+
slope_before=slope_before,
|
|
101
|
+
slope_after=slope_after,
|
|
102
|
+
kind=_kind(slope_before, slope_after, steepening),
|
|
103
|
+
)
|
|
104
|
+
)
|
|
105
|
+
logical = tuple(v.load_fraction for v in vertices if v.kind in LOGICAL_LOAD_KINDS)
|
|
106
|
+
return HprLoadKinkProfile(
|
|
107
|
+
maximum_duty=maximum_duty,
|
|
108
|
+
vertices=tuple(vertices),
|
|
109
|
+
logical_load_fractions=logical + (1.0,),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _slope(start, end, maximum_duty: float) -> float:
|
|
114
|
+
"""Temperature change per unit load fraction between two points."""
|
|
115
|
+
return float(abs(end[1] - start[1]) / ((end[0] - start[0]) / maximum_duty))
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _kind(
|
|
119
|
+
slope_before: float, slope_after: float | None, steepening: float
|
|
120
|
+
) -> HprLoadKinkKind:
|
|
121
|
+
if slope_after is None:
|
|
122
|
+
return HprLoadKinkKind.STEP
|
|
123
|
+
if slope_after > 0.0 and slope_after >= steepening * slope_before:
|
|
124
|
+
return HprLoadKinkKind.STEEPENS
|
|
125
|
+
if slope_before > 0.0 and slope_before >= steepening * slope_after:
|
|
126
|
+
return HprLoadKinkKind.FLATTENS
|
|
127
|
+
return HprLoadKinkKind.MINOR
|
|
@@ -8,11 +8,22 @@ from ....analysis.graphs.composite import clean_composite_curve
|
|
|
8
8
|
from ....analysis.numerics import delta_vals, linear_interpolation
|
|
9
9
|
from ....contracts.hpr import HeatPumpTargetInputs, HPRSearchBudget
|
|
10
10
|
from ....domain.configuration import Configuration, tol
|
|
11
|
-
from ....domain.enums import ProblemTableLabel
|
|
11
|
+
from ....domain.enums import HeatPumpAndRefrigerationCycle, ProblemTableLabel
|
|
12
12
|
from ....domain.problem_table import ProblemTable
|
|
13
13
|
from ....domain.stream import Stream
|
|
14
14
|
from ....domain.stream_collection import StreamCollection
|
|
15
15
|
from ..performance_maps.targeting import normalize_hpr_simulation_backend
|
|
16
|
+
from .compressor_efficiency import compressor_efficiency_model
|
|
17
|
+
|
|
18
|
+
# Cycles whose CoolProp models apply a compressor efficiency model; Brayton
|
|
19
|
+
# passes eta_comp to TESPy, which needs a number.
|
|
20
|
+
_VAPOUR_CYCLES = frozenset(
|
|
21
|
+
{
|
|
22
|
+
HeatPumpAndRefrigerationCycle.CascadeVapourComp.value,
|
|
23
|
+
HeatPumpAndRefrigerationCycle.ParallelVapourComp.value,
|
|
24
|
+
HeatPumpAndRefrigerationCycle.VapourCompMVR.value,
|
|
25
|
+
}
|
|
26
|
+
)
|
|
16
27
|
|
|
17
28
|
__all__ = [
|
|
18
29
|
"construct_HPRTargetInputs",
|
|
@@ -106,9 +117,15 @@ def construct_HPRTargetInputs(
|
|
|
106
117
|
refrigerant_ls=hpr.normalised_refrigerants,
|
|
107
118
|
mvr_fluid_ls=hpr.normalised_mvr_fluids,
|
|
108
119
|
do_refrigerant_sort=hpr.refrigerant_sort_enabled,
|
|
109
|
-
eta_comp=
|
|
110
|
-
|
|
111
|
-
|
|
120
|
+
eta_comp=compressor_efficiency_model(
|
|
121
|
+
hpr.compressor_model if hpr.type in _VAPOUR_CYCLES else "constant",
|
|
122
|
+
hpr.eta_comp,
|
|
123
|
+
),
|
|
124
|
+
eta_mvr_comp=compressor_efficiency_model(
|
|
125
|
+
hpr.mvr_compressor_model, hpr.mvr_eta_comp
|
|
126
|
+
),
|
|
127
|
+
eta_motor=hpr.eta_motor,
|
|
128
|
+
eta_mvr_motor=hpr.mvr_eta_motor,
|
|
112
129
|
eta_exp=hpr.eta_exp,
|
|
113
130
|
eta_ii_hpr_carnot=hpr.eta_ii_carnot,
|
|
114
131
|
eta_ii_he_carnot=hpr.effective_eta_ii_he_carnot,
|
|
@@ -15,7 +15,9 @@ in `../common`. `__init__.py` has only a docstring.
|
|
|
15
15
|
- `CascadeVapourCompressionCycle` (`cascade_vapour_compression_cycle.py`): stages coupled through cascade exchangers; `solve` takes condenser and evaporator temperature arrays and a `DutyAllocationRequest`. Stages are ordered hottest first and heat always passes up the cascade. A heat pump solves from the top stage down and the coldest stage takes the remaining cooling; a refrigerator solves from the coldest stage up and the top stage rejects the remaining heat.
|
|
16
16
|
- `ParallelVapourCompressionCycles` (`parallel_vapour_compression_cycles.py`): independent subcycles solved side by side.
|
|
17
17
|
- `MechanicalVapourRecompressionCycle` (`mechanical_vapour_recompression_cycle.py`): open MVR stage with liquid-injection desuperheating, solved by `solve_from_source_heat` or `solve_from_mass_flow`; `process_heat_components` gives desuperheat, latent and subcool heat.
|
|
18
|
-
- `VapourCompressionMvrCascade` (`vapour_compression_mvr_cascade.py`): vapour-compression stages feeding a serial MVR train; `MAX_MVR_STAGE_LIFT` limits stage lift.
|
|
18
|
+
- `VapourCompressionMvrCascade` (`vapour_compression_mvr_cascade.py`): vapour-compression stages feeding a serial MVR train; `MAX_MVR_STAGE_LIFT` limits stage lift; `eta_comp` gives the efficiency applied in each subcycle, vapour compression stages first.
|
|
19
|
+
- Compressor efficiency: `eta_comp` (vapour compression) and `eta_mvr_comp` (MVR) take a constant or a function of `CompressorConditions` (`../common/compressor_efficiency.py`), evaluated at each compressor's suction and discharge state; the cycles' `eta_comp` and `eta_mvr_comp` properties report the efficiency applied in the last solve.
|
|
20
|
+
- Motor efficiency: `VapourCompressionCycle.solve`, `ParallelVapourCompressionCycles.solve` and `CascadeVapourCompressionCycle.solve` take `eta_motor` (default 1.0, in (0, 1]); `VapourCompressionMvrCascade.solve` takes `eta_vc_motor` for its vapour compression stages and `eta_motor` for its MVR stages. `work`, `w_net` and the COPs are electrical (shaft work divided by `eta_motor`); duties are unchanged. [vapour_compression_cycle.py:VapourCompressionCycle]
|
|
19
21
|
- `CascadeCarnotCycle`, `ParallelCarnotCycles` (`carnot_cycles.py`): Carnot-family heat pump, heat engine and heat recovery stages with second-law efficiency factors.
|
|
20
22
|
- `SimpleBraytonHeatPumpCycle` (`brayton_heat_pump.py`): TESPy Brayton model (experimental, no `__all__`); `solve`, `get_hp_th_profiles`, `get_hp_hot_and_cold_streams`, `build_stream_collection`.
|
|
21
23
|
- `_MultiVapourCompressionCycleBase` (`_multi_cycle_base.py`): private base aggregating duties, temperatures and COPs over `subcycles`; `__all__` is empty.
|
|
@@ -26,6 +28,7 @@ in `../common`. `__init__.py` has only a docstring.
|
|
|
26
28
|
- Cycle temperatures are given in degC, held internally in K, and reported in degC after solving; for the CoolProp vapour cycles, state points hold `H`, `S`, `P`, `T` in SI units (the Brayton cycle uses its own state keys). [vapour_compression_cycle.py:VapourCompressionCycle.solve] [vapour_compression_cycle.py:VapourCompressionCycle._save_cycle_state]
|
|
27
29
|
- A single cycle has `STATECOUNT = 6` states; the MVR cycle has 4. [vapour_compression_cycle.py:VapourCompressionCycle] [mechanical_vapour_recompression_cycle.py:MechanicalVapourRecompressionCycle]
|
|
28
30
|
- `solve` raises `ValueError` for an evaporating temperature below the refrigerant's `Tmin`, an evaporator pressure above the condenser pressure, or a condenser with no enthalpy drop. [vapour_compression_cycle.py:VapourCompressionCycle.solve]
|
|
31
|
+
- A compressor efficiency function outside (0, 1] raises `CompressorModelError`, not `ValueError`, so the targeting search does not read it as an infeasible point; a `ValueError` from the function itself propagates as one. With a constant efficiency no compressor conditions are computed. [vapour_compression_cycle.py:VapourCompressionCycle._compute_compressor_outlet_state]
|
|
29
32
|
- A stage passing heat up gives the hottest of its condenser heat to the cascade exchanger and the coldest to its process duty. Subcooled liquid cannot heat the evaporator above, so subcooling heat must all fit in the process duty: `solve` raises the condenser outlet to that limit, without a penalty, and a stage with no process duty does not subcool. The internal heat exchanger's limit then follows the subcooling applied. [vapour_compression_cycle.py:VapourCompressionCycle._coldest_outlet_serving_cascade_heat] [vapour_compression_cycle.py:VapourCompressionCycle.solve]
|
|
30
33
|
- A cycle is marked solved only when work is finite and non-negative. [vapour_compression_cycle.py:VapourCompressionCycle.solve]
|
|
31
34
|
- Excess subcooling and missing IHX superheat are returned as penalties scaled by mass flow, not as exceptions. [vapour_compression_cycle.py:VapourCompressionCycle.solve]
|
|
@@ -309,6 +309,7 @@ class CascadeVapourCompressionCycle(_MultiVapourCompressionCycleBase):
|
|
|
309
309
|
dT_superheat: np.ndarray = 0.0,
|
|
310
310
|
dT_subcool: np.ndarray = 0.0,
|
|
311
311
|
eta_comp: float = 0.7,
|
|
312
|
+
eta_motor: float = 1.0,
|
|
312
313
|
refrigerant: List[str] | str = "water",
|
|
313
314
|
dT_ihx_gas_side: np.ndarray | float = 10.0,
|
|
314
315
|
Q_heat: np.ndarray = None,
|
|
@@ -334,6 +335,8 @@ class CascadeVapourCompressionCycle(_MultiVapourCompressionCycleBase):
|
|
|
334
335
|
Degree of subcooling after the condenser, heat delivered to the process [K].
|
|
335
336
|
eta_comp : float, optional
|
|
336
337
|
Isentropic efficiency of the compressor [-].
|
|
338
|
+
eta_motor : float, optional
|
|
339
|
+
Efficiency of each compressor motor [-].
|
|
337
340
|
refrigerant : List[str], optional
|
|
338
341
|
Cycle refrigerant; supports multi-component fluids.
|
|
339
342
|
dT_ihx_gas_side : np.ndarray | float, optional
|
|
@@ -451,6 +454,7 @@ class CascadeVapourCompressionCycle(_MultiVapourCompressionCycleBase):
|
|
|
451
454
|
dT_superheat=dT_superheat_all[i],
|
|
452
455
|
dT_subcool=dT_subcool_all[i],
|
|
453
456
|
eta_comp=eta_comp,
|
|
457
|
+
eta_motor=eta_motor,
|
|
454
458
|
refrigerant=refrigerant_all[i],
|
|
455
459
|
dT_ihx_gas_side=ihx_gas_dt_all[i],
|
|
456
460
|
Q_heat=Q_heat_all[i],
|
|
@@ -87,7 +87,9 @@ class MechanicalVapourRecompressionCycle(VapourCompressionCycle):
|
|
|
87
87
|
|
|
88
88
|
@property
|
|
89
89
|
def eta_mvr_comp(self) -> float:
|
|
90
|
-
"""MVR compressor isentropic efficiency."""
|
|
90
|
+
"""MVR compressor isentropic efficiency, as applied when it is a model."""
|
|
91
|
+
if callable(self._eta_mvr_comp):
|
|
92
|
+
return self._eta_comp_applied
|
|
91
93
|
return self._eta_mvr_comp
|
|
92
94
|
|
|
93
95
|
@property
|
|
@@ -359,7 +361,9 @@ class MechanicalVapourRecompressionCycle(VapourCompressionCycle):
|
|
|
359
361
|
self._cycle_states = self._new_cycle_states()
|
|
360
362
|
self._penalty = np.asarray([], dtype=float)
|
|
361
363
|
self._refrigerant = fluid
|
|
362
|
-
self._eta_mvr_comp =
|
|
364
|
+
self._eta_mvr_comp = (
|
|
365
|
+
eta_mvr_comp if callable(eta_mvr_comp) else float(eta_mvr_comp)
|
|
366
|
+
)
|
|
363
367
|
self._eta_motor = float(eta_motor)
|
|
364
368
|
self._m_dot = 0.0
|
|
365
369
|
self._m_dot_source = 0.0
|
|
@@ -385,7 +389,9 @@ class MechanicalVapourRecompressionCycle(VapourCompressionCycle):
|
|
|
385
389
|
if self._dT_subcool < 0.0:
|
|
386
390
|
self._max_work *= 1e3
|
|
387
391
|
return None
|
|
388
|
-
if self.
|
|
392
|
+
if self._eta_motor <= 0.0 or (
|
|
393
|
+
not callable(self._eta_mvr_comp) and self._eta_mvr_comp <= 0.0
|
|
394
|
+
):
|
|
389
395
|
self._max_work *= 1e3
|
|
390
396
|
return None
|
|
391
397
|
if self._T_cond <= self._T_evap:
|
|
@@ -485,6 +491,7 @@ class MechanicalVapourRecompressionCycle(VapourCompressionCycle):
|
|
|
485
491
|
h_in=state0.hmass(),
|
|
486
492
|
s_in=state0.smass(),
|
|
487
493
|
P_out=P_hi,
|
|
494
|
+
suction=state0,
|
|
488
495
|
)
|
|
489
496
|
finally:
|
|
490
497
|
self._eta_comp = old_eta
|
|
@@ -202,6 +202,7 @@ class ParallelVapourCompressionCycles(_MultiVapourCompressionCycleBase):
|
|
|
202
202
|
dT_superheat: np.ndarray = 0.0,
|
|
203
203
|
dT_subcool: np.ndarray = 0.0,
|
|
204
204
|
eta_comp: float = 0.7,
|
|
205
|
+
eta_motor: float = 1.0,
|
|
205
206
|
refrigerant: List[str] | str = "water",
|
|
206
207
|
dT_ihx_gas_side: np.ndarray | float = 10.0,
|
|
207
208
|
Q_heat: np.ndarray | float | None = None,
|
|
@@ -226,6 +227,8 @@ class ParallelVapourCompressionCycles(_MultiVapourCompressionCycleBase):
|
|
|
226
227
|
Degree of subcooling after the condenser [K].
|
|
227
228
|
eta_comp : float, optional
|
|
228
229
|
Isentropic efficiency of the compressor [-].
|
|
230
|
+
eta_motor : float, optional
|
|
231
|
+
Efficiency of each compressor motor [-].
|
|
229
232
|
refrigerant : List[str] | str, optional
|
|
230
233
|
Cycle refrigerants; one per heat pump or a scalar value.
|
|
231
234
|
dT_ihx_gas_side : np.ndarray | float, optional
|
|
@@ -243,7 +246,7 @@ class ParallelVapourCompressionCycles(_MultiVapourCompressionCycleBase):
|
|
|
243
246
|
Returns
|
|
244
247
|
-------
|
|
245
248
|
float
|
|
246
|
-
Total compressor power
|
|
249
|
+
Total compressor electrical power for the solved operating point [W].
|
|
247
250
|
"""
|
|
248
251
|
self._solved = False
|
|
249
252
|
self._subcycles = []
|
|
@@ -285,6 +288,7 @@ class ParallelVapourCompressionCycles(_MultiVapourCompressionCycleBase):
|
|
|
285
288
|
dT_superheat=dT_superheat_all[i],
|
|
286
289
|
dT_subcool=dT_subcool_all[i],
|
|
287
290
|
eta_comp=eta_comp,
|
|
291
|
+
eta_motor=eta_motor,
|
|
288
292
|
refrigerant=refrigerant_all[i],
|
|
289
293
|
dT_ihx_gas_side=ihx_gas_dt_all[i],
|
|
290
294
|
Q_heat=Q_heat_all[i],
|