Research-Stack/4-Infrastructure/shim/burgers_cfl_sweep.py
allaun 475f6319ea chore(repo): push local 768-commit branch state onto clean remote baseline
This squashes all local history (768 commits) onto the scrubbed PR #90
baseline. Individual commits were lost during filter-repo corruption;
the working tree content is preserved intact.

Build: N/A (working tree state only)
2026-06-15 22:46:50 -05:00

71 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""CFL bound verification sweep for Burgers step correspondence."""
import random, math, json, hashlib
from datetime import datetime, timezone
Q16 = 65536
random.seed(42)
def step(u, N, nu, dx, dt):
nu_q = int(nu*Q16); dt_q = int(dt*Q16); dx_q = int(dx*Q16)
new = [0]*N
for i in range(N):
ux = ((u[(i+1)%N] - u[(i-1)%N]) // (2*dx_q)) if i>0 and i<N-1 else 0
uxx = ((u[(i+1)%N] - 2*u[i] + u[(i-1)%N]) // (dx_q*dx_q//Q16)) if i>0 and i<N-1 else 0
ui = u[i]
rhs = ((nu_q * uxx) // Q16) - ((ui * ux) // Q16)
new[i] = u[i] + (dt_q * rhs) // Q16
return new
def kinetic_energy(u):
return sum((v*v)//Q16 for v in u) // 2
results = []
for N in [4, 8, 16, 32]:
for nu in [0.05, 0.1, 0.2]:
for dt in [0.005, 0.01, 0.02]:
max_err = 0; max_E0_val = 0
for _ in range(25):
u = [0]*N
for i in range(1, N-1):
u[i] = random.randint(-Q16//2, Q16//2)
E0 = kinetic_energy(u)
u1 = step(u, N, nu, 1.0, dt)
E1 = kinetic_energy(u1)
obs = abs(E1 - E0) / Q16
max_err = max(max_err, obs)
max_E0_val = max(max_E0_val, E0/Q16)
cfl = round(dt * 2.0 * max_E0_val, 6)
within = max_err < cfl + 0.001
results.append({
'N': N, 'nu': nu, 'dt': dt,
'max_E0': round(max_E0_val, 4),
'max_step_error': round(max_err, 6),
'cfl_bound': cfl,
'within_cfl': within,
})
receipt = {
'schema': 'burgers_cfl_sweep_v1',
'claim_boundary': 'monte_carlo_sweep;cfl_bound_verification',
'results': results,
'summary': {
'total_cases': len(results),
'all_within_cfl': all(r['within_cfl'] for r in results),
},
'computed_at': datetime.now(timezone.utc).isoformat(),
}
canonical = json.dumps(receipt, sort_keys=True, separators=(',', ':'))
receipt['receipt_sha256'] = hashlib.sha256(canonical.encode()).hexdigest()
with open('burgers_cfl_sweep_receipt.json', 'w') as f:
json.dump(receipt, f, indent=2)
for r in results:
mark = "" if r['within_cfl'] else ""
print(f"N={r['N']:2d} ν={r['nu']:.2f} dt={r['dt']:.3f} "
f"E0max={r['max_E0']:6.2f} err={r['max_step_error']:.6f} "
f"CFL={r['cfl_bound']:.6f} {mark}")
print(f"\nAll within CFL: {receipt['summary']['all_within_cfl']}")
print(f"Receipt: burgers_cfl_sweep_receipt.json")
print(f"SHA256: {receipt['receipt_sha256']}")