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>
4.0 KiB
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 jumps0 ↔ 1 - hard
.max(0)/ earlyOk(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) |
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.
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.