# 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.
