Snapshot WIP: solver HP epic progress, BPHX/HX physics, BMAD skill refresh.
Some checks failed
CI / check (push) Has been cancelled
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:
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user