"""Independent closed-form response check for the linear half-sine shock model."""
from pathlib import Path
import json,math,cmath
import numpy as np
ROOT=Path.cwd();G=9.80665;DT=.0005

def free(t,x0,v0,w,z):
 alpha=z*w;decay=np.exp(-alpha*t)
 if abs(z-1)<1e-12:
  b=v0+w*x0;x=decay*(x0+b*t);v=decay*(b-w*(x0+b*t))
 else:
  beta=w*math.sqrt(1-z*z);b=(v0+alpha*x0)/beta;co=np.cos(beta*t);si=np.sin(beta*t);x=decay*(x0*co+b*si);v=decay*((-alpha*x0+beta*b)*co+(-alpha*b-beta*x0)*si)
 return x,v

def exact(t,d,w,z,peak):
 omega=math.pi/d;C=-peak*G/complex(w*w-omega*omega,2*z*w*omega)
 def on(s):
  f=C*np.exp(1j*omega*s);xp=f.imag;vp=(1j*omega*f).imag;xh,vh=free(s,-C.imag,-(1j*omega*C).imag,w,z);return xp+xh,vp+vh
 x,v=on(np.minimum(t,d));mask=t>d;xd,vd=on(np.array(d));x[mask],v[mask]=free(t[mask]-d,xd,vd,w,z)
 return x,(-2*z*w*v-w*w*x)/G
rows=json.loads((ROOT/'study.json').read_text())['cases'];out=[];t=np.arange(8000)*DT
for r in rows:
 x,a=exact(t,r['duration_s'],2*math.pi*r['natural_frequency_hz'],r['damping_ratio'],25)
 pa=float(np.max(abs(a)));px=float(np.max(abs(x)))
 out.append({'duration_s':r['duration_s'],'frequency_hz':r['natural_frequency_hz'],'damping_ratio':r['damping_ratio'],'reference_peak_g':pa,'reference_travel_m':px,'peak_difference_g':abs(pa-r['peak_transmitted_acceleration_g']),'travel_difference_m':abs(px-r['peak_relative_travel_m']),'gate_agreement':(px<.25 and 1-pa/25>=.3)==(r['peak_relative_travel_m']<.25 and r['acceleration_reduction_fraction']>=.3)})
summary={'cases':len(out),'max_peak_difference_g':max(r['peak_difference_g'] for r in out),'max_travel_difference_m':max(r['travel_difference_m'] for r in out),'all_gates_agree':all(r['gate_agreement'] for r in out)}
assert summary['max_peak_difference_g']<1e-4 and summary['max_travel_difference_m']<1e-6 and summary['all_gates_agree']
result={'method':'Closed-form sinusoidal particular solution plus homogeneous transient during pulse; free homogeneous response afterward. Critical damping evaluated separately. No numerical ODE integrator.','scope':'Comparison at identical 0.5 ms sample times over4s. Does not bound continuous-time extrema or validate physical assumptions.','summary':summary,'cases':out}
(ROOT/'closed-form-check.json').write_text(json.dumps(result,indent=2));print(summary)
