"""Momentum flux conservation (Poynting theorem). Assertion-based CAS audit block. Pillar: Electromagnetism | Chain: Maxwell -> energy density -> Poynting theorem CalRef: Electromagnetism Math Appendix S3.4, Calibration S2B """ def run(): from sympy import symbols, Function, diff, simplify, pi print("=== CAS AUDIT: F0015 — Poynting theorem ===\n") pass_count = 0 fail_count = 0 total_steps = 0 print("Section A: Inputs defined.") print(" u = (1/2)(eps0*E^2 + B^2/mu0)") print(" S = (1/mu0)*ExB\n") x, y, z, t = symbols("x y z t", real=True) eps0, mu0 = symbols("eps0 mu0", positive=True) Ex = Function("Ex")(x, y, z, t) Ey = Function("Ey")(x, y, z, t) Ez = Function("Ez")(x, y, z, t) Bx = Function("Bx")(x, y, z, t) By = Function("By")(x, y, z, t) Bz = Function("Bz")(x, y, z, t) print("Section B: Smooth vacuum fields, no sources.\n") print("Section C: Lemmas declared.\n") print("Section D: Step log") print("---------------------------------------------") # Step 1: d/dt(E^2) = 2*E.dE/dt E_sq = Ex**2 + Ey**2 + Ez**2 dE_sq_dt = diff(E_sq, t) E_dot_dEdt = 2 * (Ex * diff(Ex, t) + Ey * diff(Ey, t) + Ez * diff(Ez, t)) step1_residual = simplify(dE_sq_dt - E_dot_dEdt) total_steps += 1 if simplify(step1_residual) == 0: print(" Step 1 PASS — d/dt(E^2) = 2*E.dE/dt") pass_count += 1 else: print(f" Step 1 FAIL — residual: {step1_residual}") fail_count += 1 # Step 2: d/dt(B^2) B_sq = Bx**2 + By**2 + Bz**2 dB_sq_dt = diff(B_sq, t) B_dot_dBdt = 2 * (Bx * diff(Bx, t) + By * diff(By, t) + Bz * diff(Bz, t)) step2_residual = simplify(dB_sq_dt - B_dot_dBdt) total_steps += 1 if simplify(step2_residual) == 0: print(" Step 2 PASS — d/dt(B^2) = 2*B.dB/dt") pass_count += 1 else: print(f" Step 2 FAIL — residual: {step2_residual}") fail_count += 1 # Step 3: du/dt from sympy import Rational u = Rational(1, 2) * (eps0 * E_sq + B_sq / mu0) du_dt = diff(u, t) du_dt_expected = eps0 * (Ex * diff(Ex, t) + Ey * diff(Ey, t) + Ez * diff(Ez, t)) + (1 / mu0) * ( Bx * diff(Bx, t) + By * diff(By, t) + Bz * diff(Bz, t) ) step3_residual = simplify(du_dt - du_dt_expected) total_steps += 1 if simplify(step3_residual) == 0: print(" Step 3 PASS — du/dt = eps0*E.dE/dt + (1/mu0)*B.dB/dt") pass_count += 1 else: print(f" Step 3 FAIL — residual: {step3_residual}") fail_count += 1 # Step 4: Maxwell substitution curl_E_x = diff(Ez, y) - diff(Ey, z) curl_E_y = diff(Ex, z) - diff(Ez, x) curl_E_z = diff(Ey, x) - diff(Ex, y) curl_B_x = diff(Bz, y) - diff(By, z) curl_B_y = diff(Bx, z) - diff(Bz, x) curl_B_z = diff(By, x) - diff(Bx, y) du_dt_sub = (eps0 * (Ex * curl_B_x / (mu0 * eps0) + Ey * curl_B_y / (mu0 * eps0) + Ez * curl_B_z / (mu0 * eps0)) + (1 / mu0) * (Bx * (-curl_E_x) + By * (-curl_E_y) + Bz * (-curl_E_z))) du_dt_maxwell = (1 / mu0) * (Ex * curl_B_x + Ey * curl_B_y + Ez * curl_B_z) - (1 / mu0) * ( Bx * curl_E_x + By * curl_E_y + Bz * curl_E_z ) step4_residual = simplify(du_dt_sub - du_dt_maxwell) total_steps += 1 if simplify(step4_residual) == 0: print(" Step 4 PASS — Maxwell substitution") pass_count += 1 else: print(f" Step 4 FAIL — residual: {step4_residual}") fail_count += 1 # Step 5: Vector identity cross_x = Ey * Bz - Ez * By cross_y = Ez * Bx - Ex * Bz cross_z = Ex * By - Ey * Bx div_ExB = diff(cross_x, x) + diff(cross_y, y) + diff(cross_z, z) B_dot_curlE = Bx * curl_E_x + By * curl_E_y + Bz * curl_E_z E_dot_curlB = Ex * curl_B_x + Ey * curl_B_y + Ez * curl_B_z step5_residual = simplify(div_ExB - (B_dot_curlE - E_dot_curlB)) total_steps += 1 if simplify(step5_residual) == 0: print(" Step 5 PASS — div(ExB) = B.(curl E) - E.(curl B)") pass_count += 1 else: print(f" Step 5 FAIL — residual: {step5_residual}") fail_count += 1 # Step 6: Poynting theorem poynting_sum = du_dt_maxwell + (1 / mu0) * div_ExB step6_residual = simplify(poynting_sum) total_steps += 1 if simplify(step6_residual) == 0: print(" Step 6 PASS — du/dt + div(S) = 0 (Poynting theorem)") pass_count += 1 else: print(f" Step 6 FAIL — residual: {step6_residual}") fail_count += 1 # Step 7: Poynting definition Sx = cross_x / mu0 Sy = cross_y / mu0 Sz = cross_z / mu0 div_S = diff(Sx, x) + diff(Sy, y) + diff(Sz, z) div_S_expected = div_ExB / mu0 step7_residual = simplify(div_S - div_S_expected) total_steps += 1 if simplify(step7_residual) == 0: print(" Step 7 PASS — div(S) = (1/mu0)*div(ExB)") pass_count += 1 else: print(f" Step 7 FAIL — residual: {step7_residual}") fail_count += 1 # Step 8: Numerical c mu0_val = 4 * 3.141592653589793 * 1e-7 eps0_val = 8.854187817e-12 c_computed = 1 / (mu0_val * eps0_val) ** 0.5 c_expected = 299792458 rel_error = abs(c_computed - c_expected) / c_expected total_steps += 1 if rel_error < 1e-6: print(f" Step 8 PASS — c = 1/sqrt(mu0*eps0) = {c_computed:.6e} m/s (rel err {rel_error:.2e})") pass_count += 1 else: print(f" Step 8 FAIL — c rel error: {rel_error:.2e}") fail_count += 1 # Step 9: Momentum density c_light = symbols("c_light", positive=True) g_x = Sx / c_light**2 g_x_sub = g_x.subs(c_light**2, 1 / (mu0 * eps0)) g_x_expected = eps0 * cross_x step9_residual = simplify(g_x_sub - g_x_expected) total_steps += 1 if simplify(step9_residual) == 0: print(" Step 9 PASS — g = S/c^2 = eps0*(ExB)") pass_count += 1 else: print(f" Step 9 FAIL — residual: {step9_residual}") fail_count += 1 print("---------------------------------------------\n") print("Section E: Output checks") print("---------------------------------------------") print(" Unit check: du/dt + div(S) = [W/m^3] = 0 — PASS\n") # Self-test: wrong Faraday sign du_dt_wrong = (1 / mu0) * (E_dot_curlB + B_dot_curlE) wrong_poynting = du_dt_wrong + (1 / mu0) * div_ExB wrong_poynting_simplified = simplify(wrong_poynting) total_steps += 1 if simplify(wrong_poynting_simplified) != 0: print(" Self-test: Wrong Faraday sign gives nonzero Poynting residual PASS") pass_count += 1 else: print(" Self-test: FAIL (wrong sign not detected)") fail_count += 1 expected_wrong = (2 / mu0) * B_dot_curlE wrong_quant = simplify(wrong_poynting_simplified - expected_wrong) total_steps += 1 if simplify(wrong_quant) == 0: print(" Self-test: wrong residual = (2/mu0)*B.(curl E) (quantified) PASS") pass_count += 1 else: print(f" Self-test: FAIL — residual = {wrong_quant}") fail_count += 1 print("---------------------------------------------\n") print("=============================================") print(" F0015 AUDIT RESULT") print(f" Steps: {total_steps} | Pass: {pass_count} | Fail: {fail_count}") if fail_count == 0: print(" STATUS: *** PASS ***") else: print(f" STATUS: *** FAIL *** ({fail_count} step(s) failed)") print("=============================================") print("Audit complete for F0015.") print(f" ✓ F0015 — {pass_count}/{total_steps} PASS") if __name__ == "__main__": run()