Summary
test_uv_derivatives_fd/test_uv_derivatives_fd_smooth_truncation (source/equilibrium_test.pf) each have one assertion — dU/dstate2 (and the parallel dU/dw0 array check) — that compares an analytically-exact-zero quantity against pure finite-difference (FD) noise. That's expected (see below), but the noise on this particular direction is unusually large compared to the analogous zero-derivative checks in the sibling hp/sp/sv tests, large enough that a tolerance floor safe enough to pass would make the assertion essentially meaningless. Filed as a follow-up to #88 rather than folding a band-aid fix into that PR.
For a uv (internal energy / specific volume) constrained solve, the output internal energy is pinned to the input target regardless of the second state variable (V) or the reactant weights (w0) — so dU/dstate2 and dU/dw0 are analytically exactly zero. The equivalent zero-derivative checks in hp (dH/dstate2, dH/dw0), sp (dS/dstate2, dS/dw0), and sv (dS/dstate2, per-species dnj_dstate) all have FD noise in the 1e-7 to 1e-3 range, comfortably handled by a 1e-3–1e-1 denominator floor while staying 10–500x below the smallest genuine nonzero derivative values seen elsewhere in the same tests. uv's noise on this one direction is different:
| test |
quantity |
FD noise magnitude |
test_uv_derivatives_fd |
dU/dstate2 |
~3.2e-4 |
test_uv_derivatives_fd_smooth_truncation |
dU/dstate2 |
~3.7e-2 |
test_uv_derivatives_fd_smooth_truncation |
dU/dw0 (per-reactant) |
up to ~1.2e-2 |
To pass under the same relative tolerance (5.0d-2) used for the rest of the derivative assertions in these tests, the smooth-truncation case would need a denominator floor greater than ~0.74 — i.e. larger than several genuine nonzero derivative values seen elsewhere in the very same test file (e.g. dS/dstate2 as small as ~0.055 in tv_derivatives_fd_smooth_truncation). A floor that size wouldn't meaningfully test anything for this direction.
Reproduction
Expected behavior
The FD noise on dU/dstate2/dU/dw0 for uv should be roughly in line with the analogous zero-derivative checks in hp/sp/sv (1e-7 to 1e-3), so a reasonably tight floor (matching the 1e-3–1e-1 pattern used elsewhere) can both pass reliably and still catch a real regression.
Actual behavior
FD noise on this one direction is 10–100x larger than the equivalent checks elsewhere, especially in the smooth_truncation variant. Root cause not yet investigated — could be the finite-difference step size (h = 1.0d-6) interacting poorly with how the second state variable (V) is scaled/perturbed for uv, solver convergence tolerance in that direction, or something specific to the smooth-truncation chain rule. Until root-caused, #88's fix leaves these two assertions (dU/dstate2 and dU/dw0) at their original unfailable bound (tol_dU_dstate2 = 1.0d30, a dedicated per-assertion tolerance) in both test_uv_derivatives_fd and test_uv_derivatives_fd_smooth_truncation, with a code comment explaining why, rather than papering over it with an oversized floor. Every other assertion in both tests (roughly 20 of ~22) now uses the real 5.0d-2 tolerance.
Environment
- OS: n/a (source-level)
- CEA version/commit: current branch as of 2026-09-03
Additional context
Discovered while fixing #88 (fix/derivative-fd-tolerances branch). See that PR for the full before/after tolerance investigation across hp/sp/uv/sv.
Drafted with Claude's assistance
- FD noise magnitudes in the table were read directly from
ctest -R cea_core_test -V output with write(*,*) debug prints enabled (already present, commented/uncommented, in the relevant subroutines) — not estimated or taken on faith.
- The "floor would need to exceed 0.74" claim was derived algebraically from the observed ~3.7e-2 noise and the 5.0d-2 relative tolerance (
noise / floor < tol ⇒ floor > noise / tol), then cross-checked against the smallest genuine nonzero derivative value found elsewhere in the same file (~0.055 in tv_derivatives_fd_smooth_truncation).
- Checked
gh issue list on djkees/cea before filing to confirm this isn't a duplicate.
Summary
test_uv_derivatives_fd/test_uv_derivatives_fd_smooth_truncation(source/equilibrium_test.pf) each have one assertion —dU/dstate2(and the paralleldU/dw0array check) — that compares an analytically-exact-zero quantity against pure finite-difference (FD) noise. That's expected (see below), but the noise on this particular direction is unusually large compared to the analogous zero-derivative checks in the siblinghp/sp/svtests, large enough that a tolerance floor safe enough to pass would make the assertion essentially meaningless. Filed as a follow-up to #88 rather than folding a band-aid fix into that PR.For a
uv(internal energy / specific volume) constrained solve, the output internal energy is pinned to the input target regardless of the second state variable (V) or the reactant weights (w0) — sodU/dstate2anddU/dw0are analytically exactly zero. The equivalent zero-derivative checks inhp(dH/dstate2,dH/dw0),sp(dS/dstate2,dS/dw0), andsv(dS/dstate2, per-speciesdnj_dstate) all have FD noise in the1e-7to1e-3range, comfortably handled by a1e-3–1e-1denominator floor while staying 10–500x below the smallest genuine nonzero derivative values seen elsewhere in the same tests.uv's noise on this one direction is different:test_uv_derivatives_fddU/dstate2test_uv_derivatives_fd_smooth_truncationdU/dstate2test_uv_derivatives_fd_smooth_truncationdU/dw0(per-reactant)To pass under the same relative tolerance (
5.0d-2) used for the rest of the derivative assertions in these tests, the smooth-truncation case would need a denominator floor greater than ~0.74 — i.e. larger than several genuine nonzero derivative values seen elsewhere in the very same test file (e.g.dS/dstate2as small as ~0.055 intv_derivatives_fd_smooth_truncation). A floor that size wouldn't meaningfully test anything for this direction.Reproduction
ctest -R cea_core_test -V(after [bug] equilibrium_test.pf derivative-accuracy assertions use unfailable tol = 1.0d30 #88's fix lands). Addwrite(*,*)debug prints ontotals%dU_dstate2/totals%dU_dstate2_fd(ordU_dw0/dU_dw0_fd) intest_uv_derivatives_fd_smooth_truncationand compare the printed analytic (0) vs. FD values directly.Expected behavior
The FD noise on
dU/dstate2/dU/dw0foruvshould be roughly in line with the analogous zero-derivative checks inhp/sp/sv(1e-7to1e-3), so a reasonably tight floor (matching the1e-3–1e-1pattern used elsewhere) can both pass reliably and still catch a real regression.Actual behavior
FD noise on this one direction is 10–100x larger than the equivalent checks elsewhere, especially in the
smooth_truncationvariant. Root cause not yet investigated — could be the finite-difference step size (h = 1.0d-6) interacting poorly with how the second state variable (V) is scaled/perturbed foruv, solver convergence tolerance in that direction, or something specific to the smooth-truncation chain rule. Until root-caused,#88's fix leaves these two assertions (dU/dstate2anddU/dw0) at their original unfailable bound (tol_dU_dstate2 = 1.0d30, a dedicated per-assertion tolerance) in bothtest_uv_derivatives_fdandtest_uv_derivatives_fd_smooth_truncation, with a code comment explaining why, rather than papering over it with an oversized floor. Every other assertion in both tests (roughly 20 of ~22) now uses the real5.0d-2tolerance.Environment
Additional context
Discovered while fixing #88 (
fix/derivative-fd-tolerancesbranch). See that PR for the full before/after tolerance investigation acrosshp/sp/uv/sv.Drafted with Claude's assistance
ctest -R cea_core_test -Voutput withwrite(*,*)debug prints enabled (already present, commented/uncommented, in the relevant subroutines) — not estimated or taken on faith.noise / floor < tol⇒floor > noise / tol), then cross-checked against the smallest genuine nonzero derivative value found elsewhere in the same file (~0.055 intv_derivatives_fd_smooth_truncation).gh issue liston djkees/cea before filing to confirm this isn't a duplicate.