# ADR-0001: Multi-Circuit Heat-Exchanger Architecture (DRAFT — Phase A) **Status:** Proposed (draft produced during Phase A audit) **Date:** 2026-07-16 **Decider:** Sepehr (architect review pending) **Supersedes:** none **Related:** `docs/audits/heat_exchanger_architecture_audit.md` (2026-07-16), `docs/audits/montluel_machine_coverage.md` (2026-07-16) ## Context The Phase A audit established that Entropyk has **no shared-vessel / multi-circuit heat-exchanger primitive**: - `FloodedEvaporator` is single-circuit (one inlet edge, one outlet edge; `flooded_evaporator.rs:57`). - The solver **rejects cross-circuit edges** (`TopologyError::CrossCircuitConnection`; `multi_circuit.rs:111`), so two refrigerant circuits cannot share a fluid volume. - The only inter-circuit heat mechanism is `ThermalCoupling` (`coupling.rs:52`), which transfers **duty via an external Q unknown**, not a shared volume. - `tests/multi_circuit.rs` validates only topology bookkeeping with zero-returning mocks — it does **not** test shared-vessel thermodynamics. Carrier reference (mission §5.1) describes a shared-vessel flooded evaporator (`61XWHVZE`-class): one vessel, two independent refrigerant circuits separated by an intermediate tube sheet, one common water circuit, standard 2-pass water with 1-/3-pass options. This topology cannot be represented today. Product geometry was **not provided**; this ADR fixes the architecture, not the fixture data. The audit also confirmed four reusable assets that constrain the design: `correlation_registry.rs` (evidence-aware registry), `bphx_geometry.rs` (typed geometry pattern), `bphx_correlation.rs` (formula↔registry binding), `two_phase_dp.rs` (analytic DP), and `entropyk_core::smoothing` (C¹/C² regularization with derivatives). ## Decision (proposed) Adopt a **dedicated multi-circuit exchanger component** with a shared secondary path, built on the existing registry/geometry/correlation pattern, rather than overloading the single-circuit component or faking a shared vessel with `ThermalCoupling`. ### 1. New component: `MultiCircuitFloodedEvaporator` ```rust pub struct MultiCircuitFloodedEvaporator { geometry: ShellAndTubeGeometry, // new typed geometry (Phase B) circuits: Vec, // N >= 1 secondary: SharedSecondaryPath, sizing: HeatExchangerSizing, // NominalUa | GeometryRated | CalibratedGeometry control: FloodedEvaporatorControl, // replaces target_quality=0.7 default calibration: MultiCircuitCalibration, } ``` - Refrigerant mass/energy conserved **independently per circuit** (no A↔B mixing). - Common secondary energy balance = `Σ Q_circuit`. - An OFF circuit has zero refrigerant flow and zero duty but does **not** make the active circuit singular (zero-flow-safe residuals, mission §7). - Allocated heat-transfer area follows physical partitioning. ### 2. New domain types (Phase B prerequisites, in `entropyk-core`) `Length`, `Mass`, `Area`, `TemperatureDifference`, `ThermalConductivity`, `Volume` (currently absent — audit §1.5). Plus `ShellAndTubeGeometry`, `RefrigerantPartition`, `TubeEnhancement`, `WaterBoxGeometry`, `FoulingResistances` (in `components`), validated per mission §6.1/§12.1. ### 3. Secondary layout is explicit and configurable ```rust pub enum SharedSecondaryLayout { CommonMixed, SequentialPartitions{..}, ParallelPartitions{..} } ``` The water path through refrigerant partitions is **not** chosen for Carrier equipment without evidence (audit; mission §6.4). Default to configurable; flag required product input. ### 4. Control semantics corrected (mission §3) Replace the `target_quality = 0.7` default with an explicit enum: `FloodedEvaporatorControl::{FixedLevel, Pinch, OutletSuperheat, FixedRefrigerantCharge, External}`. The outlet port's physical meaning (suction vs. recirculation vs. separator inlet) is documented per variant. A legacy quality-control mode is retained only behind a documented migration flag (audit §3.1). ### 5. Zero-flow handling via smooth blending (mission §7.2) Build on `entropyk_core::smoothing` (`smooth_abs`, `cubic_blend`, `smooth_max`). No hard `if |m| < ε { Q = 0 }` branches. Analytic derivatives verified at `m = 0`, near-zero, and normal flow. Pressure drop uses a regularized odd function of flow. ### 6. Jacobian Analytic throughout, including the zero-flow blending and `dT_sat/dP`. Because the backend exposes no `dT_sat/dP` (audit §7), add a single documented central-FD backend method `saturation_temperature_derivative_dp` (cacheable) as the single source of truth, with an optional CoolProp analytic-derivative upgrade later. ### 7. Correlations via the existing registry Extend `correlation_registry` + a new `shell_tube_correlation` module (pool boiling Cooper/Gorenflo baseline; tube-bundle condensation; Gnielinski water-side; Darcy-Weisbach + water-box minor losses). **Do not** apply internal-flow boiling correlations to shell-side flooded boiling without documented justification (mission §6.2). ## Alternatives considered - **A. Overload single-circuit `FloodedEvaporator` with two refrigerant port pairs.** Rejected: breaks the edge model (solver rejects cross-circuit edges), conflates suction outlet with shared-volume representation, and cannot guarantee independent A/B mass conservation. - **B. Compose two `FloodedEvaporator`s + a `ThermalCoupling`.** Rejected as the *primary* model: `ThermalCoupling` transfers duty, not a shared water inventory; the common water energy balance and shared geometry/partitioning would be lost. This composition remains valid for **dual-module** machines (mission §5.2, separate modules) — handled in Phase E. - **C. Defer to a generic N-port exchanger.** Rejected: the shared-vessel physics (common secondary, partitioned area, flooded boiling) is specific enough to deserve a typed component; a generic N-port wrapper would re-introduce the current ambiguities. ## Consequences - **Positive:** unblocks Montluel archetypes M2, M4-dual, M12; enables circuit-specific calibration and one-circuit-off operation; aligns flooded exchangers with the registry/geometry pattern already proven for BPHX. - **Negative:** new public API surface (migration path required — `from_nominal_ua` helper); larger equation count per component (residual scaling needed — mission §9.5); requires the Phase B geometry/correlation foundations first. - **Risk:** zero-flow blending Jacobian correctness — mitigated by Jacobian-vs-FD parity tests across all modes (mission §9.4) as a hard gate. ## Open questions (block finalization) 1. Carrier water-path layout through refrigerant partitions (drives `SharedSecondaryLayout` default) — **data not provided**. 2. Whether a legacy `target_quality` control mode has any real supported use case (mission §3.6) — needs Sepehr's confirmation before deprecation. 3. CoolProp analytic-derivative wiring priority vs. central-FD fallback sufficiency. ## Phasing - Phase B: domain types + geometry + correlation extension + `dT_sat/dP` method + zero-flow regularization utility. - Phase C: single-circuit `FloodedEvaporator` rewrite (rating vs coupled, geometry UA, control semantics, zero-flow-safe analytic Jacobian, migration). - Phase D: `MultiCircuitFloodedEvaporator` + shared secondary + one-circuit-off. - Phase E: dual-module composition (alternative B, for separate modules) + dual-circuit BPHX. - Phase F: CLI/bindings/examples/fixtures + validation. This ADR is **draft** until architect review and until the Phase A blockers (B1–B5 in the audit) are resolved enough to validate the implementation.