Complete Story 0.2 phantom-gradient regularization standard.
Add analytic derivatives and C1 tests for smooth_max/min/clamp, document epsilon/width guidance, and declare flow_regularization as the HX reference pattern without changing component physics. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
62
docs/components/flow-regularization.md
Normal file
62
docs/components/flow-regularization.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Flow regularization (zero-flow helpers)
|
||||
|
||||
Source: `crates/components/src/heat_exchanger/flow_regularization.rs`
|
||||
Used by: **FloodedEvaporator** (full residual path); **Condenser** / **Evaporator** (smooth `|ṁ|` for live `C_sec`).
|
||||
|
||||
> **Standard:** This module is the **reference specialized pattern** for HX
|
||||
> zero-flow residuals. The canonical general C¹ toolkit is
|
||||
> `entropyk_core::smoothing` — see
|
||||
> [phantom-gradient-regularization.md](./phantom-gradient-regularization.md).
|
||||
> Do not move these helpers into core; do not duplicate `smooth_*` here.
|
||||
|
||||
---
|
||||
|
||||
## EN
|
||||
|
||||
### Why
|
||||
|
||||
Zero mass flow is a **valid** state (staging, circuit off, Newton trial steps). Hard branches like `if |m| < ε { Q = 0 }` create **Jacobian discontinuities**.
|
||||
|
||||
### API
|
||||
|
||||
| Function | Meaning |
|
||||
|----------|---------|
|
||||
| `flow_activity(m, ε)` | α = m²/(m²+ε²) ∈ [0,1), α(0)=0 |
|
||||
| `flow_activity_derivative` | dα/dm |
|
||||
| `effective_duty(Q, α_a, α_b)` | Q_eff = α_a · α_b · Q |
|
||||
| `blend_transport_residual` | blend active transport residual with Δh hold |
|
||||
| `blend_transport_partials` | analytic partials of the blend |
|
||||
| `smooth_mass_magnitude` | C¹-ish smooth \|m\| for `C = \|ṁ\| · cp` |
|
||||
| `smooth_mass_magnitude_derivative` | d\|m\|_smooth / dm |
|
||||
|
||||
Defaults: `DEFAULT_M_EPS_KG_S = 1e-4`, `DEFAULT_M_SCALE_KG_S = 0.05`.
|
||||
|
||||
### Interaction with rating mode (Flooded)
|
||||
|
||||
On **FloodedEvaporator system path** (live secondary): duty uses `effective_duty` with α_ref and α_sec.
|
||||
On **Flooded rating path** (scalar C_sec only): residual energy uses **full Q** (no α_ref gate) so `ṁ_ref = 0` is not a trivial root when `C_sec > 0`.
|
||||
|
||||
### DoF rule
|
||||
|
||||
Regularization **must not** change `n_equations()`. It only reshapes residual values and derivatives.
|
||||
|
||||
---
|
||||
|
||||
## FR
|
||||
|
||||
### Pourquoi
|
||||
|
||||
Le débit nul est un état **valide**. Les `if |m| < ε` durs cassent le Newton.
|
||||
|
||||
### API
|
||||
|
||||
Voir le tableau EN.
|
||||
|
||||
### Rating vs système (Flooded)
|
||||
|
||||
- **Système (ports live)** : duty régularisée α_ref · α_sec · Q.
|
||||
- **Rating (scalaires)** : Q **plein** dans le résidu énergie (pas de racine triviale ṁ=0).
|
||||
|
||||
### Règle DoF
|
||||
|
||||
La régularisation **ne change pas** `n_equations()`.
|
||||
88
docs/components/phantom-gradient-regularization.md
Normal file
88
docs/components/phantom-gradient-regularization.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# Phantom-Gradient Regularization Standard
|
||||
|
||||
Canonical toolkit for C¹ (or smoother) replacements of hard clamps, `max`/`min`,
|
||||
and absolute-value kinks on Newton unknowns. Owned by Epic 0 / Story 0.2
|
||||
(`epics-solver-hp.md`, FR19).
|
||||
|
||||
Source code: `crates/core/src/smoothing.rs` (`entropyk_core::smoothing`).
|
||||
|
||||
---
|
||||
|
||||
## Decisions
|
||||
|
||||
| Layer | Location | Role |
|
||||
|-------|----------|------|
|
||||
| **Canonical general toolkit** | `entropyk_core::smoothing` | `smooth_max` / `smooth_min` / `smooth_abs` / `smooth_clamp` (+ analytic derivatives) |
|
||||
| **Reference specialized pattern** | `heat_exchanger::flow_regularization` | Mass-flow activity / duty / transport blend for zero-flow HX residuals — **not** duplicated into core |
|
||||
| **Verification harness** | `entropyk_components::jacobian_fd` | Central FD vs analytic (Story 0.1); CI gate is Story 0.5 |
|
||||
|
||||
**Banned** in residual / Jacobian paths on Newton unknowns:
|
||||
|
||||
- bare `.clamp(...)` whose derivative jumps `0 ↔ 1`
|
||||
- hard `.max(0)` / early `Ok(0.0)` that zeros informative physics derivatives
|
||||
|
||||
Physical clamp → smooth migrations are Stories **0.3** (valve / EXV) and **0.4** (HX).
|
||||
This standard ships toolkit + docs only; it does not change component physics.
|
||||
|
||||
DoF rule: regularization **must not** change `n_equations()`.
|
||||
|
||||
---
|
||||
|
||||
## API (core)
|
||||
|
||||
| Function | Continuity | Parameter |
|
||||
|----------|------------|-----------|
|
||||
| `smooth_max(a, b, k)` / `smooth_max_derivative` | C∞ | sharpness `k` (overshoot at equality = `k/2`) |
|
||||
| `smooth_min(a, b, k)` / `smooth_min_derivative` | C∞ | same |
|
||||
| `smooth_abs(x, eps)` / `smooth_abs_derivative` | C∞ | `eps` = value at `x=0` |
|
||||
| `smooth_clamp(x, lo, hi, width)` / `smooth_clamp_derivative` | C¹ | transition `width` at each bound |
|
||||
| `smoothstep` / `cubic_blend` / `quintic_blend` (+ derivatives) | C¹ / C² | correlation transition windows |
|
||||
|
||||
Degenerate parameters never panic: `k <= 0` → hard max/min; `eps <= 0` → hard `|x|`;
|
||||
`width <= 0` or inverted bounds → hard clamp (bounds swapped if needed).
|
||||
|
||||
---
|
||||
|
||||
## ε / width selection guidance
|
||||
|
||||
| Primitive | Parameter | Physical meaning | Rule of thumb |
|
||||
|-----------|-----------|------------------|---------------|
|
||||
| `smooth_abs` | `eps` | Blend half-width; value at origin | ~1% of characteristic `\|x\|`, or smaller if the kink is far from the operating region |
|
||||
| `smooth_max` / `smooth_min` | `k` | Softness; overshoot at equality = `k/2` | `k ≪ \|a − b\|` where you need the hard extremum; never large enough to shift equilibrium |
|
||||
| `smooth_clamp` | `width` | Transition length at each bound | Prefer `width ≤ (hi − lo) / 2`. Keep Newton-visible band physically small |
|
||||
| `flow_activity` | `m_eps` | Mass-flow activity scale | Keep HX default `DEFAULT_M_EPS_KG_S = 1e-4` (see [flow-regularization.md](./flow-regularization.md)) |
|
||||
|
||||
### Recommended starting widths (examples only)
|
||||
|
||||
| Quantity | Interval | Suggested `width` |
|
||||
|----------|----------|-------------------|
|
||||
| Valve / EXV opening | `[0, 1]` | `1e-3` … `1e-2` |
|
||||
| Thermodynamic quality | `[0, 1]` | `1e-3` … `1e-2` |
|
||||
| Fan actuator | `[0, 1.5]` | `~1e-2` |
|
||||
| Flood level | `[0, 0.98]` | `~1e-2` (respect `width ≤ (hi−lo)/2`) |
|
||||
|
||||
Always pair value and derivative in both `compute_residuals` and `jacobian_entries`
|
||||
(`smooth_clamp` + `smooth_clamp_derivative`, etc.).
|
||||
|
||||
---
|
||||
|
||||
## Relationship to flow regularization
|
||||
|
||||
`crates/components/src/heat_exchanger/flow_regularization.rs` is the **reference
|
||||
implementation** for zero-flow-safe HX residuals. It builds on
|
||||
`entropyk_core::smoothing::smooth_abs` and stays in `entropyk-components` because
|
||||
it encodes residual units (watts) and characteristic mass-flow scales
|
||||
(`m_scale`) that are HX-specific.
|
||||
|
||||
Do **not** move `flow_activity` / `blend_transport_residual` into core.
|
||||
Do **not** invent a second smoothing module under `components/`.
|
||||
|
||||
Details: [flow-regularization.md](./flow-regularization.md).
|
||||
|
||||
---
|
||||
|
||||
## Verification
|
||||
|
||||
- Unit / FD continuity tests: `crates/core/src/smoothing.rs` (`#[cfg(test)]`).
|
||||
- Component Jacobian health: `check_jacobian_health` (Story 0.1 audit harness).
|
||||
- Envelope CI gate: Story 0.5.
|
||||
Reference in New Issue
Block a user