Files
Entropyk/docs/adr/ADR-0001-multi-circuit-heat-exchanger-architecture.md
sepehr 5bd180b5b8
Some checks failed
CI / check (push) Has been cancelled
Snapshot WIP: solver HP epic progress, BPHX/HX physics, BMAD skill refresh.
Capture uncommitted solver robustness work (regularization, domain errors, linear solver lifecycle, tube DP/MSH), web workbench updates, and synced BMAD skills across IDE agent folders before starting BPHX pressure-drop.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 16:35:31 +02:00

7.5 KiB
Raw Blame History

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

pub struct MultiCircuitFloodedEvaporator {
    geometry: ShellAndTubeGeometry,        // new typed geometry (Phase B)
    circuits: Vec<FloodedCircuit>,          // 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

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 FloodedEvaporators + 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 (B1B5 in the audit) are resolved enough to validate the implementation.