Snapshot WIP: solver HP epic progress, BPHX/HX physics, BMAD skill refresh.
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>
This commit is contained in:
2026-07-19 16:35:31 +02:00
parent 88620790d6
commit 5bd180b5b8
1363 changed files with 101041 additions and 58547 deletions

View File

@@ -0,0 +1,148 @@
# 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 (B1B5 in the
audit) are resolved enough to validate the implementation.