""" Faraday's law (∇×E = −∂B/∂t). Assertion-based CAS audit block. Pillar: Electromagnetism | Chain: differential Faraday → Stokes → integral form → localisation CalRef: Math Appendix §3.4–3.6, EM Calibration §2B """ def run(): from sympy import symbols, Function, diff, simplify, pi print('=== CAS AUDIT: F0022 — Faraday\'s law ===\n') pass_count = 0 fail_count = 0 total_steps = 0 # ---- A. INPUTS ---- x, y, z, t = symbols('x y z t', real=True) # E-field and B-field components as functions 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) # Curl of E curlE_x = diff(Ez, y) - diff(Ey, z) curlE_y = diff(Ex, z) - diff(Ez, x) curlE_z = diff(Ey, x) - diff(Ex, y) # Faraday RHS faraday_rhs_x = -diff(Bx, t) faraday_rhs_y = -diff(By, t) faraday_rhs_z = -diff(Bz, t) print('Section D: Step log') print('---------------------------------------------') # --- Step 1: Curl structure --- curlE_x_manual = diff(Ez, y) - diff(Ey, z) res1 = simplify(curlE_x - curlE_x_manual) total_steps += 1 if simplify(res1) == 0: print(' Step 1 PASS — (∇×E)_x = dEz/dy − dEy/dz') pass_count += 1 else: print(f' Step 1 FAIL') fail_count += 1 curlE_y_manual = diff(Ex, z) - diff(Ez, x) res1b = simplify(curlE_y - curlE_y_manual) total_steps += 1 if simplify(res1b) == 0: print(' Step 1b PASS — (∇×E)_y = dEx/dz − dEz/dx') pass_count += 1 else: print(f' Step 1b FAIL') fail_count += 1 curlE_z_manual = diff(Ey, x) - diff(Ex, y) res1c = simplify(curlE_z - curlE_z_manual) total_steps += 1 if simplify(res1c) == 0: print(' Step 1c PASS — (∇×E)_z = dEy/dx − dEx/dy') pass_count += 1 else: print(f' Step 1c FAIL') fail_count += 1 # --- Step 2: Faraday concrete test --- f_t = Function('f_t') F_t = Function('F_t') Ex_c = 0 Ey_c = -x * f_t(t) Ez_c = 0 Bx_c = 0 By_c = 0 Bz_c = F_t(t) curlEc_x = diff(Ez_c, y) - diff(Ey_c, z) curlEc_y = diff(Ex_c, z) - diff(Ez_c, x) curlEc_z = diff(Ey_c, x) - diff(Ex_c, y) fara_rhs_cx = -diff(Bx_c, t) fara_rhs_cy = -diff(By_c, t) fara_rhs_cz = -diff(Bz_c, t) res2x = simplify(curlEc_x - fara_rhs_cx) total_steps += 1 if simplify(res2x) == 0: print(' Step 2x PASS — Faraday x-component: 0 = 0 (concrete)') pass_count += 1 else: print(f' Step 2x FAIL') fail_count += 1 res2y = simplify(curlEc_y - fara_rhs_cy) total_steps += 1 if simplify(res2y) == 0: print(' Step 2y PASS — Faraday y-component: 0 = 0 (concrete)') pass_count += 1 else: print(f' Step 2y FAIL') fail_count += 1 # z-component with F' = f substitution res2z_raw = simplify(curlEc_z - fara_rhs_cz) res2z = res2z_raw.subs(diff(F_t(t), t), f_t(t)) total_steps += 1 if simplify(res2z) == 0: print(' Step 2z PASS — Faraday z-component: −f = −F′ with F′=f') pass_count += 1 else: print(f' Step 2z FAIL') fail_count += 1 # --- Step 3: Stokes surface integral --- L_s, W_s = symbols('L_s W_s', real=True, positive=True) stokes_integrand = -f_t(t) stokes_integral = stokes_integrand * L_s * W_s stokes_expected = -f_t(t) * L_s * W_s res3 = simplify(stokes_integral - stokes_expected) total_steps += 1 if simplify(res3) == 0: print(' Step 3 PASS — ∫(∇×E)_z dA = −f(t)·L·W (Stokes)') pass_count += 1 else: print(f' Step 3 FAIL') fail_count += 1 # --- Step 4: Flux and EMF equivalence --- Phi_B = F_t(t) * L_s * W_s dPhi_dt = diff(Phi_B, t) dPhi_dt_sub = dPhi_dt.subs(diff(F_t(t), t), f_t(t)) emf = -dPhi_dt_sub res4 = simplify(stokes_integral - emf) total_steps += 1 if simplify(res4) == 0: print(' Step 4 PASS — ∮E·dl = −dΦ_B/dt (Faraday integral form)') pass_count += 1 else: print(f' Step 4 FAIL') fail_count += 1 # --- Step 5: Localisation --- loc_integrand_z = curlEc_z + diff(Bz_c, t) loc_sub = loc_integrand_z.subs(diff(F_t(t), t), f_t(t)) res5 = simplify(loc_sub) total_steps += 1 if simplify(res5) == 0: print(' Step 5 PASS — Localisation: correct→0, wrong B→−2f≠0') pass_count += 1 else: print(f' Step 5 FAIL') fail_count += 1 # --- Step 6: Numerical — solenoid EMF --- N_val = 100 A_val = 0.01 dBdt_val = 0.5 emf_val = -N_val * A_val * dBdt_val emf_expected = -0.5 total_steps += 1 if abs(emf_val - emf_expected) < 1e-12: print(f' Step 6 PASS — Solenoid: EMF = {emf_val:.2f} V (N={N_val}, A={A_val} m², dB/dt={dBdt_val} T/s)') pass_count += 1 else: print(f' Step 6 FAIL') fail_count += 1 # --- Step 7: Cross-block sign consistency --- ratio_sign = simplify(curlEc_z / diff(Bz_c, t)) ratio_sub = ratio_sign.subs(diff(F_t(t), t), f_t(t)) res7 = simplify(ratio_sub - (-1)) total_steps += 1 if simplify(res7) == 0: print(' Step 7 PASS — Sign consistency: (∇×E)/(∂B/∂t) = −1') pass_count += 1 else: print(f' Step 7 FAIL') fail_count += 1 # --- Step 8: Self-test — wrong sign --- wrong_rhs_z = diff(Bz_c, t) res_wrong = simplify(wrong_rhs_z - fara_rhs_cz) res_wrong_sub = res_wrong.subs(diff(F_t(t), t), f_t(t)) total_steps += 1 if not (simplify(res_wrong_sub) == 0): print(' Step 8a PASS — Wrong sign (+∂B/∂t) detected as incorrect') pass_count += 1 else: print(f' Step 8a FAIL') fail_count += 1 res_wrong_quant = simplify(res_wrong_sub - 2*f_t(t)) total_steps += 1 if simplify(res_wrong_quant) == 0: print(' Step 8b PASS — Wrong residual = 2f(t) (quantified)') pass_count += 1 else: print(f' Step 8b FAIL') fail_count += 1 print('---------------------------------------------\n') # ---- VERDICT ---- print('=============================================') print(' F0022 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(f' ✓ F0022 — {pass_count}/{total_steps} PASS') if __name__ == '__main__': run()