Internal Service Layer

These modules are contributor implementation owners. Process-engineer code uses OpenPinch.PinchProblem or OpenPinch.PinchWorkspace. The service layer is the boundary between validated input data and the prepared/solved in-memory model. It is the right integration surface when you want more control than PinchProblem provides but do not want to invoke individual low-level algorithms directly.

Layering

The service stack is designed in three steps:

  1. validate or receive typed request data

  2. prepare the inputs into a Zone hierarchy

  3. dispatch direct, indirect, HPR, exergy, cogeneration, or area/cost targeting

Use Cases

Use the service layer when you need to:

  • develop repository applications that need more control than the supported request/response boundary

  • prepare a zone hierarchy once and run multiple advanced studies against it

  • inspect the prepared model before solving

  • mutate a live prepared model with process components before rerunning targets

  • bypass file handling entirely and work with typed inputs

  • apply exergy or cogeneration as post-processing on already solved targets

Main Service Surface

Deterministic engineering analyses and specialist calculations.

Preparation Entry Point

The preparation stage is the key boundary between external inputs and the internal model. It validates configuration choices, builds the zone tree, applies dt_cont multipliers, instantiates process and utility streams, and produces the Zone object consumed by the solver stack.

Period-valued inputs remain period-aware after preparation, but period selection does not happen inside prepare_problem(...). Instead, the selected period is applied later through the targeting-service args dictionaries or the higher level problem.target.*(..., period_id=...) wrappers.

OpenPinch.application._problem.input.construction.prepare_problem(streams=None, utilities=None, options=None, project_name='Site', zone_tree=None)[source]

Build the top-level zone hierarchy for analysis.

Parameters:
  • streams (List[StreamSchema] | None)

  • utilities (List[UtilitySchema] | None)

  • options (Dict[str, Any] | None)

  • project_name (str)

  • zone_tree (ZoneTreeSchema)

Return type:

Zone

Heat Exchanger Network Synthesis Entry

Heat exchanger network synthesis is problem-rooted. User code should normally enter through PinchProblem.design:

problem.design.enhanced_heat_exchanger_network(quality_tier=2)
problem.design.open_hens()
problem.design.heat_exchanger_network()
problem.design.multiperiod_heat_exchanger_network()
problem.design.network_evolution((existing_network,))

The internal service entry point owns method dispatch and final result caching. It dispatches to the same direct services exposed by the design accessor. Each named method selects one workflow without a method-name string.

Service entry and dispatch for heat exchanger network synthesis.

OpenPinch.analysis.heat_exchanger_networks.service.heat_exchanger_network_evolution_method_service(problem, *, initial_networks=None, options=None, workspace_variant=None, executor=None)[source]

Run only seeded network evolution and update the problem cache.

Parameters:
Return type:

HeatExchangerNetworkSynthesisResult

OpenPinch.analysis.heat_exchanger_networks.service.heat_exchanger_network_open_hens_method_service(problem, *, options=None, workspace_variant=None, executor=None)[source]

Run the original tier-1 OpenHENS PDM -> TDM -> EVM sequence.

Parameters:
  • problem (PinchProblem)

  • options (dict[str, Any] | None)

  • workspace_variant (str | None)

  • executor (SynthesisExecutor | None)

Return type:

HeatExchangerNetworkSynthesisResult

OpenPinch.analysis.heat_exchanger_networks.service.heat_exchanger_network_pinch_design_method_service(problem, *, options=None, workspace_variant=None, executor=None)[source]

Run only the pinch design method and update the problem cache.

Parameters:
  • problem (PinchProblem)

  • options (dict[str, Any] | None)

  • workspace_variant (str | None)

  • executor (SynthesisExecutor | None)

Return type:

HeatExchangerNetworkSynthesisResult

OpenPinch.analysis.heat_exchanger_networks.service.heat_exchanger_network_synthesis_service(problem, *, method=None, initial_networks=None, options=None, workspace_variant=None, executor=None)[source]

Dispatch one HEN design method and update the problem cache.

Parameters:
Return type:

HeatExchangerNetworkSynthesisResult

OpenPinch.analysis.heat_exchanger_networks.service.heat_exchanger_network_thermal_derivative_method_service(problem, *, initial_networks=None, options=None, workspace_variant=None, executor=None)[source]

Run only seeded TDM and update the problem cache.

Parameters:
Return type:

HeatExchangerNetworkSynthesisResult

The HEN synthesis package is intentionally method-oriented:

  • targeting contains method-specific orchestration.

  • execution contains settings, task builders, executor contracts, and fallback policy.

  • results contains result assembly and seed lookup.

  • reporting contains ranking, verification, and export helpers.

  • solver contains optional-dependency checks, array adapters, backend calls, and network extraction.

  • models contains the equation/unit model layer for pinch design and stagewise models.

Network Grid Diagrams

The presentation owner constructs a grid diagram from the selected heat exchanger network:

from OpenPinch.presentation.network_grid.service import build_grid_diagram

design = problem.results.design
period_id = design.network.period_ids[0]
diagram = build_grid_diagram(design.network, period_id=period_id)

The standalone service remains available for batch rendering one or more HeatExchangerNetwork objects, for example when displaying several ranked candidates.

Service entrypoint for heat exchanger network grid diagrams.

OpenPinch.presentation.network_grid.service.build_grid_diagram(networks, *, index=None, period_id=None, temperature_scaled=False)[source]

Return OpenHENS-style grid diagrams for one or more networks.

Parameters:
Return type:

HeatExchangerNetworkGridDiagram | tuple[HeatExchangerNetworkGridDiagram, …]

Network Controllability

Solved heat exchanger networks can also be screened for steady-state controllability. The service treats process-stream outlet temperatures as controlled outputs and practical bypass or utility-flow adjustments as manipulated variables, then scores the resulting duty-normalised interaction matrix.

For multiperiod networks, pass period_id to both diagram and controllability services. OpenPinch does not silently select period zero.

design = problem.results.design
period_id = design.network.period_ids[0]
assessment = design.network.quantify_controllability(period_id=period_id)
assessment.score
assessment.components.rank

The score is a screening metric rather than a dynamic closed-loop simulation. It is intended for comparing candidate HEN topologies and identifying networks with weak actuator coverage, poor pairing, low thermal margin, or insufficient control redundancy.

Steady-state controllability analysis for heat exchanger networks.

OpenPinch.analysis.heat_exchanger_networks.controllability.quantify_heat_exchanger_network_controllability(network, *, period_id=None, active_only=True, include_utility_actuators=True, minimum_interaction=1e-09, minimum_approach_temperature=5.0, desired_redundancy=2, rank_tolerance=None, condition_warning_threshold=25.0)[source]

Return a 0-1 controllability assessment for a solved HeatExchangerNetworkLabel.

The service builds a steady-state interaction matrix from available network data. Rows are process-stream outlet temperatures, columns are practical manipulated variables: recovery bypass fractions and utility flow rates. Entries are duty-normalised thermal authority values, which provide a deterministic controllability proxy when no dynamic HEN model is available.

Parameters:
  • network (HeatExchangerNetwork)

  • period_id (str | None)

  • active_only (bool)

  • include_utility_actuators (bool)

  • minimum_interaction (float)

  • minimum_approach_temperature (float)

  • desired_redundancy (int)

  • rank_tolerance (float | None)

  • condition_warning_threshold (float)

Return type:

HeatExchangerNetworkControllabilityResult

Typical Preparation and Solve Pattern

from OpenPinch.contracts.input import TargetInput
from OpenPinch.analysis import (
    data_preprocessing_service,
    direct_heat_integration_service,
    indirect_heat_integration_service,
)

source_data = {"streams": [...], "utilities": [...]}
input_data = TargetInput.model_validate(source_data)
zone = data_preprocessing_service(input_data, project_name="Example")

direct_heat_integration_service(zone, {"period_id": "peak"})
indirect_heat_integration_service(zone, {"period_id": "peak"})

Each targeting service mutates the prepared zone in place, records the requested period metadata on the zone, and adds or refreshes the corresponding target model.

The exergy service follows a slightly different contract from the base thermal targeting services: it enriches an already existing compatible target for the requested period instead of re-solving direct or indirect targeting internally.

Application Facade

The supported orchestration facade is documented in PinchProblem and PinchWorkspace.

Choosing Between Interfaces

  • Use OpenPinch.PinchProblem for supported application integration.

  • Use problem.components.add_process_mvr(...) when the study needs direct gas/vapour MVR stream replacement before ordinary target reruns.

  • Use concrete analysis owners for repository development or advanced research.

The service layer is also the best place to look when you are trying to understand how the narrative workflow maps onto the actual analysis pipeline.