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:
149
apps/web/public/docs/components/flooded-evaporator.md
Normal file
149
apps/web/public/docs/components/flooded-evaporator.md
Normal file
@@ -0,0 +1,149 @@
|
||||
# FloodedEvaporator
|
||||
|
||||
Config type: `"FloodedEvaporator"`
|
||||
Source: `crates/components/src/heat_exchanger/flooded_evaporator.rs`
|
||||
Example: `crates/cli/examples/chiller_flooded_4port_watercooled.json` (DoF 19=19, COP ≈ 6.45)
|
||||
|
||||
---
|
||||
|
||||
## EN
|
||||
|
||||
### Purpose & physical model
|
||||
|
||||
Shell-and-tube **flooded** evaporator. Refrigerant boils on the shell side; secondary (water/brine) flows in the tubes. Heat duty uses **phase-change ε-NTU** (`C_min = C_sec`, `C_r → 0`):
|
||||
|
||||
```
|
||||
ε = 1 − exp(−UA / C_sec)
|
||||
Q = ε · C_sec · (T_sec,in − T_evap(P))
|
||||
```
|
||||
|
||||
- `T_evap(P)` = saturation temperature of the refrigerant at edge pressure
|
||||
- `C_sec` = secondary heat-capacity rate [W/K]
|
||||
|
||||
There is **no plate-geometry correlation** inside this component (unlike BPHX). UA is a **lumped parameter** (possibly scaled by calibration `z_ua` via the inner `HeatExchanger` calib API).
|
||||
|
||||
### Dual operating modes (both enter Newton residuals)
|
||||
|
||||
| Mode | How secondary is defined | Secondary Newton unknowns | When to use |
|
||||
|------|--------------------------|---------------------------|-------------|
|
||||
| **System (4-port)** | Live edges `secondary_inlet` / `secondary_outlet` (e.g. BrineSource → HX → BrineSink) | Yes (`n_secondary` = 1 or 2) | Closed water loop, real machine |
|
||||
| **Rating** | Scalars `secondary_inlet_temp_*` + `C_sec` (`secondary_mass_flow_kg_s` × `cp` or `secondary_capacity_rate_w_per_k`) | No (`n_secondary` = 0) | Qualification / open-loop duty; still **coupled ε-NTU in residuals** |
|
||||
|
||||
`coupled_ready` = refrigerant indices ready **and** (live secondary edges **or** rating scalars).
|
||||
Never falls through to generic four-port `HeatExchanger::inner` residuals for normal operation (seed path is local and finite).
|
||||
|
||||
**Rating residual energy:** uses full `Q` (not `α(ṁ)·Q`) so `ṁ = 0` is not a trivial root when `C_sec > 0`.
|
||||
**System residual energy:** uses `effective_duty(Q, α_ref, α_sec)` from `flow_regularization` for zero-flow safety.
|
||||
|
||||
Also exposed: `rate(p_in)` open-loop rating API for sweeps (same ε-NTU formulas).
|
||||
|
||||
### Outlet closure (DoF-critical)
|
||||
|
||||
| Setting | Residual r2 | Typical use |
|
||||
|---------|-------------|-------------|
|
||||
| Default (`quality_control: false`) | `h_out − h_g(P)` saturated vapor | Compressor suction after disengagement |
|
||||
| `quality_control: true` | `x_out − target_quality` | Legacy recirculation / two-phase outlet |
|
||||
|
||||
Both keep **the same** `n_equations` (quality replaces sat-vapor; it does not add an extra free residual by itself).
|
||||
`quality_control: true` on a closed cycle often needs a **free actuator** elsewhere or the DoF gate rejects the graph.
|
||||
|
||||
### Residuals & `n_equations()`
|
||||
|
||||
| Row | Equation |
|
||||
|-----|----------|
|
||||
| r0 | `P_out − P_in` (no refrigerant ΔP by default) |
|
||||
| r1 | `ṁ_ref · (h_out − h_in) − Q_eff` |
|
||||
| r2 | sat-vapor **or** quality target (see above) |
|
||||
| r_sec mass | `ṁ_sec,out − ṁ_sec,in` only if live edges and **not** same-branch |
|
||||
| r_sec energy | live secondary energy + duty (blended at low ṁ) |
|
||||
|
||||
```
|
||||
n_equations = 3 + n_secondary
|
||||
n_secondary = 0 # rating (no live edges)
|
||||
| 1 # live edges, same-branch ṁ
|
||||
| 2 # live edges, independent ṁ in/out
|
||||
```
|
||||
|
||||
### Ports
|
||||
|
||||
| Port | Index | Role |
|
||||
|------|-------|------|
|
||||
| `inlet` | 0 | Refrigerant from EXV |
|
||||
| `outlet` | 1 | Refrigerant to compressor suction |
|
||||
| `secondary_inlet` | 2 | Water/brine in |
|
||||
| `secondary_outlet` | 3 | Water/brine out |
|
||||
|
||||
CLI aliases: `water_in` / `brine_in` → secondary_inlet, etc. (`resolve_port_index`).
|
||||
|
||||
### Calibration
|
||||
|
||||
| Factor | Effect | Default |
|
||||
|--------|--------|---------|
|
||||
| `z_ua` (BOLT `Z_UA`) | `UA_eff = z_ua · UA` via inner calib | **1.0** |
|
||||
| `z_dp` | pressure-drop scale if ΔP model used | 1.0 |
|
||||
|
||||
Inverse calibration (CLI `controls[]` / UI Fixed checkboxes): impose a measure (e.g. SST = `saturationTemperature`) and free `z_ua`.
|
||||
|
||||
### JSON parameters
|
||||
|
||||
| Key | Meaning | Unit | Default |
|
||||
|-----|---------|------|---------|
|
||||
| `ua` | UA | W/K | **required** |
|
||||
| `refrigerant` | refrigerant id | – | primary fluid |
|
||||
| `secondary_fluid` | secondary fluid | – | Water / MEG |
|
||||
| `quality_control` | quality residual instead of sat-vapor | bool | `false` |
|
||||
| `target_quality` | x target if quality_control | – | 0.7 |
|
||||
| `secondary_inlet_temp_c` / `_k` | rating T_sec,in | °C / K | – |
|
||||
| `secondary_mass_flow_kg_s` | rating ṁ_sec | kg/s | – |
|
||||
| `secondary_cp_j_per_kgk` | rating cp | J/(kg·K) | 4186 |
|
||||
| `secondary_capacity_rate_w_per_k` | rating C_sec direct | W/K | – |
|
||||
| calib `z_ua` / `z_dp` | Z-factors | – | 1.0 |
|
||||
|
||||
### energy_transfers / mass
|
||||
|
||||
When coupled: cooling `Q ≈ ṁ·(h_out − h_in)` (positive heat absorbed by refrigerant).
|
||||
`port_mass_flows` reports 4-port signs without calling generic inner four-port.
|
||||
|
||||
### Zero flow
|
||||
|
||||
`flow_regularization` on system path: smooth `|ṁ|` for live `C_sec`, activity factors, secondary Δh hold. Seed residuals stay finite if P is non-physical.
|
||||
|
||||
---
|
||||
|
||||
## FR
|
||||
|
||||
### But & modèle
|
||||
|
||||
Évaporateur **noyé** tubes-calandre. Duty **ε-NTU** à changement de phase :
|
||||
|
||||
```
|
||||
ε = 1 − exp(−UA / C_sec)
|
||||
Q = ε · C_sec · (T_sec,in − T_evap(P))
|
||||
```
|
||||
|
||||
Pas de corrélation géométrique type Longo/Shah (voir BPHX pour ça). UA est un **paramètre global**, modulable par `z_ua` (défaut **1**).
|
||||
|
||||
### Deux modes (tous deux dans le Newton)
|
||||
|
||||
| Mode | Secondaire | Inconnues eau | Usage |
|
||||
|------|------------|---------------|--------|
|
||||
| **Système** | Ports live Source → HX → Sink | oui | Machine fermée |
|
||||
| **Rating** | Scalaires T + ṁ·cp (ou C_sec) | non | Qualification ; Q ε-NTU **dans** les résidus |
|
||||
|
||||
### Clôture de sortie
|
||||
|
||||
- Défaut : **vapeur saturée** `h_out = h_g(P)` (aspiration compresseur).
|
||||
- `quality_control: true` : `x_out − x_cible` (même nombre d’équations).
|
||||
|
||||
### Résiduels
|
||||
|
||||
`n_equations = 3 + n_secondary` (0 / 1 / 2). Voir tableau EN.
|
||||
|
||||
### Calibration
|
||||
|
||||
Imposer une mesure (SST) et libérer `z_ua` (UI case Fixed, ou `controls[]`).
|
||||
`z_ua = 1` = pas de correction.
|
||||
|
||||
### Ports / JSON
|
||||
|
||||
Identiques aux tableaux EN.
|
||||
Reference in New Issue
Block a user