Path: blob/main/latex-templates/templates/optics/polarization.tex
51 views
unlisted
\documentclass[a4paper, 11pt]{article}1\usepackage[utf8]{inputenc}2\usepackage[T1]{fontenc}3\usepackage{amsmath, amssymb}4\usepackage{graphicx}5\usepackage{siunitx}6\usepackage{booktabs}7\usepackage[makestderr]{pythontex}89\title{Optics: Polarization States and Jones Calculus}10\author{Computational Science Templates}11\date{\today}1213\begin{document}14\maketitle1516\section{Introduction}17Polarization describes the orientation of the electric field oscillation in electromagnetic waves. This analysis explores polarization states using Jones vectors and Mueller matrices, demonstrating the effects of optical elements like polarizers, wave plates, and rotators. Applications in ellipsometry, stress analysis, and optical communications are examined.1819\section{Mathematical Framework}2021\subsection{Jones Vectors}22Jones vectors represent polarization states:23\begin{equation}24\mathbf{E} = \begin{pmatrix} E_x \\ E_y \end{pmatrix} = \begin{pmatrix} A_x e^{i\phi_x} \\ A_y e^{i\phi_y} \end{pmatrix}25\end{equation}2627\subsection{Stokes Parameters}28The Stokes vector describes polarization including partial polarization:29\begin{equation}30\mathbf{S} = \begin{pmatrix} S_0 \\ S_1 \\ S_2 \\ S_3 \end{pmatrix} = \begin{pmatrix} |E_x|^2 + |E_y|^2 \\ |E_x|^2 - |E_y|^2 \\ 2\text{Re}(E_x E_y^*) \\ 2\text{Im}(E_x E_y^*) \end{pmatrix}31\end{equation}3233\subsection{Jones Matrices}34Common Jones matrices:35\begin{itemize}36\item Linear polarizer at angle $\theta$: $J_P = \begin{pmatrix} \cos^2\theta & \cos\theta\sin\theta \\ \cos\theta\sin\theta & \sin^2\theta \end{pmatrix}$37\item Wave plate with retardance $\delta$: $J_W = \begin{pmatrix} e^{-i\delta/2} & 0 \\ 0 & e^{i\delta/2} \end{pmatrix}$38\end{itemize}3940\section{Environment Setup}41\begin{pycode}42import numpy as np43import matplotlib.pyplot as plt44plt.rc('text', usetex=True)45plt.rc('font', family='serif')4647def save_plot(filename, caption=""):48plt.savefig(filename, bbox_inches='tight', dpi=150)49print(r'\begin{figure}[htbp]')50print(r'\centering')51print(r'\includegraphics[width=0.95\textwidth]{' + filename + '}')52if caption:53print(r'\caption{' + caption + '}')54print(r'\end{figure}')55plt.close()56\end{pycode}5758\section{Jones Vector Representation}59\begin{pycode}60# Jones vectors for common polarization states61def linear_pol(theta):62"""Linear polarization at angle theta."""63return np.array([np.cos(theta), np.sin(theta)])6465def circular_pol(handedness='right'):66"""Circular polarization."""67if handedness == 'right':68return np.array([1, -1j]) / np.sqrt(2)69else:70return np.array([1, 1j]) / np.sqrt(2)7172def elliptical_pol(a, b, theta=0, handedness='right'):73"""Elliptical polarization with semi-axes a, b at angle theta."""74sign = -1 if handedness == 'right' else 175E = np.array([a, sign * 1j * b])76# Rotate by theta77c, s = np.cos(theta), np.sin(theta)78R = np.array([[c, -s], [s, c]])79return R @ E / np.sqrt(a**2 + b**2)8081# Jones matrices82def linear_polarizer(theta):83"""Linear polarizer at angle theta."""84c, s = np.cos(theta), np.sin(theta)85return np.array([[c**2, c*s], [c*s, s**2]])8687def wave_plate(delta, theta=0):88"""Wave plate with retardance delta, fast axis at angle theta."""89c, s = np.cos(theta), np.sin(theta)90R = np.array([[c, s], [-s, c]])91W = np.array([[np.exp(-1j*delta/2), 0], [0, np.exp(1j*delta/2)]])92return R.T @ W @ R9394def quarter_wave(theta=0):95return wave_plate(np.pi/2, theta)9697def half_wave(theta=0):98return wave_plate(np.pi, theta)99100def rotator(theta):101"""Polarization rotator (Faraday rotator)."""102c, s = np.cos(theta), np.sin(theta)103return np.array([[c, -s], [s, c]])104105# Visualization functions106def polarization_ellipse(jones, n_points=100):107"""Generate polarization ellipse from Jones vector."""108t = np.linspace(0, 2*np.pi, n_points)109Ex = np.real(jones[0] * np.exp(1j*t))110Ey = np.real(jones[1] * np.exp(1j*t))111return Ex, Ey112113fig, axes = plt.subplots(2, 2, figsize=(10, 8))114115# Plot 1: Common polarization states116states = [117('Horizontal', linear_pol(0), 'blue'),118('Vertical', linear_pol(np.pi/2), 'red'),119('45$^\\circ$', linear_pol(np.pi/4), 'green'),120('RCP', circular_pol('right'), 'purple'),121('LCP', circular_pol('left'), 'orange')122]123124for name, jones, color in states:125Ex, Ey = polarization_ellipse(jones)126axes[0, 0].plot(Ex, Ey, color=color, linewidth=2, label=name)127128axes[0, 0].set_xlabel('$E_x$')129axes[0, 0].set_ylabel('$E_y$')130axes[0, 0].set_title('Polarization States')131axes[0, 0].legend(fontsize=8, loc='upper right')132axes[0, 0].set_xlim([-1.2, 1.2])133axes[0, 0].set_ylim([-1.2, 1.2])134axes[0, 0].set_aspect('equal')135axes[0, 0].grid(True, alpha=0.3)136137# Plot 2: Elliptical polarization with different ellipticities138ellipticities = [0, 0.3, 0.6, 1.0]139colors_ell = ['blue', 'green', 'orange', 'red']140141for ell, color in zip(ellipticities, colors_ell):142a = 1143b = ell144jones = elliptical_pol(a, b, theta=np.pi/6)145Ex, Ey = polarization_ellipse(jones)146axes[0, 1].plot(Ex, Ey, color=color, linewidth=2, label=f'$\\varepsilon = {ell:.1f}$')147148axes[0, 1].set_xlabel('$E_x$')149axes[0, 1].set_ylabel('$E_y$')150axes[0, 1].set_title('Elliptical Polarization')151axes[0, 1].legend(fontsize=8)152axes[0, 1].set_aspect('equal')153axes[0, 1].grid(True, alpha=0.3)154155# Plot 3: 3D representation of electric field156t = np.linspace(0, 4*np.pi, 200)157z = t / (2*np.pi)158159# Right circular polarization160from mpl_toolkits.mplot3d import Axes3D161ax3d = axes[1, 0]162163Ex_rcp = np.cos(t)164Ey_rcp = np.sin(t)165166# Project onto 2D (simplified)167ax3d.plot(t / np.pi, Ex_rcp, 'b-', linewidth=1.5, label='$E_x$')168ax3d.plot(t / np.pi, Ey_rcp, 'r--', linewidth=1.5, label='$E_y$')169ax3d.set_xlabel('Phase ($\\pi$)')170ax3d.set_ylabel('Electric field')171ax3d.set_title('RCP Electric Field Components')172ax3d.legend()173ax3d.grid(True, alpha=0.3)174175# Plot 4: Poincare sphere projection (Stokes parameters)176def jones_to_stokes(jones):177Ex, Ey = jones178S0 = np.abs(Ex)**2 + np.abs(Ey)**2179S1 = np.abs(Ex)**2 - np.abs(Ey)**2180S2 = 2 * np.real(Ex * np.conj(Ey))181S3 = 2 * np.imag(Ex * np.conj(Ey))182return np.array([S0, S1, S2, S3])183184# Generate points on Poincare sphere185theta_p = np.linspace(0, 2*np.pi, 50)186phi_p = np.linspace(0, np.pi, 25)187THETA, PHI = np.meshgrid(theta_p, phi_p)188189S1_sphere = np.sin(PHI) * np.cos(THETA)190S2_sphere = np.sin(PHI) * np.sin(THETA)191S3_sphere = np.cos(PHI)192193axes[1, 1].contourf(S1_sphere, S2_sphere, S3_sphere, levels=20, cmap='coolwarm')194axes[1, 1].set_xlabel('$S_1/S_0$')195axes[1, 1].set_ylabel('$S_2/S_0$')196axes[1, 1].set_title('Poincar\\'e Sphere Projection')197axes[1, 1].set_aspect('equal')198199# Mark key states200for name, jones, color in states[:3]:201S = jones_to_stokes(jones)202axes[1, 1].plot(S[1]/S[0], S[2]/S[0], 'o', color=color, markersize=8)203204plt.tight_layout()205save_plot('polarization_states.pdf', 'Polarization states: Jones vectors, elliptical polarization, and Poincar\\'e sphere.')206\end{pycode}207208\section{Malus's Law and Polarizer Chains}209\begin{pycode}210# Malus's Law demonstration211angles = np.linspace(0, np.pi, 100)212input_pol = linear_pol(0) # Horizontal213transmitted = []214for theta in angles:215P = linear_polarizer(theta)216output = P @ input_pol217intensity = np.abs(output[0])**2 + np.abs(output[1])**2218transmitted.append(intensity)219220fig, axes = plt.subplots(2, 2, figsize=(10, 8))221222# Plot 1: Malus's Law223axes[0, 0].plot(np.rad2deg(angles), transmitted, 'b-', linewidth=2)224axes[0, 0].plot(np.rad2deg(angles), np.cos(angles)**2, 'r--', linewidth=1.5, alpha=0.7, label='Theory')225axes[0, 0].set_xlabel('Polarizer Angle (degrees)')226axes[0, 0].set_ylabel('Transmitted Intensity')227axes[0, 0].set_title("Malus's Law: $I = I_0\\cos^2\\theta$")228axes[0, 0].legend()229axes[0, 0].grid(True, alpha=0.3)230231# Plot 2: Two crossed polarizers with intermediate polarizer232intermediate_angles = np.linspace(0, np.pi/2, 50)233transmission_chain = []234235for theta_mid in intermediate_angles:236# Three polarizers: 0, theta_mid, 90 degrees237P1 = linear_polarizer(0)238P2 = linear_polarizer(theta_mid)239P3 = linear_polarizer(np.pi/2)240241output = P3 @ P2 @ P1 @ input_pol242intensity = np.abs(output[0])**2 + np.abs(output[1])**2243transmission_chain.append(intensity)244245# Theory: cos^2(theta) * cos^2(90-theta) = 0.25*sin^2(2*theta)246theory = 0.25 * np.sin(2 * intermediate_angles)**2247248axes[0, 1].plot(np.rad2deg(intermediate_angles), transmission_chain, 'b-', linewidth=2, label='Simulation')249axes[0, 1].plot(np.rad2deg(intermediate_angles), theory, 'r--', linewidth=1.5, alpha=0.7, label='Theory')250axes[0, 1].set_xlabel('Intermediate Polarizer Angle (degrees)')251axes[0, 1].set_ylabel('Transmitted Intensity')252axes[0, 1].set_title('Crossed Polarizers with Intermediate')253axes[0, 1].legend()254axes[0, 1].grid(True, alpha=0.3)255256# Plot 3: N polarizers between crossed pair257N_polarizers = np.arange(1, 21)258transmission_N = []259260for N in N_polarizers:261if N == 0:262transmission_N.append(0)263else:264angles_chain = np.linspace(0, np.pi/2, N + 2)265jones = input_pol266for angle in angles_chain:267P = linear_polarizer(angle)268jones = P @ jones269intensity = np.abs(jones[0])**2 + np.abs(jones[1])**2270transmission_N.append(intensity)271272# Theory: cos^(2N)(pi/(2N))273theory_N = np.cos(np.pi / (2 * (N_polarizers + 1)))**(2 * (N_polarizers + 1))274275axes[1, 0].plot(N_polarizers, transmission_N, 'bo-', linewidth=1.5, markersize=4, label='Simulation')276axes[1, 0].plot(N_polarizers, theory_N, 'r--', linewidth=1.5, alpha=0.7, label='Theory')277axes[1, 0].set_xlabel('Number of Intermediate Polarizers')278axes[1, 0].set_ylabel('Transmitted Intensity')279axes[1, 0].set_title('Transmission Through N Polarizers')280axes[1, 0].legend()281axes[1, 0].grid(True, alpha=0.3)282283# Plot 4: Extinction ratio284extinction_ratios = []285polarizer_angles = np.linspace(0, np.pi, 500)286287# Perfect polarizer288for theta in polarizer_angles:289P = linear_polarizer(theta)290output = P @ input_pol291intensity = np.abs(output[0])**2 + np.abs(output[1])**2292extinction_ratios.append(intensity)293294axes[1, 1].semilogy(np.rad2deg(polarizer_angles), extinction_ratios, 'b-', linewidth=2)295axes[1, 1].set_xlabel('Polarizer Angle (degrees)')296axes[1, 1].set_ylabel('Transmitted Intensity')297axes[1, 1].set_title('Extinction Ratio')298axes[1, 1].set_ylim([1e-6, 1.5])299axes[1, 1].grid(True, alpha=0.3, which='both')300301plt.tight_layout()302save_plot('malus_law.pdf', "Malus's law, polarizer chains, and extinction ratio analysis.")303\end{pycode}304305\section{Wave Plates and Polarization Conversion}306\begin{pycode}307fig, axes = plt.subplots(2, 2, figsize=(10, 8))308309# Plot 1: Quarter-wave plate effect310input_linear = linear_pol(np.pi/4)311qwp_angles = [0, np.pi/8, np.pi/4]312colors = ['blue', 'green', 'red']313labels = ['$\\theta = 0^\\circ$ (elliptical)', '$\\theta = 22.5^\\circ$', '$\\theta = 45^\\circ$ (circular)']314315for theta, color, label in zip(qwp_angles, colors, labels):316QWP = quarter_wave(theta)317output = QWP @ input_linear318Ex, Ey = polarization_ellipse(output)319axes[0, 0].plot(Ex, Ey, color=color, linewidth=2, label=label)320321axes[0, 0].set_xlabel('$E_x$')322axes[0, 0].set_ylabel('$E_y$')323axes[0, 0].set_title('Quarter-Wave Plate Effects (45$^\\circ$ input)')324axes[0, 0].legend(fontsize=8)325axes[0, 0].set_aspect('equal')326axes[0, 0].grid(True, alpha=0.3)327328# Plot 2: Half-wave plate rotation329input_horizontal = linear_pol(0)330hwp_angles = np.linspace(0, np.pi/2, 5)331colors_hwp = plt.cm.viridis(np.linspace(0, 1, 5))332333for theta, color in zip(hwp_angles, colors_hwp):334HWP = half_wave(theta)335output = HWP @ input_horizontal336Ex, Ey = polarization_ellipse(output)337axes[0, 1].plot(Ex, Ey, color=color, linewidth=2, label=f'$\\theta = {np.rad2deg(theta):.0f}^\\circ$')338339axes[0, 1].set_xlabel('$E_x$')340axes[0, 1].set_ylabel('$E_y$')341axes[0, 1].set_title('Half-Wave Plate Rotation')342axes[0, 1].legend(fontsize=8)343axes[0, 1].set_aspect('equal')344axes[0, 1].grid(True, alpha=0.3)345346# Plot 3: Retardance scan - output intensity through analyzer347retardances = np.linspace(0, 4*np.pi, 200)348analyzer_angles = [0, np.pi/4, np.pi/2]349colors_ret = ['blue', 'green', 'red']350351input_45 = linear_pol(np.pi/4)352353for analyzer, color in zip(analyzer_angles, colors_ret):354intensities = []355for delta in retardances:356WP = wave_plate(delta, theta=0)357A = linear_polarizer(analyzer)358output = A @ WP @ input_45359I = np.abs(output[0])**2 + np.abs(output[1])**2360intensities.append(I)361362axes[1, 0].plot(retardances/np.pi, intensities, color=color, linewidth=2,363label=f'Analyzer: {np.rad2deg(analyzer):.0f}$^\\circ$')364365axes[1, 0].set_xlabel('Retardance ($\\pi$)')366axes[1, 0].set_ylabel('Transmitted Intensity')367axes[1, 0].set_title('Intensity vs Retardance')368axes[1, 0].legend(fontsize=8)369axes[1, 0].grid(True, alpha=0.3)370371# Plot 4: Circular to linear conversion (QWP)372input_rcp = circular_pol('right')373qwp_scan = np.linspace(0, np.pi, 100)374ellipticity_output = []375376for theta in qwp_scan:377QWP = quarter_wave(theta)378output = QWP @ input_rcp379380# Calculate ellipticity from Stokes parameters381S = jones_to_stokes(output)382ellipticity = np.arctan2(S[3], np.sqrt(S[1]**2 + S[2]**2)) / (np.pi/2)383ellipticity_output.append(ellipticity)384385axes[1, 1].plot(np.rad2deg(qwp_scan), ellipticity_output, 'b-', linewidth=2)386axes[1, 1].axhline(y=0, color='gray', linestyle='--', alpha=0.7)387axes[1, 1].set_xlabel('QWP Fast Axis Angle (degrees)')388axes[1, 1].set_ylabel('Output Ellipticity')389axes[1, 1].set_title('RCP Through QWP')390axes[1, 1].grid(True, alpha=0.3)391392plt.tight_layout()393save_plot('wave_plates.pdf', 'Wave plate effects: QWP, HWP, retardance scan, and circular to linear conversion.')394\end{pycode}395396\section{Mueller Matrix Formalism}397\begin{pycode}398# Mueller matrices for partially polarized light399def jones_to_mueller(J):400"""Convert Jones matrix to Mueller matrix."""401# Using Kronecker product method402A = np.array([[1, 0, 0, 1],403[1, 0, 0, -1],404[0, 1, 1, 0],405[0, 1j, -1j, 0]])406A_inv = np.linalg.inv(A)407408# J tensor J* is 4x4409J_kron = np.kron(J, np.conj(J))410411M = np.real(A @ J_kron @ A_inv)412return M413414# Mueller matrix for depolarizer415def depolarizer_mueller(p):416"""Mueller matrix for partial depolarizer with polarization degree p."""417return np.diag([1, p, p, p])418419# Mueller matrix for linear polarizer420def polarizer_mueller(theta):421c2 = np.cos(2*theta)422s2 = np.sin(2*theta)423return 0.5 * np.array([[1, c2, s2, 0],424[c2, c2**2, c2*s2, 0],425[s2, c2*s2, s2**2, 0],426[0, 0, 0, 0]])427428# Mueller matrix for retarder429def retarder_mueller(delta, theta=0):430c2 = np.cos(2*theta)431s2 = np.sin(2*theta)432cd = np.cos(delta)433sd = np.sin(delta)434return np.array([[1, 0, 0, 0],435[0, c2**2 + s2**2*cd, c2*s2*(1-cd), -s2*sd],436[0, c2*s2*(1-cd), s2**2 + c2**2*cd, c2*sd],437[0, s2*sd, -c2*sd, cd]])438439fig, axes = plt.subplots(2, 2, figsize=(10, 8))440441# Plot 1: Degree of polarization through depolarizer442S_in = np.array([1, 1, 0, 0]) # Horizontal polarized443dop_values = np.linspace(0, 1, 100)444dop_out = []445446for p in dop_values:447M = depolarizer_mueller(p)448S_out = M @ S_in449dop = np.sqrt(S_out[1]**2 + S_out[2]**2 + S_out[3]**2) / S_out[0]450dop_out.append(dop)451452axes[0, 0].plot(dop_values, dop_out, 'b-', linewidth=2)453axes[0, 0].plot([0, 1], [0, 1], 'r--', linewidth=1.5, alpha=0.7, label='Linear')454axes[0, 0].set_xlabel('Depolarizer parameter $p$')455axes[0, 0].set_ylabel('Output DOP')456axes[0, 0].set_title('Degree of Polarization Through Depolarizer')457axes[0, 0].legend()458axes[0, 0].grid(True, alpha=0.3)459460# Plot 2: Partially polarized light through polarizer461dop_in_values = [0.2, 0.5, 0.8, 1.0]462colors_dop = ['red', 'orange', 'green', 'blue']463polarizer_angles = np.linspace(0, np.pi, 100)464465for dop_in, color in zip(dop_in_values, colors_dop):466# Partially polarized horizontal467S_in = np.array([1, dop_in, 0, 0])468intensities = []469470for theta in polarizer_angles:471M = polarizer_mueller(theta)472S_out = M @ S_in473intensities.append(S_out[0])474475axes[0, 1].plot(np.rad2deg(polarizer_angles), intensities, color=color, linewidth=2,476label=f'DOP = {dop_in:.1f}')477478axes[0, 1].set_xlabel('Polarizer Angle (degrees)')479axes[0, 1].set_ylabel('Transmitted Intensity')480axes[0, 1].set_title('Partially Polarized Light Through Polarizer')481axes[0, 1].legend(fontsize=8)482axes[0, 1].grid(True, alpha=0.3)483484# Plot 3: Mueller matrix visualization485M_qwp = retarder_mueller(np.pi/2, 0)486487im = axes[1, 0].imshow(M_qwp, cmap='RdBu', vmin=-1, vmax=1)488axes[1, 0].set_xticks([0, 1, 2, 3])489axes[1, 0].set_yticks([0, 1, 2, 3])490axes[1, 0].set_xticklabels(['$S_0$', '$S_1$', '$S_2$', '$S_3$'])491axes[1, 0].set_yticklabels(['$S_0$', '$S_1$', '$S_2$', '$S_3$'])492axes[1, 0].set_title('Mueller Matrix: QWP at 0$^\\circ$')493494for i in range(4):495for j in range(4):496val = M_qwp[i, j]497axes[1, 0].text(j, i, f'{val:.2f}', ha='center', va='center', fontsize=9)498499# Plot 4: Stokes vector trajectory on Poincare sphere500# RCP through rotating HWP501hwp_rotation = np.linspace(0, np.pi, 100)502S_rcp = np.array([1, 0, 0, 1]) # RCP503504S1_traj = []505S2_traj = []506S3_traj = []507508for theta in hwp_rotation:509M = retarder_mueller(np.pi, theta)510S_out = M @ S_rcp511S1_traj.append(S_out[1]/S_out[0])512S2_traj.append(S_out[2]/S_out[0])513S3_traj.append(S_out[3]/S_out[0])514515axes[1, 1].plot(S1_traj, S2_traj, 'b-', linewidth=2)516axes[1, 1].plot(S1_traj[0], S2_traj[0], 'go', markersize=8, label='Start')517axes[1, 1].plot(S1_traj[-1], S2_traj[-1], 'ro', markersize=8, label='End')518# Draw unit circle519theta_circle = np.linspace(0, 2*np.pi, 100)520axes[1, 1].plot(np.cos(theta_circle), np.sin(theta_circle), 'k--', alpha=0.3)521axes[1, 1].set_xlabel('$S_1/S_0$')522axes[1, 1].set_ylabel('$S_2/S_0$')523axes[1, 1].set_title('Stokes Vector Trajectory (RCP through rotating HWP)')524axes[1, 1].legend()525axes[1, 1].set_aspect('equal')526axes[1, 1].grid(True, alpha=0.3)527528plt.tight_layout()529save_plot('mueller_matrix.pdf', 'Mueller matrix formalism: depolarization, partial polarization, and Stokes trajectories.')530\end{pycode}531532\section{Optical Activity and Faraday Effect}533\begin{pycode}534# Optical activity (natural rotation)535def optically_active_medium(thickness, specific_rotation, concentration=1):536"""Jones matrix for optically active medium."""537rotation = specific_rotation * thickness * concentration538return rotator(rotation)539540# Faraday rotator541def faraday_rotator(thickness, verdet_constant, B_field):542"""Jones matrix for Faraday effect."""543rotation = verdet_constant * B_field * thickness544return rotator(rotation)545546fig, axes = plt.subplots(2, 2, figsize=(10, 8))547548# Plot 1: Optical rotation vs thickness549thicknesses = np.linspace(0, 10, 100) # cm550specific_rotation = 66.5 # degrees/dm for sucrose551concentrations = [0.1, 0.2, 0.5, 1.0] # g/mL552colors_conc = ['blue', 'green', 'orange', 'red']553554input_h = linear_pol(0)555556for conc, color in zip(concentrations, colors_conc):557rotations = []558for t in thicknesses:559M = optically_active_medium(t/10, np.deg2rad(specific_rotation), conc)560output = M @ input_h561# Calculate rotation angle562angle = np.arctan2(np.real(output[1]), np.real(output[0]))563rotations.append(np.rad2deg(angle))564565axes[0, 0].plot(thicknesses, rotations, color=color, linewidth=2,566label=f'c = {conc} g/mL')567568axes[0, 0].set_xlabel('Path length (cm)')569axes[0, 0].set_ylabel('Rotation angle (degrees)')570axes[0, 0].set_title('Optical Rotation (Sucrose)')571axes[0, 0].legend(fontsize=8)572axes[0, 0].grid(True, alpha=0.3)573574# Plot 2: Faraday rotation vs magnetic field575B_fields = np.linspace(0, 1, 100) # Tesla576verdet_constant = 3.8 # rad/(T*m) for terbium gallium garnet577thickness = 0.01 # m578579rotation_faraday = verdet_constant * B_fields * thickness * 180 / np.pi580581axes[0, 1].plot(B_fields, rotation_faraday, 'b-', linewidth=2)582axes[0, 1].set_xlabel('Magnetic field (T)')583axes[0, 1].set_ylabel('Rotation angle (degrees)')584axes[0, 1].set_title('Faraday Rotation (TGG, 1 cm)')585axes[0, 1].grid(True, alpha=0.3)586587# Plot 3: Optical isolator588# Forward: polarizer -> Faraday rotator (45 deg) -> analyzer (45 deg)589# Backward: analyzer -> Faraday rotator (45 deg) -> polarizer590591rotation_45 = np.pi/4592FR = rotator(rotation_45)593P0 = linear_polarizer(0)594P45 = linear_polarizer(np.pi/4)595596# Forward pass597input_forward = np.array([1, 0])598forward_1 = P0 @ input_forward599forward_2 = FR @ forward_1600forward_out = P45 @ forward_2601I_forward = np.abs(forward_out[0])**2 + np.abs(forward_out[1])**2602603# Backward pass (Faraday effect is non-reciprocal)604input_backward = np.array([np.cos(np.pi/4), np.sin(np.pi/4)])605backward_1 = FR @ input_backward # Same rotation direction606backward_out = P0 @ backward_1607I_backward = np.abs(backward_out[0])**2 + np.abs(backward_out[1])**2608609bar_positions = [0, 1]610bar_heights = [I_forward, I_backward]611bar_labels = ['Forward', 'Backward']612bar_colors = ['green', 'red']613614axes[1, 0].bar(bar_positions, bar_heights, color=bar_colors, alpha=0.7)615axes[1, 0].set_xticks(bar_positions)616axes[1, 0].set_xticklabels(bar_labels)617axes[1, 0].set_ylabel('Transmitted Intensity')618axes[1, 0].set_title('Optical Isolator Performance')619axes[1, 0].grid(True, alpha=0.3, axis='y')620621# Add isolation ratio text622isolation = 10 * np.log10(I_forward / I_backward) if I_backward > 0 else np.inf623624# Plot 4: Polarization rotation in chiral medium625# Different for left and right circular polarizations626input_lcp = circular_pol('left')627input_rcp = circular_pol('right')628629rotation_angles = np.linspace(0, np.pi, 100)630631# Track phase difference between LCP and RCP632lcp_phase = []633rcp_phase = []634635for rot in rotation_angles:636R = rotator(rot)637out_lcp = R @ input_lcp638out_rcp = R @ input_rcp639640# Phase is argument of complex amplitude641lcp_phase.append(np.angle(out_lcp[0]))642rcp_phase.append(np.angle(out_rcp[0]))643644axes[1, 1].plot(np.rad2deg(rotation_angles), np.rad2deg(lcp_phase), 'b-', linewidth=2, label='LCP')645axes[1, 1].plot(np.rad2deg(rotation_angles), np.rad2deg(rcp_phase), 'r-', linewidth=2, label='RCP')646axes[1, 1].set_xlabel('Rotator angle (degrees)')647axes[1, 1].set_ylabel('Output phase (degrees)')648axes[1, 1].set_title('Circular Polarization Through Rotator')649axes[1, 1].legend()650axes[1, 1].grid(True, alpha=0.3)651652plt.tight_layout()653save_plot('optical_activity.pdf', 'Optical activity and Faraday effect: rotation, isolators, and circular birefringence.')654\end{pycode}655656\section{Birefringence and Stress Analysis}657\begin{pycode}658# Photoelastic stress analysis659fig, axes = plt.subplots(2, 2, figsize=(10, 8))660661# Plot 1: Birefringent material between crossed polarizers662# Intensity depends on retardance and orientation663retardances = np.linspace(0, 4*np.pi, 100)664orientations = [0, np.pi/8, np.pi/4, 3*np.pi/8]665colors_orient = ['blue', 'green', 'orange', 'red']666667input_h = linear_pol(0)668analyzer_v = linear_polarizer(np.pi/2)669670for theta, color in zip(orientations, colors_orient):671intensities = []672for delta in retardances:673WP = wave_plate(delta, theta)674output = analyzer_v @ WP @ input_h675I = np.abs(output[0])**2 + np.abs(output[1])**2676intensities.append(I)677678axes[0, 0].plot(retardances/np.pi, intensities, color=color, linewidth=2,679label=f'$\\theta = {np.rad2deg(theta):.0f}^\\circ$')680681axes[0, 0].set_xlabel('Retardance ($\\pi$)')682axes[0, 0].set_ylabel('Transmitted Intensity')683axes[0, 0].set_title('Birefringent Material Between Crossed Polarizers')684axes[0, 0].legend(fontsize=8)685axes[0, 0].grid(True, alpha=0.3)686687# Plot 2: Simulated photoelastic pattern688x = np.linspace(-5, 5, 200)689y = np.linspace(-5, 5, 200)690X, Y = np.meshgrid(x, y)691692# Simulated stress field (disk under diametral compression)693sigma_1 = 1 / (X**2 + Y**2 + 0.5) # Radial pattern694sigma_2 = -0.5 * sigma_1695stress_diff = sigma_1 - sigma_2696697# Retardance proportional to stress difference698C = 1 # Stress-optic coefficient699d = 1 # Thickness700delta_stress = 2 * np.pi * C * d * stress_diff701702# Fast axis along principal stress703theta_stress = 0.5 * np.arctan2(Y, X)704705# Intensity between crossed polarizers706I_photo = np.sin(2 * theta_stress)**2 * np.sin(delta_stress/2)**2707708im = axes[0, 1].pcolormesh(X, Y, I_photo, cmap='hot', shading='auto')709axes[0, 1].set_xlabel('$x$')710axes[0, 1].set_ylabel('$y$')711axes[0, 1].set_title('Photoelastic Stress Pattern')712axes[0, 1].set_aspect('equal')713714# Plot 3: Isochromatic fringes (constant retardance)715# Represent different orders716fringe_orders = np.arange(0, 5)717for m in fringe_orders:718# Find contour where delta = 2*pi*m719contour_level = m720axes[1, 0].contour(X, Y, delta_stress/(2*np.pi), levels=[m], colors='k', linewidths=1)721722axes[1, 0].set_xlabel('$x$')723axes[1, 0].set_ylabel('$y$')724axes[1, 0].set_title('Isochromatic Fringes')725axes[1, 0].set_aspect('equal')726727# Plot 4: Liquid crystal retardance728# Voltage-controlled birefringence729voltages = np.linspace(0, 10, 100) # V730731# Simplified model: retardance decreases with voltage732V_threshold = 1 # Threshold voltage733delta_0 = 2 * np.pi # Maximum retardance734delta_lc = delta_0 * np.exp(-((voltages - V_threshold)/3)**2)735delta_lc[voltages < V_threshold] = delta_0736737# Transmission between crossed polarizers at 45 degrees738T_lc = np.sin(delta_lc/2)**2739740axes[1, 1].plot(voltages, T_lc, 'b-', linewidth=2)741axes[1, 1].set_xlabel('Applied Voltage (V)')742axes[1, 1].set_ylabel('Normalized Transmission')743axes[1, 1].set_title('Liquid Crystal Cell Response')744axes[1, 1].grid(True, alpha=0.3)745746plt.tight_layout()747save_plot('birefringence.pdf', 'Birefringence applications: photoelasticity, isochromatics, and LC response.')748\end{pycode}749750\section{Results Summary}751\begin{pycode}752# Generate results table753print(r'\begin{table}[htbp]')754print(r'\centering')755print(r'\caption{Summary of Polarization Parameters}')756print(r'\begin{tabular}{lll}')757print(r'\toprule')758print(r'Configuration & Parameter & Result \\')759print(r'\midrule')760print(r"Malus's Law & Maximum transmission & 1.0 \\")761print(r"Crossed polarizers & Transmission & 0 \\")762print(f"Three polarizers (0$^\\circ$, 45$^\\circ$, 90$^\\circ$) & Transmission & {0.25:.2f} \\\\")763print(r"QWP at 45$^\circ$ & Linear $\rightarrow$ circular & Yes \\")764print(r"HWP at $\theta$ & Rotation & $2\theta$ \\")765print(r'\midrule')766print(f"Optical isolator & Forward transmission & {I_forward:.2f} \\\\")767print(f"Optical isolator & Backward transmission & {I_backward:.3f} \\\\")768print(f"Sucrose specific rotation & $[\\alpha]_D$ & {specific_rotation:.1f}$^\\circ$/dm \\\\")769print(f"TGG Verdet constant & $V$ & {verdet_constant:.1f} rad/(T$\\cdot$m) \\\\")770print(r'\bottomrule')771print(r'\end{tabular}')772print(r'\end{table}')773\end{pycode}774775\section{Statistical Summary}776\begin{itemize}777\item \textbf{Malus's Law}: $I = I_0\cos^2\theta$ verified778\item \textbf{Quarter-wave plate}: Converts linear to circular polarization at 45$^\circ$779\item \textbf{Half-wave plate}: Rotates polarization by $2\theta$780\item \textbf{Stokes parameters}: $S_0^2 = S_1^2 + S_2^2 + S_3^2$ for fully polarized light781\item \textbf{Three-polarizer transmission}: 25\% maximum at 45$^\circ$ intermediate782\item \textbf{N-polarizer limit}: Approaches 100\% as $N \to \infty$783\item \textbf{Optical isolator}: Non-reciprocal due to Faraday effect784\end{itemize}785786\section{Conclusion}787Jones and Mueller calculus provide complete descriptions of polarization transformations for coherent and partially coherent light. Circular polarization requires a phase difference of $\pi/2$ between orthogonal components. Wave plates are essential for polarization control in optical systems, from LCD displays to optical communications. The Faraday effect enables non-reciprocal devices like optical isolators, critical for protecting laser sources. Photoelasticity exploits stress-induced birefringence for mechanical stress analysis. Understanding polarization is fundamental to many optical technologies including polarimetry, ellipsometry, and quantum key distribution.788789\end{document}790791792