Snapshot WIP: solver HP epic progress, BPHX/HX physics, BMAD skill refresh.
Some checks failed
CI / check (push) Has been cancelled

Capture uncommitted solver robustness work (regularization, domain errors, linear solver lifecycle, tube DP/MSH), web workbench updates, and synced BMAD skills across IDE agent folders before starting BPHX pressure-drop.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-19 16:35:31 +02:00
parent 88620790d6
commit 5bd180b5b8
1363 changed files with 101041 additions and 58547 deletions

View File

@@ -25,6 +25,12 @@ const DEFAULT_CAP_NONZERO: NonZeroUsize = NonZeroUsize::new(DEFAULT_CACHE_CAPACI
/// Quantization factor: values rounded to 1e-9 relative.
/// (v * 1e9).round() as i64 for Hash-compatible key.
///
/// Overflow safety (Story 0.7, 2026-07-19 finite-poisoning incident): for
/// |v| > 9e9 the product `v * 1e9` exceeds `i64::MAX` and wraps to garbage,
/// making extreme solver trial states (blown iterates, h ~ 1e13) collide
/// with legitimate keys. Those states fall back to exact bit hashing — they
/// do not need near-state hits, they need to never collide.
#[inline]
fn quantize(v: f64) -> i64 {
if v.is_nan() {
@@ -35,6 +41,9 @@ fn quantize(v: f64) -> i64 {
#[cfg(debug_assertions)]
eprintln!("[WARN] quantize: Infinite value encountered, mapping to 0");
0
} else if v.abs() > 9.0e9 {
// Exact, sign-masked bit pattern (no quantization) for huge values.
(v.to_bits() & 0x7fff_ffff_ffff_ffff) as i64
} else {
(v * 1e9).round() as i64
}
@@ -240,6 +249,24 @@ mod tests {
cache_resize(NonZeroUsize::new(DEFAULT_CACHE_CAPACITY).expect("capacity is non-zero"));
}
#[test]
fn test_quantize_extreme_values_do_not_collide_with_normal_keys() {
// 2026-07-19 incident: `v * 1e9` overflows i64 for |v| > ~9e9, wrapping
// blown-up trial states onto legitimate keys (finite poisoning).
let normal_a = quantize(100_000.0);
let normal_b = quantize(420_000.0);
for extreme in [1.0e13, -1.0e13, 3.7e15, f64::MAX / 2.0] {
let q = quantize(extreme);
assert_ne!(q, normal_a, "extreme {extreme} collides with 1e5");
assert_ne!(q, normal_b, "extreme {extreme} collides with 4.2e5");
}
// Distinct extremes get distinct keys (exact bit hashing).
assert_ne!(quantize(1.0e13), quantize(1.0e13 * 1.000001));
// Normal quantization unchanged.
assert_eq!(quantize(1.5), quantize(1.5));
assert_ne!(quantize(1.5), quantize(1.5 + 1e-8));
}
#[test]
fn test_cache_key_different_backends() {
let fluid = FluidId::new("R134a");