mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
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)
71 lines
2.5 KiB
Python
71 lines
2.5 KiB
Python
#!/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']}")
|