Files
MeanField/experiments/summarize_geometry_quality.py
Emily Boudreaux 75cc638739 perf(allocations): reduced overall allocations by 95%, increaseed jacobian applicatin by 2x
This commit uses global pre allocated work space to dramatically reduce memory usage and allocation time
2026-09-10 06:50:56 -04:00

97 lines
4.3 KiB
Python

#!/usr/bin/env python3
"""Read-only, standard-library summary of geometry_quality_experiment artifacts."""
import argparse
import csv
import math
from pathlib import Path
def rows(path):
if not path.exists():
return []
with path.open(newline="") as stream:
return list(csv.DictReader(stream))
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("directory", type=Path)
args = parser.parse_args()
root = args.directory
print("GEOMETRY (boundaries are censored at alpha=1)")
for path in sorted(root.glob("*_geometry_elements.csv")):
data = rows(path)
limited = [r for r in data if r["limited"] == "1"]
if not limited:
print(path.stem, "no sampled boundary <=1")
continue
first = limited[0]
boundary = float(first["boundary_step"])
ties = [r["element"] for r in limited if float(r["boundary_step"]) <= boundary * (1 + 1e-6)]
print(path.stem, f"boundary={boundary:.10g}", f"limiter={first['element']}",
f"attr={first['attribute']}", f"ties_1ppm={','.join(ties)}",
f"radial_gradient={float(first['limiter_radial_gradient']):.7g}")
for key in first:
if "reference" in key and ("sigma" in key or "det" in key):
print(" ", key, first[key])
print("\nLINEAR SOLVES")
for row in rows(root / "solves.csv"):
print(row)
print("\nSURFACE (unweighted nodal fractional changes)")
for row in rows(root / "surface_summary.csv"):
print(row)
surface_rows = rows(root / "surface.csv")
for case in sorted({r["case"] for r in surface_rows}):
groups = {}
for row in surface_rows:
if row["case"] != case:
continue
radius = float(row["radius"])
key = tuple(sorted(round(abs(float(row[c]) / radius), 8) for c in ("x", "y", "z")))
groups.setdefault(key, []).append(float(row["correction_fraction"]))
print(case, "cubic_symmetry_groups=", len(groups), "max_within_group_spread=",
max((max(v) - min(v) for v in groups.values()), default=math.nan))
print("\nACCEPTED RESIDUAL BLOCKS")
for row in rows(root / "blocks.csv"):
if row["case"] == "accepted" and row["kind"] == "residual":
print(row["block"], "normalized_l2=" + row["normalized_l2"])
print("\nFINITE DIFFERENCES")
for row in rows(root / "finite_differences.csv"):
if float(row["action_norm"]) > 1e-12:
print(row["epsilon"], row["row"], "relative_error=" + row["relative_error"])
print("\nMAPPING CHECKS")
for path in sorted(root.glob("*_geometry_mapping_checks.csv")):
data = rows(path)
errors = [float(r["relative_mapping_matrix_error"]) for r in data]
errors = [v for v in errors if math.isfinite(v)]
print(path.stem, "max_matrix_error=", max(errors, default=math.nan),
"invalid_samples=", sum(not math.isfinite(float(r["direct_det"])) for r in data))
print("\nEXTENSION CHECKS")
for row in rows(root / "extension_checks.csv"):
print(row)
print("\nCORE DIAGONAL AT NEWTON LIMITER")
steps = {r["case"]: float(r["safe_step"]) for r in rows(root / "solves.csv")}
for path in sorted(root.glob("*_core_diagonal.csv")):
data = rows(path)
for row in data:
if abs(float(row["s"]) - 0.010885670926971493) < 1e-12:
print(path.stem, "actual_u=", row["actual_radial_displacement"],
"desired_u=", row["desired_radial_displacement"],
"actual_gradient=", row["actual_radial_gradient"],
"desired_gradient=", row["desired_radial_gradient"])
case = path.stem.removesuffix("_core_diagonal")
for alpha in sorted({1.0, steps.get(case, 1.0)}):
determinants = []
for row in data:
if "relative_det_coefficient_0" not in row:
continue
c = [float(row[f"relative_det_coefficient_{i}"]) for i in range(4)]
det = ((c[3] * alpha + c[2]) * alpha + c[1]) * alpha + c[0]
determinants.append((det, float(row["s"])))
if determinants:
print(" ", case, "alpha=", alpha, "min_diagonal_det_and_s=", min(determinants))
if __name__ == "__main__":
main()