Some checks failed
CI / check (push) Has been cancelled
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>
149 lines
7.5 KiB
Markdown
149 lines
7.5 KiB
Markdown
# 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<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
|
||
|
||
```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.
|