"""
Heat diffusion equation (∂T/∂t = κ∇²T).

Assertion-based CAS audit block.
Pillar: Thermodynamics | Chain: energy conservation + Fourier's law + u=ρcT → diffusion equation
CalRef: Math Appendix §4D, Thermodynamics Calibration §4D
"""


def run():
    from sympy import symbols, diff, simplify, sin, cos, exp, pi

    print('=== CAS AUDIT: F0030 — Heat diffusion equation ===\n')

    pass_count = 0
    fail_count = 0
    total_steps = 0

    x, t = symbols('x t', real=True)
    rho, c_sp, k_th, kappa = symbols('rho c_sp k_th kappa', real=True, positive=True)
    alpha_w = symbols('alpha_w', real=True, positive=True)

    # Test solution
    T_sol = exp(-kappa * alpha_w**2 * t) * sin(alpha_w * x)
    dT_dt = diff(T_sol, t)
    d2T_dx2 = diff(T_sol, x, 2)

    print('Section D: Step log')
    print('---------------------------------------------')

    # --- Step 1: Sinusoidal mode solution ---
    res1 = simplify(dT_dt - kappa * d2T_dx2)
    total_steps += 1
    if simplify(res1) == 0:
        print('  Step 1  PASS — T=e^{−κα²t}sin(αx) satisfies ∂T/∂t = κ∇²T')
        pass_count += 1
    else:
        print('  Step 1  FAIL')
        fail_count += 1

    # --- Step 2: Fourier substitution chain ---
    conservation_residual = rho * c_sp * dT_dt - k_th * d2T_dx2
    conservation_sub = conservation_residual.subs(kappa, k_th/(rho*c_sp))
    res2 = simplify(conservation_sub)
    total_steps += 1
    if simplify(res2) == 0:
        print('  Step 2  PASS — ρc·∂T/∂t − k·∂²T/∂x² = 0 when κ=k/(ρc)')
        pass_count += 1
    else:
        print('  Step 2  FAIL')
        fail_count += 1

    # --- Step 3: Thermal diffusivity definition ---
    res3_sub = simplify(k_th - rho * c_sp * kappa).subs(kappa, k_th/(rho*c_sp))
    total_steps += 1
    if simplify(res3_sub) == 0:
        print('  Step 3  PASS — κ = k/(ρc) (thermal diffusivity definition)')
        pass_count += 1
    else:
        print('  Step 3  FAIL')
        fail_count += 1

    # --- Step 4: Cosine mode ---
    T_cos = exp(-kappa * alpha_w**2 * t) * cos(alpha_w * x)
    dT_cos_dt = diff(T_cos, t)
    d2T_cos_dx2 = diff(T_cos, x, 2)
    res4 = simplify(dT_cos_dt - kappa * d2T_cos_dx2)
    total_steps += 1
    if simplify(res4) == 0:
        print('  Step 4  PASS — T=e^{−κα²t}cos(αx) also satisfies ∂T/∂t = κ∇²T')
        pass_count += 1
    else:
        print('  Step 4  FAIL')
        fail_count += 1

    # --- Step 5: Superposition (linearity) ---
    a_coeff, b_coeff = symbols('a_coeff b_coeff', real=True)
    T_super = a_coeff * T_sol + b_coeff * T_cos
    dT_super_dt = diff(T_super, t)
    d2T_super_dx2 = diff(T_super, x, 2)
    res5 = simplify(dT_super_dt - kappa * d2T_super_dx2)
    total_steps += 1
    if simplify(res5) == 0:
        print('  Step 5  PASS — Superposition preserved (linearity of diffusion eq)')
        pass_count += 1
    else:
        print('  Step 5  FAIL')
        fail_count += 1

    # --- Step 6: Two-sided localisation ---
    wrong_residual = simplify(dT_dt - kappa * diff(T_sol, x))
    total_steps += 1
    if not (simplify(wrong_residual) == 0):
        print('  Step 6  PASS — Wrong PDE (∂T/∂t = κ∂T/∂x) correctly rejected')
        pass_count += 1
    else:
        print('  Step 6  FAIL')
        fail_count += 1

    # --- Step 7: Steady-state limit ---
    A_lin, B_lin = symbols('A_lin B_lin', real=True)
    T_steady = A_lin * x + B_lin
    d2T_steady = diff(T_steady, x, 2)
    res7 = simplify(d2T_steady)
    total_steps += 1
    if simplify(res7) == 0:
        print('  Step 7  PASS — Steady state: T=Ax+B satisfies ∇²T=0 (Laplace limit)')
        pass_count += 1
    else:
        print('  Step 7  FAIL')
        fail_count += 1

    # --- Step 8: Decay rate depends on wave number ---
    alpha1, alpha2 = symbols('alpha1 alpha2', real=True, positive=True)
    rate1 = kappa * alpha1**2
    rate2 = kappa * alpha2**2
    ratio = simplify(rate2.subs(alpha2, 2*alpha1) / rate1)
    res8 = simplify(ratio - 4)
    total_steps += 1
    if simplify(res8) == 0:
        print('  Step 8  PASS — Decay rate ∝ α²: doubling α quadruples decay')
        pass_count += 1
    else:
        print('  Step 8  FAIL')
        fail_count += 1

    # --- Step 9: Numerical — iron bar diffusion ---
    k_num = 80.0
    rho_num = 7874.0
    c_num = 449.0
    kappa_num = k_num / (rho_num * c_num)
    L_num = 0.1
    alpha_num = pi / L_num
    tau_num = 1.0 / (kappa_num * alpha_num**2)
    kappa_expected = 2.263e-5
    tau_expected = 44.8
    total_steps += 1
    if abs(kappa_num - kappa_expected)/kappa_expected < 0.01 and abs(tau_num - tau_expected)/tau_expected < 0.01:
        print(f'  Step 9  PASS — Iron: κ={kappa_num:.3e} m²/s, τ={tau_num:.1f} s (L=0.1m fundamental mode)')
        pass_count += 1
    else:
        print('  Step 9  FAIL')
        fail_count += 1

    # --- Step 10: Unit consistency ---
    D_dim = symbols('D_dim', real=True, positive=True)
    k_proxy = rho * c_sp * D_dim
    kappa_proxy = k_proxy / (rho * c_sp)
    res10 = simplify(kappa_proxy - D_dim)
    total_steps += 1
    if simplify(res10) == 0:
        print('  Step 10 PASS — [κ] = [m²/s], [∂T/∂t] = [κ∇²T] = [K/s]')
        pass_count += 1
    else:
        print('  Step 10 FAIL')
        fail_count += 1

    # --- Step 11: Self-test — wrong sign in Fourier's law ---
    wrong_antidiff = simplify(dT_dt + kappa * d2T_dx2)
    total_steps += 1
    if not (simplify(wrong_antidiff) == 0):
        print('  Step 11 PASS — Wrong Fourier sign → anti-diffusion detected')
        pass_count += 1
    else:
        print('  Step 11 FAIL')
        fail_count += 1

    print('---------------------------------------------\n')

    # ---- VERDICT ----
    print('=============================================')
    print('  F0030 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'  ✓ F0030 — {pass_count}/{total_steps} PASS')


if __name__ == '__main__':
    run()
