Add diagram workbench UI with Modelica DoF coaching and ISO glyphs.

Ship the Next.js cycle editor with CAD chrome, technical HX symbols, Fixed/Free boundary guidance, and secondary water/air pressure drop support in the solver stack.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-17 22:46:46 +02:00
parent 62efea0646
commit 3358b74342
275 changed files with 70187 additions and 5230 deletions

View File

@@ -0,0 +1,124 @@
# Condenser / CondenserCoil
Config types: `"Condenser"`, `"CondenserCoil"`
Source: `crates/components/src/heat_exchanger/condenser.rs`
---
## EN
### Purpose & physical model
Refrigerant **condenser** rejecting heat to a secondary stream (water/glycol or air). Coupled duty is **phase-change ε-NTU** (isothermal refrigerant side at `T_cond(P)`):
```
ε = 1 exp(UA_eff / C_sec)
Q = ε · C_sec · (T_cond(P_in) T_sec,in) # heat rejected by refrigerant
```
- Optional lumped refrigerant ΔP: `ΔP = k · ṁ · |ṁ|`
- `CondenserCoil` locks secondary side to **Air** conventions
- **No plate correlation** here (see BPHX for Longo/Shah geometry UA)
`UA_eff` can be reduced by flooded-level actuator; `C_sec` can be scaled by fan speed φ when fan head-pressure is active.
### Dual secondary modes (Newton)
| Mode | Secondary source | `n_secondary` |
|------|------------------|---------------|
| **System** | Live edges ports 2/3 (`secondary_inlet` / `secondary_outlet`) | 1 or 2 |
| **Rating** | Scalars `secondary_inlet_temp_*` + capacity rate / ṁ·cp | 0 |
`coupled_ready` requires refrigerant indices **and** (live edges **or** rating scalars).
`live_secondary_stream` prefers edges; falls back to rating scalars (with fan φ scaling of `C_sec` when applicable).
### Residuals & `n_equations()` (coupled)
| Row | Equation |
|-----|----------|
| r0 | `P_out (P_in ΔP)` (skippable) |
| r1 | `ṁ · (h_in h_out) Q` |
| r2 (emergent) | `h_out h(P, T_cond SC)` subcooling closure |
| r_mass | `ṁ_out ṁ_in` if not same-branch |
| r_head (optional) | `T_cond T_target` (fan **or** flooded head-pressure) |
| r_sec | live secondary mass/energy only if edges present |
```
n_equations = n_thermo + (mass?) + (head?) + n_secondary
n_thermo = 2 normally, 3 with emergent_pressure (+ subcooling residual)
```
### Emergent pressure & actuators
- `emergent_pressure: true` + `subcooling_k` → condensing pressure is **solved**, not fixed by design T
- **Fan head-pressure:** free φ scales `C_sec = φ · C_nominal`; residual pins `T_cond`
- **Flooded head-pressure:** free level λ scales `UA_eff`; mutually exclusive with fan
### Ports
| Port | Index |
|------|-------|
| `inlet` / `outlet` | 0 / 1 refrigerant |
| `secondary_inlet` / `secondary_outlet` | 2 / 3 secondary |
System wiring: Source → secondary_in → secondary_out → Sink.
### Calibration
| Factor | Meaning | Default |
|--------|---------|---------|
| `z_ua` | UA scale | **1.0** |
| `z_dp` | ΔP scale | 1.0 |
| `z_flow` / `z_power` / `z_etav` | via shared Calib API | 1.0 |
UI: Fixed on SDT target + free `z_ua` for inverse calibration.
### JSON parameters (main)
| Key | Meaning | Default |
|-----|---------|---------|
| `ua` | UA [W/K] | required |
| `emergent_pressure` | free P_cond | false |
| `subcooling_k` | outlet SC [K] | 5 |
| `secondary_fluid` | Water / Air / … | |
| `secondary_inlet_temp_c` / mass_flow / cp | rating stream | |
| `pressure_drop_coeff` | k for ΔP | |
| `fan_head_pressure_target_c` | fan control | |
| `flooded_head_pressure_target_c` | level control | |
| `skip_pressure_eq` | drop r0 | false |
### Zero flow
Live `C_sec` uses `smooth_mass_magnitude(|ṁ|)`. Mass-flow index never remapped to a pressure column.
---
## FR
### But & modèle
Condenseur frigo → secondaire (eau/air). Duty **ε-NTU** :
```
Q = ε · C_sec · (T_cond(P) T_sec,in)
```
Pas de corrélation plaques (voir BPHX). UA global ± actionneurs fan/niveau.
### Modes secondaire
- **Système :** ports live Source/Sink
- **Rating :** scalaires T + ṁ·cp **dans le Newton** (pas seulement `rate()`)
### Pression émergente
`emergent_pressure` + sous-refroidissement : `P_cond` est **calculée**.
Fan ou flooded head-pressure = +1 actionneur libre.
### Calibration
`z_ua = 1` par défaut. Imposer SDT + libérer Z_UA pour caler le condenseur.
### Ports / JSON
Voir tableaux EN.