Separate surface and interval-witness enthalpy observations

This commit is contained in:
2026-09-19 10:52:33 -04:00
parent e21f723fdf
commit 4ff1b10693

View File

@@ -60,6 +60,13 @@ def numeric(row, omit=("control",)):
return {k: float(v) for k, v in row.items() if k not in omit}
def enthalpy_observations(records, key):
values = [row[key] for row in records]
require(all(map(math.isfinite, values)), "Nonfinite saved enthalpy observation")
return {"samples": len(values), "minimum_enthalpy": min(values) if values else None,
"negative_enthalpy_samples": sum(value < 0 for value in values)}
def poly_value(coefficients, x):
value = coefficients[-1]
for coefficient in reversed(coefficients[:-1]):
@@ -305,11 +312,17 @@ def audit_measures(get, expected_controls, n, K):
require(traces, "Missing surface samples")
unique = {(r["face"], r["u"], r["v"]) for r in traces}
require(len(unique) == len(traces) == 25 * len({r["face"] for r in traces}), "Surface coverage")
witnesses = [row for element in support for row in pieces[(control, degree, element)]]
result[f"Q{degree}/{control}"] = {
"summary": {str(q): totals[(control, degree, q)] for q in ORDERS},
"summary_enthalpy_scope": "Integration nodes only; EOS availability flags do not cover boundary samples or density-minimum witnesses.",
"surface": {"samples": len(traces), "minimum_density": min(r["rho"] for r in traces),
"negative_samples": sum(r["rho"] < 0 for r in traces),
"resolved_negative_samples": sum(r["resolved_negative"] for r in traces)},
"resolved_negative_samples": sum(r["resolved_negative"] for r in traces),
"enthalpy": {**enthalpy_observations(traces, "h"),
"scope": "Saved one-sided 5-by-5 face samples; counts are not volume or area fractions."}},
"negative_interval_witness_enthalpy": {**enthalpy_observations(witnesses, "witness_h"),
"scope": "One saved density-minimum witness per exported negative interval on order30 tangential lines; this is not an enthalpy-extremum search."},
"negative_mass_q30_minus_q22": totals[(control, degree, 30)]["negative_mass"] - totals[(control, degree, 22)]["negative_mass"],
"negative_volume_q30_minus_q22": totals[(control, degree, 30)]["negative_volume"] - totals[(control, degree, 22)]["negative_volume"]}
return result, support, totals, {"negative_lines": len(lines), "fully_resolved_negative_lines": resolved_lines}
@@ -605,6 +618,14 @@ def audit_case(campaign, name):
class SelfTests(unittest.TestCase):
def test_separate_enthalpy_observations(self):
self.assertEqual(enthalpy_observations([], "h"),
{"samples": 0, "minimum_enthalpy": None, "negative_enthalpy_samples": 0})
self.assertEqual(enthalpy_observations([{"h": -1e-18}, {"h": 0.}, {"h": 1.}], "h"),
{"samples": 3, "minimum_enthalpy": -1e-18, "negative_enthalpy_samples": 1})
with self.assertRaises(AssertionError):
enthalpy_observations([{"witness_h": math.nan}], "witness_h")
def test_independent_roots(self):
cases = ((["0", ".1875", "-1", "1", "0"], [(.25, .75)]),
([".025634765625", "-.34375", "1.34375", "-2", "1"], [(.125, .375), (.625, .875)]),