Path: blob/main/latex-templates/templates/optics/fiber_modes.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: Optical Fiber Mode Analysis}10\author{Computational Science Templates}11\date{\today}1213\begin{document}14\maketitle1516\section{Introduction}17Optical fibers guide light through total internal reflection. The number and characteristics of guided modes depend on the fiber parameters including core radius, refractive indices, and wavelength. This analysis examines single-mode and multi-mode fiber behavior, mode field characteristics, dispersion properties, and bend loss effects.1819\section{Mathematical Framework}2021\subsection{Normalized Frequency (V-number)}22The V-number determines the number of modes:23\begin{equation}24V = \frac{2\pi a}{\lambda}\sqrt{n_1^2 - n_2^2} = \frac{2\pi a}{\lambda} \cdot NA25\end{equation}2627For step-index fiber, the number of modes is approximately:28\begin{equation}29N \approx \frac{V^2}{2}30\end{equation}3132Single-mode condition: $V < 2.405$ (LP$_{01}$ mode only)3334\subsection{LP Mode Characteristic Equation}35The characteristic equation for LP$_{lm}$ modes:36\begin{equation}37u \frac{J_{l\pm 1}(u)}{J_l(u)} = \pm w \frac{K_{l\pm 1}(w)}{K_l(w)}38\end{equation}3940where $u = a\sqrt{k_0^2 n_1^2 - \beta^2}$, $w = a\sqrt{\beta^2 - k_0^2 n_2^2}$, and $u^2 + w^2 = V^2$.4142\subsection{Mode Field Diameter}43The Marcuse approximation for mode field diameter:44\begin{equation}45\frac{w}{a} = 0.65 + \frac{1.619}{V^{3/2}} + \frac{2.879}{V^6}46\end{equation}4748\subsection{Dispersion}49Total dispersion in single-mode fiber:50\begin{equation}51D_{total} = D_M + D_W = -\frac{\lambda}{c}\frac{d^2 n}{d\lambda^2}52\end{equation}5354\section{Environment Setup}55\begin{pycode}56import numpy as np57from scipy.special import jv, kv, jn_zeros58from scipy.optimize import brentq59import matplotlib.pyplot as plt60plt.rc('text', usetex=True)61plt.rc('font', family='serif')6263def save_plot(filename, caption=""):64plt.savefig(filename, bbox_inches='tight', dpi=150)65print(r'\begin{figure}[htbp]')66print(r'\centering')67print(r'\includegraphics[width=0.95\textwidth]{' + filename + '}')68if caption:69print(r'\caption{' + caption + '}')70print(r'\end{figure}')71plt.close()72\end{pycode}7374\section{V-Number and Mode Count Analysis}75\begin{pycode}76# Fiber parameters77a = 4e-6 # Core radius (m) for single-mode78a_mm = 25e-6 # Core radius (m) for multi-mode79n1 = 1.48 # Core refractive index80n2 = 1.46 # Cladding refractive index81NA = np.sqrt(n1**2 - n2**2)82delta = (n1 - n2) / n1 # Relative index difference8384# Wavelength range85wavelengths = np.linspace(800e-9, 1700e-9, 200)8687# V-number calculation88def V_number(a, wavelength, NA):89return 2 * np.pi * a * NA / wavelength9091# Calculate V for both fibers92V_sm = V_number(a, wavelengths, NA)93V_mm = V_number(a_mm, wavelengths, NA)9495# Number of modes (approximate)96N_modes_mm = V_mm**2 / 29798# Mode field diameter (Marcuse approximation)99def MFD(a, V):100return 2 * a * (0.65 + 1.619/V**1.5 + 2.879/V**6)101102MFD_sm = MFD(a, V_sm)103104# Cutoff wavelength for single-mode operation105lambda_cutoff = 2 * np.pi * a * NA / 2.405106107# Create plots108fig, axes = plt.subplots(2, 2, figsize=(10, 8))109110# Plot 1: V-number vs wavelength111axes[0, 0].plot(wavelengths*1e9, V_sm, 'b-', linewidth=2, label=f'Single-mode (a={a*1e6:.0f}$\\mu$m)')112axes[0, 0].plot(wavelengths*1e9, V_mm/10, 'r-', linewidth=2, label=f'Multi-mode (a={a_mm*1e6:.0f}$\\mu$m, /10)')113axes[0, 0].axhline(y=2.405, color='gray', linestyle='--', alpha=0.7, label='SM cutoff')114axes[0, 0].set_xlabel('Wavelength (nm)')115axes[0, 0].set_ylabel('V-number')116axes[0, 0].set_title('Normalized Frequency')117axes[0, 0].legend(fontsize=8)118axes[0, 0].grid(True, alpha=0.3)119120# Plot 2: Number of modes121axes[0, 1].semilogy(wavelengths*1e9, N_modes_mm, 'r-', linewidth=2)122axes[0, 1].set_xlabel('Wavelength (nm)')123axes[0, 1].set_ylabel('Number of Modes')124axes[0, 1].set_title('Multi-mode Fiber Mode Count')125axes[0, 1].grid(True, alpha=0.3, which='both')126127# Plot 3: Mode field diameter128axes[1, 0].plot(wavelengths*1e9, MFD_sm*1e6, 'g-', linewidth=2)129axes[1, 0].axhline(y=2*a*1e6, color='gray', linestyle='--', alpha=0.7, label='Core diameter')130axes[1, 0].set_xlabel('Wavelength (nm)')131axes[1, 0].set_ylabel('MFD ($\\mu$m)')132axes[1, 0].set_title('Mode Field Diameter')133axes[1, 0].legend()134axes[1, 0].grid(True, alpha=0.3)135136# Plot 4: NA vs wavelength (constant for step-index)137wavelength_array = np.linspace(800, 1700, 100)138NA_array = NA * np.ones_like(wavelength_array)139acceptance_angle = np.arcsin(NA) * 180 / np.pi140axes[1, 1].plot(wavelength_array, NA_array, 'purple', linewidth=2, label=f'NA = {NA:.3f}')141axes[1, 1].axhline(y=NA, color='gray', linestyle='--', alpha=0.5)142axes[1, 1].set_xlabel('Wavelength (nm)')143axes[1, 1].set_ylabel('Numerical Aperture')144axes[1, 1].set_title(f'NA and Acceptance Angle ($\\theta_a = {acceptance_angle:.1f}^\\circ$)')145axes[1, 1].legend()146axes[1, 1].grid(True, alpha=0.3)147axes[1, 1].set_ylim([0, 0.4])148149plt.tight_layout()150save_plot('fiber_v_number.pdf', 'V-number, mode count, and MFD analysis for step-index fibers.')151\end{pycode}152153\section{LP Mode Profiles and Characteristic Equation}154\begin{pycode}155# Solve LP mode characteristic equation156def lp_characteristic(u, V, l):157"""Characteristic equation for LP modes."""158if u <= 0 or u >= V:159return np.inf160w = np.sqrt(V**2 - u**2)161if w <= 0:162return np.inf163164# Handle Bessel function edge cases165try:166if l == 0:167lhs = u * jv(1, u) / jv(0, u)168else:169lhs = u * jv(l-1, u) / jv(l, u) - l170rhs = -w * kv(l-1, w) / kv(l, w) - l171return lhs - rhs172except:173return np.inf174175# Find modes for V = 5176V_test = 5.0177modes_found = []178179for l in range(10): # Azimuthal mode number180# Find zeros of Bessel function to bracket solutions181zeros = jn_zeros(l, 10)182u_brackets = [0.01] + list(zeros[zeros < V_test])183184m = 1 # Radial mode number185for i in range(len(u_brackets) - 1):186try:187u_low, u_high = u_brackets[i], u_brackets[i+1]188if u_high > V_test - 0.01:189u_high = V_test - 0.01190191# Check for sign change192f_low = lp_characteristic(u_low + 0.01, V_test, l)193f_high = lp_characteristic(u_high - 0.01, V_test, l)194195if f_low * f_high < 0:196u_sol = brentq(lp_characteristic, u_low + 0.01, u_high - 0.01,197args=(V_test, l))198w_sol = np.sqrt(V_test**2 - u_sol**2)199beta_norm = w_sol / V_test200modes_found.append((l, m, u_sol, w_sol, beta_norm))201m += 1202except:203pass204205# Generate mode profiles206r = np.linspace(0, 3*a, 300)207rho = r / a208209fig, axes = plt.subplots(2, 2, figsize=(10, 8))210211# Plot selected LP mode intensity profiles212mode_colors = ['blue', 'red', 'green', 'orange', 'purple']213mode_names = ['LP$_{01}$', 'LP$_{11}$', 'LP$_{21}$', 'LP$_{02}$', 'LP$_{31}$']214215# Gaussian approximation for LP01216w_mode = a * (0.65 + 1.619/V_test**1.5 + 2.879/V_test**6)217E_01 = np.exp(-(r/w_mode)**2)218219# Higher order mode approximations220E_11 = (r/a) * np.exp(-(r/(1.2*w_mode))**2)221E_21 = (r/a)**2 * np.exp(-(r/(1.4*w_mode))**2)222E_02 = (1 - 2*(r/w_mode)**2) * np.exp(-(r/w_mode)**2)223E_31 = (r/a)**3 * np.exp(-(r/(1.6*w_mode))**2)224225mode_profiles = [E_01, E_11, E_21, E_02, E_31]226227# Plot 1: Intensity profiles228for i, (E, name, color) in enumerate(zip(mode_profiles[:4], mode_names[:4], mode_colors[:4])):229I = np.abs(E)**2230I = I / np.max(I)231axes[0, 0].plot(r*1e6, I, color=color, linewidth=2, label=name)232233axes[0, 0].axvline(x=a*1e6, color='gray', linestyle='--', alpha=0.7, label='Core edge')234axes[0, 0].set_xlabel('Radius ($\\mu$m)')235axes[0, 0].set_ylabel('Intensity (normalized)')236axes[0, 0].set_title(f'LP Mode Intensity Profiles (V = {V_test})')237axes[0, 0].legend(fontsize=8)238axes[0, 0].grid(True, alpha=0.3)239240# Plot 2: 2D mode pattern for LP11241theta = np.linspace(0, 2*np.pi, 100)242R, THETA = np.meshgrid(r[:100], theta)243X = R * np.cos(THETA)244Y = R * np.sin(THETA)245246# LP11 has cos(theta) angular dependence247E_11_2d = (R/a) * np.exp(-(R/(1.2*w_mode))**2) * np.cos(THETA)248I_11_2d = np.abs(E_11_2d)**2249250im = axes[0, 1].pcolormesh(X*1e6, Y*1e6, I_11_2d, cmap='hot', shading='auto')251circle = plt.Circle((0, 0), a*1e6, fill=False, color='white', linestyle='--')252axes[0, 1].add_patch(circle)253axes[0, 1].set_xlabel('x ($\\mu$m)')254axes[0, 1].set_ylabel('y ($\\mu$m)')255axes[0, 1].set_title('LP$_{11}$ Mode 2D Pattern')256axes[0, 1].set_aspect('equal')257258# Plot 3: b-V diagram (normalized propagation constant)259V_range = np.linspace(0.5, 8, 200)260b_values = {}261262# Approximate b-V curves for LP modes263# b = (beta/k0 - n2)/(n1 - n2) = (1 - (u/V)^2)264for V in V_range:265for l in range(4):266# Simple approximation: cutoff at V = 2.405 * sqrt(l+1)267V_cutoff = 2.405 * np.sqrt(l + 0.5) if l > 0 else 0268if V > V_cutoff:269# Approximate b value270if l == 0:271b = (1.1428 - 0.996/V)**2 if V > 1 else 0.1 * V**2272else:273x = (V - V_cutoff) / V_cutoff if V_cutoff > 0 else V274b = x**2 / (1 + x**2)275276if l not in b_values:277b_values[l] = {'V': [], 'b': []}278b_values[l]['V'].append(V)279b_values[l]['b'].append(b)280281for l, data in b_values.items():282axes[1, 0].plot(data['V'], data['b'], linewidth=2, label=f'LP$_{{{l}m}}$')283284axes[1, 0].axvline(x=2.405, color='gray', linestyle='--', alpha=0.5, label='SM cutoff')285axes[1, 0].set_xlabel('V-number')286axes[1, 0].set_ylabel('Normalized propagation constant $b$')287axes[1, 0].set_title('b-V Diagram')288axes[1, 0].legend(fontsize=8)289axes[1, 0].grid(True, alpha=0.3)290axes[1, 0].set_xlim([0, 8])291axes[1, 0].set_ylim([0, 1])292293# Plot 4: Mode confinement factor294V_conf = np.linspace(1, 6, 100)295# Confinement factor: fraction of power in core296Gamma = 1 - np.exp(-2 * (V_conf/2.405)**2)297298axes[1, 1].plot(V_conf, Gamma * 100, 'b-', linewidth=2)299axes[1, 1].axhline(y=86.5, color='gray', linestyle='--', alpha=0.5, label='86.5\\% (Gaussian)')300axes[1, 1].set_xlabel('V-number')301axes[1, 1].set_ylabel('Confinement factor (\\%)')302axes[1, 1].set_title('Power Confinement in Core')303axes[1, 1].legend()304axes[1, 1].grid(True, alpha=0.3)305306plt.tight_layout()307save_plot('fiber_mode_profiles.pdf', 'LP mode profiles, b-V diagram, and confinement analysis.')308\end{pycode}309310\section{Dispersion Analysis}311\begin{pycode}312# Material dispersion (Sellmeier equation for silica)313def sellmeier_n(wavelength):314"""Refractive index of fused silica using Sellmeier equation."""315lam = wavelength * 1e6 # Convert to microns316n_sq = 1 + 0.6961663 * lam**2 / (lam**2 - 0.0684043**2)317n_sq += 0.4079426 * lam**2 / (lam**2 - 0.1162414**2)318n_sq += 0.8974794 * lam**2 / (lam**2 - 9.896161**2)319return np.sqrt(n_sq)320321def material_dispersion(wavelength):322"""Material dispersion D_M in ps/(nm*km)."""323lam = wavelength * 1e6 # microns324c = 3e8 # m/s325326# Numerical second derivative327dlam = 1e-9328n_plus = sellmeier_n(wavelength + dlam)329n_minus = sellmeier_n(wavelength - dlam)330n_center = sellmeier_n(wavelength)331332d2n_dlam2 = (n_plus - 2*n_center + n_minus) / (dlam**2)333334# D_M = -(lambda/c) * d2n/dlambda2335D_M = -lam * 1e-6 / c * d2n_dlam2 * 1e6 # Convert to ps/(nm*km)336return D_M337338# Waveguide dispersion (approximate)339def waveguide_dispersion(wavelength, a, n1, n2):340"""Waveguide dispersion D_W in ps/(nm*km)."""341V = V_number(a, wavelength, np.sqrt(n1**2 - n2**2))342343# Approximate second derivative of Vb344# D_W = -(n2 * delta / c * lambda) * V * d2(Vb)/dV2345delta = (n1 - n2) / n1346c = 3e8347348# Simplified approximation349d2Vb_dV2 = 0.08 + 0.549 * (2.834 - V)**2350D_W = n2 * delta / c * wavelength * V * d2Vb_dV2 * 1e6351352return D_W353354# Wavelength range for dispersion355wavelengths_disp = np.linspace(1.0e-6, 1.7e-6, 200)356357# Calculate dispersions358D_M = np.array([material_dispersion(lam) for lam in wavelengths_disp])359D_W = np.array([waveguide_dispersion(lam, a, n1, n2) for lam in wavelengths_disp])360D_total = D_M + D_W361362# Find zero-dispersion wavelength363idx_zero = np.argmin(np.abs(D_total))364lambda_zero = wavelengths_disp[idx_zero]365366fig, axes = plt.subplots(2, 2, figsize=(10, 8))367368# Plot 1: Material and waveguide dispersion369axes[0, 0].plot(wavelengths_disp*1e9, D_M, 'b-', linewidth=2, label='Material $D_M$')370axes[0, 0].plot(wavelengths_disp*1e9, D_W, 'r--', linewidth=2, label='Waveguide $D_W$')371axes[0, 0].plot(wavelengths_disp*1e9, D_total, 'k-', linewidth=2.5, label='Total $D$')372axes[0, 0].axhline(y=0, color='gray', linestyle='-', alpha=0.5)373axes[0, 0].axvline(x=lambda_zero*1e9, color='green', linestyle='--', alpha=0.7,374label=f'$\\lambda_0 = {lambda_zero*1e9:.0f}$ nm')375axes[0, 0].set_xlabel('Wavelength (nm)')376axes[0, 0].set_ylabel('Dispersion (ps/(nm$\\cdot$km))')377axes[0, 0].set_title('Chromatic Dispersion')378axes[0, 0].legend(fontsize=8)379axes[0, 0].grid(True, alpha=0.3)380381# Plot 2: Pulse broadening vs fiber length382fiber_lengths = np.array([1, 10, 50, 100]) # km383delta_lambda = 0.1 # nm (source linewidth)384D_at_1550 = D_total[np.argmin(np.abs(wavelengths_disp - 1550e-9))]385386pulse_broadening = np.abs(D_at_1550) * delta_lambda * fiber_lengths387388axes[0, 1].bar(range(len(fiber_lengths)), pulse_broadening, color='steelblue', alpha=0.7)389axes[0, 1].set_xticks(range(len(fiber_lengths)))390axes[0, 1].set_xticklabels([f'{L} km' for L in fiber_lengths])391axes[0, 1].set_ylabel('Pulse broadening (ps)')392axes[0, 1].set_title(f'Dispersion at 1550 nm ($\\Delta\\lambda = {delta_lambda}$ nm)')393axes[0, 1].grid(True, alpha=0.3, axis='y')394395# Plot 3: Refractive index vs wavelength396n_silica = np.array([sellmeier_n(lam) for lam in wavelengths_disp])397dn_dlambda = np.gradient(n_silica, wavelengths_disp)398399ax3 = axes[1, 0]400ax3.plot(wavelengths_disp*1e9, n_silica, 'b-', linewidth=2)401ax3.set_xlabel('Wavelength (nm)')402ax3.set_ylabel('Refractive index $n$', color='b')403ax3.tick_params(axis='y', labelcolor='b')404ax3.set_title('Silica Refractive Index (Sellmeier)')405ax3.grid(True, alpha=0.3)406407ax3b = ax3.twinx()408ax3b.plot(wavelengths_disp*1e9, dn_dlambda*1e9, 'r--', linewidth=2)409ax3b.set_ylabel('$dn/d\\lambda$ (nm$^{-1}$)', color='r')410ax3b.tick_params(axis='y', labelcolor='r')411412# Plot 4: Group velocity dispersion parameter beta2413c = 3e8414# beta_2 = D * lambda^2 / (2*pi*c)415beta_2 = D_total * (wavelengths_disp * 1e9)**2 / (2 * np.pi * c) * 1e-3 # ps^2/km416417axes[1, 1].plot(wavelengths_disp*1e9, beta_2, 'purple', linewidth=2)418axes[1, 1].axhline(y=0, color='gray', linestyle='-', alpha=0.5)419axes[1, 1].set_xlabel('Wavelength (nm)')420axes[1, 1].set_ylabel('$\\beta_2$ (ps$^2$/km)')421axes[1, 1].set_title('Group Velocity Dispersion')422axes[1, 1].grid(True, alpha=0.3)423424plt.tight_layout()425save_plot('fiber_dispersion.pdf', 'Chromatic dispersion analysis and pulse broadening effects.')426\end{pycode}427428\section{Bend Loss and Attenuation}429\begin{pycode}430# Bend loss calculation431def bend_loss_coefficient(wavelength, a, n1, n2, R_bend):432"""433Calculate bend loss coefficient (dB/turn) for single-mode fiber.434Uses Marcuse formula.435"""436V = V_number(a, wavelength, np.sqrt(n1**2 - n2**2))437w_mode = a * (0.65 + 1.619/V**1.5 + 2.879/V**6)438439# Normalized parameters440delta = (n1 - n2) / n1441k0 = 2 * np.pi / wavelength442443# Effective index approximation444n_eff = n1 * (1 - delta * (1.1428 - 0.996/V)**2)445446# Bend loss coefficient (simplified)447gamma = np.sqrt(k0**2 * (n_eff**2 - n2**2))448449# Marcuse formula (approximation)450alpha_bend = np.sqrt(np.pi / (2 * gamma * R_bend)) * np.exp(-4 * delta * gamma**3 * R_bend**2 / (3 * k0**2 * n_eff**2))451452# Convert to dB per turn453loss_per_turn = 4.343 * 2 * np.pi * R_bend * alpha_bend454455return loss_per_turn456457# Bend radii range458R_bends = np.linspace(5e-3, 50e-3, 100) # 5 mm to 50 mm459460# Calculate bend loss at different wavelengths461wavelengths_bend = [1310e-9, 1550e-9, 1625e-9]462colors_bend = ['blue', 'green', 'red']463464fig, axes = plt.subplots(2, 2, figsize=(10, 8))465466# Plot 1: Bend loss vs bend radius467for lam, color in zip(wavelengths_bend, colors_bend):468loss = []469for R in R_bends:470try:471l = bend_loss_coefficient(lam, a, n1, n2, R)472loss.append(min(l, 100)) # Cap at 100 dB473except:474loss.append(100)475axes[0, 0].semilogy(R_bends*1e3, loss, color=color, linewidth=2,476label=f'$\\lambda = {lam*1e9:.0f}$ nm')477478axes[0, 0].set_xlabel('Bend radius (mm)')479axes[0, 0].set_ylabel('Bend loss (dB/turn)')480axes[0, 0].set_title('Bend Loss vs Radius')481axes[0, 0].legend()482axes[0, 0].grid(True, alpha=0.3, which='both')483axes[0, 0].set_ylim([1e-6, 100])484485# Plot 2: Fiber attenuation spectrum486wavelengths_atten = np.linspace(800e-9, 1700e-9, 200)487488# Typical silica fiber attenuation (empirical model)489def fiber_attenuation(wavelength):490"""Attenuation in dB/km for standard silica fiber."""491lam = wavelength * 1e6 # microns492493# Rayleigh scattering494alpha_R = 0.75 / lam**4495496# OH absorption peak at 1383 nm497alpha_OH = 0.5 * np.exp(-((lam - 1.383)**2) / (0.02)**2)498499# IR absorption500alpha_IR = 0.01 * np.exp(lam - 1.5)501502return alpha_R + alpha_OH + alpha_IR503504attenuation = np.array([fiber_attenuation(lam) for lam in wavelengths_atten])505506axes[0, 1].plot(wavelengths_atten*1e9, attenuation, 'b-', linewidth=2)507axes[0, 1].axvline(x=1310, color='green', linestyle='--', alpha=0.7, label='O-band')508axes[0, 1].axvline(x=1550, color='red', linestyle='--', alpha=0.7, label='C-band')509axes[0, 1].set_xlabel('Wavelength (nm)')510axes[0, 1].set_ylabel('Attenuation (dB/km)')511axes[0, 1].set_title('Fiber Attenuation Spectrum')512axes[0, 1].legend()513axes[0, 1].grid(True, alpha=0.3)514axes[0, 1].set_ylim([0, 3])515516# Plot 3: Power budget calculation517link_length = np.linspace(0, 100, 100) # km518P_launch = 0 # dBm519alpha_1310 = fiber_attenuation(1310e-9)520alpha_1550 = fiber_attenuation(1550e-9)521522P_1310 = P_launch - alpha_1310 * link_length523P_1550 = P_launch - alpha_1550 * link_length524525axes[1, 0].plot(link_length, P_1310, 'g-', linewidth=2, label=f'1310 nm ($\\alpha = {alpha_1310:.2f}$ dB/km)')526axes[1, 0].plot(link_length, P_1550, 'r-', linewidth=2, label=f'1550 nm ($\\alpha = {alpha_1550:.2f}$ dB/km)')527axes[1, 0].axhline(y=-30, color='gray', linestyle='--', alpha=0.7, label='Receiver sensitivity')528axes[1, 0].set_xlabel('Link length (km)')529axes[1, 0].set_ylabel('Received power (dBm)')530axes[1, 0].set_title('Optical Power Budget')531axes[1, 0].legend(fontsize=8)532axes[1, 0].grid(True, alpha=0.3)533534# Plot 4: Splice and connector loss budget535components = ['Launch', 'Connector', 'Splice 1', '10 km fiber', 'Splice 2', 'Connector', 'Received']536loss_values = [0, -0.5, -0.1, -2.0, -0.1, -0.5, 0]537cumulative_power = np.cumsum([P_launch] + loss_values)538539axes[1, 1].bar(range(len(components)), cumulative_power[:-1], color='steelblue', alpha=0.7)540axes[1, 1].step(range(len(components)), cumulative_power[:-1], 'r-', linewidth=2, where='mid')541axes[1, 1].axhline(y=-30, color='gray', linestyle='--', alpha=0.7)542axes[1, 1].set_xticks(range(len(components)))543axes[1, 1].set_xticklabels(components, rotation=45, ha='right', fontsize=8)544axes[1, 1].set_ylabel('Power (dBm)')545axes[1, 1].set_title('Link Loss Budget')546axes[1, 1].grid(True, alpha=0.3, axis='y')547548plt.tight_layout()549save_plot('fiber_attenuation.pdf', 'Bend loss, attenuation spectrum, and link power budget.')550\end{pycode}551552\section{Results Summary}553\begin{pycode}554# Calculate values at key wavelengths555V_1310 = V_number(a, 1310e-9, NA)556V_1550 = V_number(a, 1550e-9, NA)557MFD_1310 = MFD(a, V_1310)558MFD_1550 = MFD(a, V_1550)559N_modes_mm_1550 = V_number(a_mm, 1550e-9, NA)**2 / 2560561# Dispersion at 1550 nm562D_1550 = D_total[np.argmin(np.abs(wavelengths_disp - 1550e-9))]563564# Attenuation565alpha_1310_val = fiber_attenuation(1310e-9)566alpha_1550_val = fiber_attenuation(1550e-9)567568# Generate results table569print(r'\begin{table}[htbp]')570print(r'\centering')571print(r'\caption{Summary of Optical Fiber Parameters}')572print(r'\begin{tabular}{llcc}')573print(r'\toprule')574print(r'Parameter & Symbol & 1310 nm & 1550 nm \\')575print(r'\midrule')576print(f'V-number (SM) & $V$ & {V_1310:.2f} & {V_1550:.2f} \\\\')577print(f'Mode field diameter & MFD & {MFD_1310*1e6:.1f} $\\mu$m & {MFD_1550*1e6:.1f} $\\mu$m \\\\')578print(f'Attenuation & $\\alpha$ & {alpha_1310_val:.2f} dB/km & {alpha_1550_val:.2f} dB/km \\\\')579print(f'Dispersion & $D$ & -- & {D_1550:.1f} ps/(nm$\\cdot$km) \\\\')580print(r'\midrule')581print(f'Numerical aperture & NA & \\multicolumn{{2}}{{c}}{{{NA:.3f}}} \\\\')582print(f'Cutoff wavelength & $\\lambda_c$ & \\multicolumn{{2}}{{c}}{{{lambda_cutoff*1e9:.0f} nm}} \\\\')583print(f'Zero-dispersion & $\\lambda_0$ & \\multicolumn{{2}}{{c}}{{{lambda_zero*1e9:.0f} nm}} \\\\')584print(f'MM fiber modes & $N$ & \\multicolumn{{2}}{{c}}{{$\\approx$ {N_modes_mm_1550:.0f}}} \\\\')585print(r'\bottomrule')586print(r'\end{tabular}')587print(r'\end{table}')588\end{pycode}589590\section{Statistical Summary}591\begin{itemize}592\item \textbf{Core refractive index}: $n_1 = $ \py{f"{n1:.2f}"}593\item \textbf{Cladding refractive index}: $n_2 = $ \py{f"{n2:.2f}"}594\item \textbf{Core radius (SM)}: $a = $ \py{f"{a*1e6:.0f}"} $\mu$m595\item \textbf{Core radius (MM)}: $a = $ \py{f"{a_mm*1e6:.0f}"} $\mu$m596\item \textbf{Relative index difference}: $\Delta = $ \py{f"{delta*100:.2f}"}\%597\item \textbf{Acceptance angle}: $\theta_a = $ \py{f"{np.arcsin(NA)*180/np.pi:.1f}"}$^\circ$598\item \textbf{Minimum attenuation at}: \py{f"{wavelengths_atten[np.argmin(attenuation)]*1e9:.0f}"} nm599\end{itemize}600601\section{Conclusion}602Single-mode fibers require $V < 2.405$, achieved through small core diameters around 8-10 $\mu$m. The mode field extends beyond the core into the cladding, with the MFD increasing with wavelength. Chromatic dispersion arises from both material and waveguide contributions, with a zero-dispersion wavelength around 1310 nm for standard fiber. Multi-mode fibers support many modes that travel different paths, causing modal dispersion. The 1550 nm C-band offers minimum attenuation (0.2 dB/km) and is preferred for long-haul telecommunications, while dispersion-shifted fibers move the zero-dispersion wavelength to 1550 nm for optimized performance.603604\end{document}605606607