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.
Files changed (497) hide show
  1. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/README.md +2 -2
  2. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/README.md +1 -1
  3. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/executor.py +8 -1
  4. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/README.md +6 -0
  5. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/README.md +5 -1
  6. openpinch-0.8.3/OpenPinch/analysis/heat_pumps/common/compressor_efficiency.py +136 -0
  7. openpinch-0.8.3/OpenPinch/analysis/heat_pumps/common/load_kinks.py +127 -0
  8. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/preprocessing.py +21 -4
  9. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/README.md +4 -1
  10. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/cascade_vapour_compression_cycle.py +4 -0
  11. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/mechanical_vapour_recompression_cycle.py +10 -3
  12. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/parallel_vapour_compression_cycles.py +5 -1
  13. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/vapour_compression_cycle.py +57 -7
  14. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/vapour_compression_mvr_cascade.py +12 -1
  15. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/README.md +4 -4
  16. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/generation.py +4 -2
  17. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/target_basis.py +9 -0
  18. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/target_records.py +45 -3
  19. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/targeting.py +6 -0
  20. openpinch-0.8.3/OpenPinch/analysis/heat_pumps/refrigerant_screen.py +178 -0
  21. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/README.md +2 -0
  22. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/cascade_vapour_compression.py +6 -3
  23. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/parallel_vapour_compression.py +1 -0
  24. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/vapour_compression_mvr.py +2 -1
  25. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/README.md +7 -3
  26. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/accessors/README.md +5 -4
  27. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/accessors/target.py +73 -0
  28. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/README.md +2 -1
  29. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/catalog.py +7 -0
  30. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/heat_recovery_dt_min.py +2 -1
  31. openpinch-0.8.3/OpenPinch/application/hpr_load_kinks.py +182 -0
  32. openpinch-0.8.3/OpenPinch/application/hpr_refrigerant_screen.py +155 -0
  33. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/workspace.py +34 -1
  34. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/README.md +7 -1
  35. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/hpr.py +6 -2
  36. openpinch-0.8.3/OpenPinch/contracts/hpr_load_kinks.py +133 -0
  37. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/hpr_performance_map.py +8 -2
  38. openpinch-0.8.3/OpenPinch/contracts/hpr_refrigerant_screen.py +115 -0
  39. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/hpr_performance_map/heat-pump-1.0.json +1 -0
  40. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/hpr_performance_map/refrigeration-1.0.json +1 -0
  41. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/hpr_performance_map/schema-1.0.json +7 -0
  42. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/schema.py +4 -0
  43. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/units.py +28 -1
  44. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/README.md +4 -2
  45. openpinch-0.8.3/OpenPinch/domain/compressor_model.py +35 -0
  46. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/configuration.py +12 -6
  47. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/configuration_fields.py +30 -1
  48. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/fluids.py +24 -1
  49. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/configuration_text.py +39 -0
  50. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/README.md +1 -1
  51. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/specialist.py +4 -0
  52. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/06_multiperiod_heat_integration.ipynb +8 -1
  53. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/08_carnot_heat_pump_and_refrigeration.ipynb +92 -13
  54. {openpinch-0.8.2 → openpinch-0.8.3}/PKG-INFO +1 -1
  55. {openpinch-0.8.2 → openpinch-0.8.3}/pyproject.toml +1 -1
  56. {openpinch-0.8.2 → openpinch-0.8.3}/.gitignore +0 -0
  57. {openpinch-0.8.2 → openpinch-0.8.3}/LICENSE +0 -0
  58. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/README.md +0 -0
  59. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/__init__.py +0 -0
  60. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/__main__.py +0 -0
  61. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/README.md +0 -0
  62. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/__init__.py +0 -0
  63. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/README.md +0 -0
  64. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/__init__.py +0 -0
  65. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/csv.py +0 -0
  66. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/file_exports.py +0 -0
  67. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/json.py +0 -0
  68. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/problem_sources.py +0 -0
  69. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/records.py +0 -0
  70. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/tabular.py +0 -0
  71. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/workbook.py +0 -0
  72. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/io/workspace_bundles.py +0 -0
  73. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/adapters/optional_dependencies.py +0 -0
  74. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/README.md +0 -0
  75. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/__init__.py +0 -0
  76. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/economics.py +0 -0
  77. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/README.md +0 -0
  78. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/__init__.py +0 -0
  79. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/cascade.py +0 -0
  80. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/diagram.py +0 -0
  81. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/selection.py +0 -0
  82. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/serialization.py +0 -0
  83. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/energy_transfer/service.py +0 -0
  84. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/exergy/README.md +0 -0
  85. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/exergy/__init__.py +0 -0
  86. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/exergy/service.py +0 -0
  87. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/README.md +0 -0
  88. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/__init__.py +0 -0
  89. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/composite.py +0 -0
  90. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/grand_composite.py +0 -0
  91. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/metadata.py +0 -0
  92. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/primitives.py +0 -0
  93. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/service.py +0 -0
  94. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/graphs/specifications.py +0 -0
  95. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/__init__.py +0 -0
  96. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/context.py +0 -0
  97. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/controllability.py +0 -0
  98. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/duty_optimisation.py +0 -0
  99. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/errors.py +0 -0
  100. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/__init__.py +0 -0
  101. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/fake_executor.py +0 -0
  102. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/fallbacks.py +0 -0
  103. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/pathways.py +0 -0
  104. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/settings.py +0 -0
  105. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/execution/task_builders.py +0 -0
  106. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/README.md +0 -0
  107. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/__init__.py +0 -0
  108. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/metadata.py +0 -0
  109. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/period_state.py +0 -0
  110. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/recovery.py +0 -0
  111. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/segment_area.py +0 -0
  112. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/service.py +0 -0
  113. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/extraction/utility.py +0 -0
  114. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/indexing.py +0 -0
  115. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/README.md +0 -0
  116. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/__init__.py +0 -0
  117. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/README.md +0 -0
  118. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/__init__.py +0 -0
  119. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/alpha.py +0 -0
  120. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/approach.py +0 -0
  121. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/area.py +0 -0
  122. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/costing.py +0 -0
  123. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/execution.py +0 -0
  124. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/parameters.py +0 -0
  125. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/piecewise.py +0 -0
  126. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_base/superstructure.py +0 -0
  127. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_pinch_design/README.md +0 -0
  128. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_pinch_design/__init__.py +0 -0
  129. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_pinch_design/amalgamation.py +0 -0
  130. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_pinch_design/equations.py +0 -0
  131. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_pinch_design/postprocess.py +0 -0
  132. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_pinch_design/preprocessing.py +0 -0
  133. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/README.md +0 -0
  134. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/__init__.py +0 -0
  135. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/equations.py +0 -0
  136. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/evolution.py +0 -0
  137. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/objectives.py +0 -0
  138. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/postprocess.py +0 -0
  139. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/setup.py +0 -0
  140. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/verification.py +0 -0
  141. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/_stagewise/warm_start.py +0 -0
  142. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/base.py +0 -0
  143. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/fixed_structure.py +0 -0
  144. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/packed_pinch_design.py +0 -0
  145. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/packed_stagewise.py +0 -0
  146. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/pinch_decomposition.py +0 -0
  147. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/problem.py +0 -0
  148. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/stage_packing.py +0 -0
  149. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/stagewise.py +0 -0
  150. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/models/thermal_profiles.py +0 -0
  151. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/prepared_problem.py +0 -0
  152. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/reporting/README.md +0 -0
  153. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/reporting/__init__.py +0 -0
  154. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/reporting/exports.py +0 -0
  155. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/reporting/ranking.py +0 -0
  156. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/reporting/verification.py +0 -0
  157. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/results/README.md +0 -0
  158. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/results/__init__.py +0 -0
  159. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/results/assembly.py +0 -0
  160. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/results/seeds.py +0 -0
  161. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/results/selection.py +0 -0
  162. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/service.py +0 -0
  163. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/README.md +0 -0
  164. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/__init__.py +0 -0
  165. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/arrays.py +0 -0
  166. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/backend.py +0 -0
  167. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/dependencies.py +0 -0
  168. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/piecewise.py +0 -0
  169. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/solver/pinch_design_decomposition.py +0 -0
  170. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/README.md +0 -0
  171. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/__init__.py +0 -0
  172. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/_stage.py +0 -0
  173. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/network_evolution_method.py +0 -0
  174. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/open_hens_method.py +0 -0
  175. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/pinch_design_method.py +0 -0
  176. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/thermal_derivative_method.py +0 -0
  177. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_exchanger_networks/targeting/topology.py +0 -0
  178. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/__init__.py +0 -0
  179. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/README.md +0 -0
  180. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/__init__.py +0 -0
  181. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/aggregation.py +0 -0
  182. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/execution.py +0 -0
  183. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/preparation.py +0 -0
  184. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/setup.py +0 -0
  185. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_multiperiod/state.py +0 -0
  186. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/README.md +0 -0
  187. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/__init__.py +0 -0
  188. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/membership.py +0 -0
  189. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/replacement_streams.py +0 -0
  190. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/selection.py +0 -0
  191. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/state.py +0 -0
  192. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/values.py +0 -0
  193. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/_process_mvr/work.py +0 -0
  194. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/__init__.py +0 -0
  195. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/_shared/README.md +0 -0
  196. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/_shared/__init__.py +0 -0
  197. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/_shared/air.py +0 -0
  198. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/_shared/plotting.py +0 -0
  199. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/_shared/streams.py +0 -0
  200. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/encoding.py +0 -0
  201. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/layout.py +0 -0
  202. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/load_selection.py +0 -0
  203. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/multi_vc_objective.py +0 -0
  204. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/postprocessing.py +0 -0
  205. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/shared.py +0 -0
  206. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/common/units.py +0 -0
  207. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/components.py +0 -0
  208. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/__init__.py +0 -0
  209. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/_multi_cycle_base.py +0 -0
  210. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/brayton_heat_pump.py +0 -0
  211. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/cycles/carnot_cycles.py +0 -0
  212. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/direct_mvr/README.md +0 -0
  213. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/direct_mvr/__init__.py +0 -0
  214. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/direct_mvr/execution.py +0 -0
  215. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/direct_mvr/models.py +0 -0
  216. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/direct_mvr/thermodynamics.py +0 -0
  217. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/direct_mvr/units.py +0 -0
  218. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/optimisation_adapter.py +0 -0
  219. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/__init__.py +0 -0
  220. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/adapters/README.md +0 -0
  221. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/adapters/__init__.py +0 -0
  222. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/adapters/coolprop.py +0 -0
  223. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/adapters/tespy.py +0 -0
  224. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/characteristics/README.md +0 -0
  225. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/characteristics/__init__.py +0 -0
  226. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/characteristics/openpinch-single-stage-compressor-v1.json +0 -0
  227. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/context.py +0 -0
  228. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/coolprop_preflight.py +0 -0
  229. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/errors.py +0 -0
  230. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/factory.py +0 -0
  231. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/fluids.py +0 -0
  232. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/models.py +0 -0
  233. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/points.py +0 -0
  234. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/protocols.py +0 -0
  235. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/provenance.py +0 -0
  236. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/resources.py +0 -0
  237. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/settings.py +0 -0
  238. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/performance_maps/targeting_models.py +0 -0
  239. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/process_mvr.py +0 -0
  240. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/service.py +0 -0
  241. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/__init__.py +0 -0
  242. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/_carnot_common.py +0 -0
  243. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/brayton.py +0 -0
  244. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/cascade_carnot.py +0 -0
  245. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_pumps/targeting/parallel_carnot.py +0 -0
  246. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/heat_transfer.py +0 -0
  247. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/numerics.py +0 -0
  248. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/README.md +0 -0
  249. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/__init__.py +0 -0
  250. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/carnot.py +0 -0
  251. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/costing.py +0 -0
  252. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/cycle.py +0 -0
  253. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/inputs.py +0 -0
  254. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/profile.py +0 -0
  255. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/search.py +0 -0
  256. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/service.py +0 -0
  257. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/orc/simulated.py +0 -0
  258. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/parallelism.py +0 -0
  259. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/power/README.md +0 -0
  260. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/power/__init__.py +0 -0
  261. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/power/service.py +0 -0
  262. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/power/steam_turbine.py +0 -0
  263. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/README.md +0 -0
  264. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/__init__.py +0 -0
  265. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/area_cost.py +0 -0
  266. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/cascade.py +0 -0
  267. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/context.py +0 -0
  268. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/direct.py +0 -0
  269. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/grand_composite.py +0 -0
  270. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/heat_recovery_dt_min.py +0 -0
  271. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/indirect.py +0 -0
  272. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/residual.py +0 -0
  273. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/temperature_driving_force.py +0 -0
  274. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/targeting/utilities.py +0 -0
  275. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/thermodynamics/README.md +0 -0
  276. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/thermodynamics/__init__.py +0 -0
  277. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/thermodynamics/water.py +0 -0
  278. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/README.md +0 -0
  279. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/__init__.py +0 -0
  280. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/allocation.py +0 -0
  281. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/bounds.py +0 -0
  282. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/codec.py +0 -0
  283. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/context.py +0 -0
  284. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/errors.py +0 -0
  285. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/evaluation.py +0 -0
  286. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/normalization.py +0 -0
  287. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/optimisation.py +0 -0
  288. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/penalties.py +0 -0
  289. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/profiles.py +0 -0
  290. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/replay.py +0 -0
  291. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/service.py +0 -0
  292. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/start_points.py +0 -0
  293. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/thermodynamics.py +0 -0
  294. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/analysis/utility_placement/units.py +0 -0
  295. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/__init__.py +0 -0
  296. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/README.md +0 -0
  297. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/__init__.py +0 -0
  298. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/accessors/__init__.py +0 -0
  299. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/accessors/component.py +0 -0
  300. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/accessors/design.py +0 -0
  301. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/accessors/plot.py +0 -0
  302. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/arguments.py +0 -0
  303. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/README.md +0 -0
  304. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/__init__.py +0 -0
  305. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/canonicalization.py +0 -0
  306. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/construction.py +0 -0
  307. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/loading.py +0 -0
  308. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/segments.py +0 -0
  309. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/semantics.py +0 -0
  310. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/utilities.py +0 -0
  311. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/input/validation.py +0 -0
  312. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/output/README.md +0 -0
  313. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/output/__init__.py +0 -0
  314. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/output/reporting.py +0 -0
  315. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/output/result_extraction.py +0 -0
  316. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/periods/README.md +0 -0
  317. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/periods/__init__.py +0 -0
  318. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/periods/aggregation.py +0 -0
  319. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/__init__.py +0 -0
  320. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/dispatch.py +0 -0
  321. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/execution.py +0 -0
  322. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/provenance.py +0 -0
  323. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_problem/targeting/state.py +0 -0
  324. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_workspace/README.md +0 -0
  325. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_workspace/__init__.py +0 -0
  326. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_workspace/case_inputs.py +0 -0
  327. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/_workspace/state.py +0 -0
  328. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/case_derivation.py +0 -0
  329. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/commands.py +0 -0
  330. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/hpr_selection.py +0 -0
  331. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/problem.py +0 -0
  332. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/residual_utility.py +0 -0
  333. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/targeting.py +0 -0
  334. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/application/utility_placement.py +0 -0
  335. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/__init__.py +0 -0
  336. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/common.py +0 -0
  337. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/controllability.py +0 -0
  338. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/graphs.py +0 -0
  339. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/heat_recovery_dt_min.py +0 -0
  340. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/input.py +0 -0
  341. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/output.py +0 -0
  342. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/report_metrics.py +0 -0
  343. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/report_units.py +0 -0
  344. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/reporting.py +0 -0
  345. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/README.md +0 -0
  346. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/__init__.py +0 -0
  347. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/hpr_performance_map/README.md +0 -0
  348. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/resources/hpr_performance_map/__init__.py +0 -0
  349. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/README.md +0 -0
  350. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/__init__.py +0 -0
  351. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/common.py +0 -0
  352. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/method.py +0 -0
  353. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/result.py +0 -0
  354. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/task.py +0 -0
  355. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/topology.py +0 -0
  356. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/synthesis/view.py +0 -0
  357. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/turbine.py +0 -0
  358. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/utility_placement.py +0 -0
  359. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/contracts/workspace.py +0 -0
  360. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/__init__.py +0 -0
  361. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger/README.md +0 -0
  362. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger/__init__.py +0 -0
  363. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger/area.py +0 -0
  364. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger/period_state.py +0 -0
  365. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger/rules.py +0 -0
  366. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger_network/README.md +0 -0
  367. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger_network/__init__.py +0 -0
  368. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_heat_exchanger_network/types.py +0 -0
  369. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_problem_table/README.md +0 -0
  370. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_problem_table/__init__.py +0 -0
  371. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_problem_table/constants.py +0 -0
  372. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_problem_table/equality.py +0 -0
  373. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_problem_table/intervals.py +0 -0
  374. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_problem_table/types.py +0 -0
  375. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/README.md +0 -0
  376. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/__init__.py +0 -0
  377. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/linearisation.py +0 -0
  378. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/profile.py +0 -0
  379. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/segment.py +0 -0
  380. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/segments.py +0 -0
  381. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/thermodynamics.py +0 -0
  382. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream/value_state.py +0 -0
  383. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream_collection/README.md +0 -0
  384. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream_collection/__init__.py +0 -0
  385. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream_collection/filters.py +0 -0
  386. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream_collection/numeric_view.py +0 -0
  387. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream_collection/serialization.py +0 -0
  388. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_stream_collection/sorting.py +0 -0
  389. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_validation.py +0 -0
  390. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_value/README.md +0 -0
  391. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_value/__init__.py +0 -0
  392. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_value/coercion.py +0 -0
  393. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_value/resolution.py +0 -0
  394. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/_value/units.py +0 -0
  395. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/analysis.py +0 -0
  396. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/enums.py +0 -0
  397. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/heat_exchanger.py +0 -0
  398. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/heat_exchanger_network.py +0 -0
  399. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/hpr.py +0 -0
  400. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/problem_table.py +0 -0
  401. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/progress.py +0 -0
  402. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/solver_options.py +0 -0
  403. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/stream.py +0 -0
  404. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/stream_collection.py +0 -0
  405. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/targets.py +0 -0
  406. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/value.py +0 -0
  407. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/domain/zone.py +0 -0
  408. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/README.md +0 -0
  409. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/__init__.py +0 -0
  410. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/README.md +0 -0
  411. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/__init__.py +0 -0
  412. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/_multistart.py +0 -0
  413. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/_surrogate.py +0 -0
  414. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/bayesian.py +0 -0
  415. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/cma_es.py +0 -0
  416. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/dual_annealing.py +0 -0
  417. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/protocol.py +0 -0
  418. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/backends/rbf.py +0 -0
  419. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/candidates.py +0 -0
  420. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/errors.py +0 -0
  421. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/execution.py +0 -0
  422. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/feasibility.py +0 -0
  423. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/models.py +0 -0
  424. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/optimisation/service.py +0 -0
  425. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/README.md +0 -0
  426. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/__init__.py +0 -0
  427. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/configuration.py +0 -0
  428. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/README.md +0 -0
  429. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/__init__.py +0 -0
  430. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/dashboard.css +0 -0
  431. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/dependencies.py +0 -0
  432. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/exports.py +0 -0
  433. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/rendering.py +0 -0
  434. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/dashboard/state.py +0 -0
  435. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/graphs/README.md +0 -0
  436. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/graphs/__init__.py +0 -0
  437. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/graphs/plotly.py +0 -0
  438. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/graphs/problem.py +0 -0
  439. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/graphs/simple.py +0 -0
  440. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/README.md +0 -0
  441. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/__init__.py +0 -0
  442. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/_constants.py +0 -0
  443. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/dependencies.py +0 -0
  444. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/geometry.py +0 -0
  445. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/labels.py +0 -0
  446. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/layout.py +0 -0
  447. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/plotly.py +0 -0
  448. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/rendering.py +0 -0
  449. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/results.py +0 -0
  450. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/service.py +0 -0
  451. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/state.py +0 -0
  452. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/temperatures.py +0 -0
  453. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/network_grid/view.py +0 -0
  454. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/__init__.py +0 -0
  455. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/adapters.py +0 -0
  456. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/excel_text.py +0 -0
  457. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/hpr.py +0 -0
  458. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/problem_table.py +0 -0
  459. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/results.py +0 -0
  460. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/stream_collection.py +0 -0
  461. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/thermal.py +0 -0
  462. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/presentation/reporting/workbook.py +0 -0
  463. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/resources.py +0 -0
  464. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/README.md +0 -0
  465. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/__init__.py +0 -0
  466. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/01_first_solve_and_core_curves.ipynb +0 -0
  467. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/02_focused_direct_and_total_site.ipynb +0 -0
  468. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/03_multisegment_streams.ipynb +0 -0
  469. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/04_workspace_cases_and_scenarios.ipynb +0 -0
  470. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/05_workspace_persistence.ipynb +0 -0
  471. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/07_area_cost_and_exergy.ipynb +0 -0
  472. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/09_vapour_compression.ipynb +0 -0
  473. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/10_multiperiod_heat_pumps.ipynb +0 -0
  474. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/11_process_mvr_and_cascade.ipynb +0 -0
  475. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/12_cogeneration.ipynb +0 -0
  476. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/13_multiperiod_cogeneration.ipynb +0 -0
  477. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/14_energy_transfer.ipynb +0 -0
  478. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/15_hen_synthesis_and_selection.ipynb +0 -0
  479. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/16_advanced_hen_methods.ipynb +0 -0
  480. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/17_multiperiod_hen_synthesis.ipynb +0 -0
  481. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/18_results_plots_reports_exports.ipynb +0 -0
  482. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/19_utility_placement_optimisation.ipynb +0 -0
  483. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/README.md +0 -0
  484. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/notebooks/__init__.py +0 -0
  485. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/Four-stream-Yee-and-Grossmann-1990-1.json +0 -0
  486. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/README.md +0 -0
  487. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/__init__.py +0 -0
  488. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/basic_pinch.json +0 -0
  489. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/chocolate_factory.json +0 -0
  490. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/crude_preheat_train.json +0 -0
  491. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/crude_preheat_train_multiperiod.json +0 -0
  492. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/dairy_chilling_multiperiod.json +0 -0
  493. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/process_mvr.json +0 -0
  494. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/pulp_mill.json +0 -0
  495. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/zonal_site.json +0 -0
  496. {openpinch-0.8.2 → openpinch-0.8.3}/OpenPinch/tutorials/sample_cases/zonal_site_multiperiod.json +0 -0
  497. {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
@@ -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].
@@ -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=hpr.eta_comp,
110
- eta_mvr_comp=hpr.mvr_eta_comp,
111
- eta_motor=hpr.mvr_eta_motor,
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 = float(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._eta_mvr_comp <= 0.0 or self._eta_motor <= 0.0:
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 requirement for the solved operating point [W].
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],