Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ok-landscape
GitHub Repository: Ok-landscape/computational-pipeline
Path: blob/main/latex-templates/templates/optics/gaussian_beam.tex
51 views
unlisted
1
\documentclass[a4paper, 11pt]{article}
2
\usepackage[utf8]{inputenc}
3
\usepackage[T1]{fontenc}
4
\usepackage{amsmath, amssymb}
5
\usepackage{graphicx}
6
\usepackage{siunitx}
7
\usepackage{booktabs}
8
\usepackage[makestderr]{pythontex}
9
10
\title{Optics: Gaussian Beam Propagation}
11
\author{Computational Science Templates}
12
\date{\today}
13
14
\begin{document}
15
\maketitle
16
17
\section{Introduction}
18
Gaussian beams are fundamental to laser optics and optical communication. They represent the lowest-order transverse electromagnetic mode (TEM$_{00}$) of optical resonators. This analysis computes the propagation characteristics of a Gaussian beam, including beam waist, divergence, Rayleigh range, and focuses on practical applications like focusing and optical system design using ABCD matrix methods.
19
20
\section{Mathematical Framework}
21
22
\subsection{Electric Field and Intensity}
23
The Gaussian beam electric field amplitude:
24
\begin{equation}
25
E(r, z) = E_0 \frac{w_0}{w(z)} \exp\left(-\frac{r^2}{w(z)^2}\right) \exp\left(i\left(kz + k\frac{r^2}{2R(z)} - \psi(z)\right)\right)
26
\end{equation}
27
28
The intensity profile is:
29
\begin{equation}
30
I(r, z) = I_0 \left(\frac{w_0}{w(z)}\right)^2 \exp\left(-\frac{2r^2}{w(z)^2}\right)
31
\end{equation}
32
33
\subsection{Key Parameters}
34
\begin{align}
35
w(z) &= w_0\sqrt{1 + \left(\frac{z}{z_R}\right)^2} & \text{(beam width)} \\
36
z_R &= \frac{\pi w_0^2}{\lambda} & \text{(Rayleigh range)} \\
37
R(z) &= z\left[1 + \left(\frac{z_R}{z}\right)^2\right] & \text{(wavefront curvature)} \\
38
\psi(z) &= \arctan\left(\frac{z}{z_R}\right) & \text{(Gouy phase)}
39
\end{align}
40
41
\subsection{Beam Quality Factor}
42
The $M^2$ parameter characterizes beam quality:
43
\begin{equation}
44
M^2 = \frac{\pi w_0 \theta}{\lambda}
45
\end{equation}
46
where $\theta$ is the far-field divergence half-angle. For an ideal Gaussian beam, $M^2 = 1$.
47
48
\section{Environment Setup}
49
\begin{pycode}
50
import numpy as np
51
import matplotlib.pyplot as plt
52
plt.rc('text', usetex=True)
53
plt.rc('font', family='serif')
54
55
def save_plot(filename, caption=""):
56
plt.savefig(filename, bbox_inches='tight', dpi=150)
57
print(r'\begin{figure}[htbp]')
58
print(r'\centering')
59
print(r'\includegraphics[width=0.95\textwidth]{' + filename + '}')
60
if caption:
61
print(r'\caption{' + caption + '}')
62
print(r'\end{figure}')
63
plt.close()
64
\end{pycode}
65
66
\section{Basic Beam Propagation}
67
\begin{pycode}
68
# Beam parameters
69
wavelength = 1064e-9 # Nd:YAG (m)
70
w0 = 100e-6 # Beam waist (m)
71
72
# Rayleigh range
73
z_R = np.pi * w0**2 / wavelength
74
75
# Propagation functions
76
def beam_width(z, w0, z_R):
77
return w0 * np.sqrt(1 + (z / z_R)**2)
78
79
def radius_of_curvature(z, z_R):
80
z = np.where(z == 0, 1e-10, z)
81
return z * (1 + (z_R / z)**2)
82
83
def gouy_phase(z, z_R):
84
return np.arctan(z / z_R)
85
86
def intensity_profile(r, z, w0, z_R):
87
w = beam_width(z, w0, z_R)
88
return (w0 / w)**2 * np.exp(-2 * r**2 / w**2)
89
90
# z array
91
z = np.linspace(-5 * z_R, 5 * z_R, 500)
92
93
# Calculate beam parameters
94
w = beam_width(z, w0, z_R)
95
R = radius_of_curvature(z, z_R)
96
psi = gouy_phase(z, z_R)
97
98
# Divergence angle
99
theta_div = wavelength / (np.pi * w0)
100
101
# Beam profile at different z
102
z_positions = [0, z_R, 3*z_R]
103
r = np.linspace(-500e-6, 500e-6, 200)
104
105
# Create plots
106
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
107
108
# Plot 1: Beam envelope
109
z_mm = z * 1000
110
w_um = w * 1e6
111
axes[0, 0].fill_between(z_mm, -w_um, w_um, alpha=0.3, color='red')
112
axes[0, 0].plot(z_mm, w_um, 'r-', linewidth=2)
113
axes[0, 0].plot(z_mm, -w_um, 'r-', linewidth=2)
114
axes[0, 0].axvline(x=z_R*1000, color='blue', linestyle='--', alpha=0.5, label=f'$z_R = {z_R*1000:.1f}$ mm')
115
axes[0, 0].axvline(x=-z_R*1000, color='blue', linestyle='--', alpha=0.5)
116
axes[0, 0].set_xlabel('Propagation distance (mm)')
117
axes[0, 0].set_ylabel('Beam radius ($\\mu$m)')
118
axes[0, 0].set_title('Gaussian Beam Envelope')
119
axes[0, 0].legend()
120
axes[0, 0].grid(True, alpha=0.3)
121
122
# Plot 2: Intensity profiles at different z
123
colors = ['blue', 'green', 'red']
124
for z_pos, color in zip(z_positions, colors):
125
w_z = beam_width(z_pos, w0, z_R)
126
I = np.exp(-2 * r**2 / w_z**2)
127
label = f'$z = {z_pos/z_R:.0f} z_R$' if z_pos > 0 else '$z = 0$'
128
axes[0, 1].plot(r*1e6, I, color=color, linewidth=2, label=label)
129
130
axes[0, 1].set_xlabel('Radial position ($\\mu$m)')
131
axes[0, 1].set_ylabel('Intensity (normalized)')
132
axes[0, 1].set_title('Intensity Profiles')
133
axes[0, 1].legend()
134
axes[0, 1].grid(True, alpha=0.3)
135
136
# Plot 3: Radius of curvature
137
R_mm = R / 1000
138
axes[1, 0].plot(z_mm, R_mm, 'b-', linewidth=2)
139
axes[1, 0].axhline(y=0, color='gray', linestyle='-', alpha=0.3)
140
axes[1, 0].set_xlabel('Propagation distance (mm)')
141
axes[1, 0].set_ylabel('Radius of curvature (m)')
142
axes[1, 0].set_title('Wavefront Curvature')
143
axes[1, 0].set_ylim([-50, 50])
144
axes[1, 0].grid(True, alpha=0.3)
145
146
# Plot 4: Gouy phase
147
axes[1, 1].plot(z_mm, np.rad2deg(psi), 'purple', linewidth=2)
148
axes[1, 1].axhline(y=90, color='gray', linestyle='--', alpha=0.5)
149
axes[1, 1].axhline(y=-90, color='gray', linestyle='--', alpha=0.5)
150
axes[1, 1].set_xlabel('Propagation distance (mm)')
151
axes[1, 1].set_ylabel('Gouy phase (degrees)')
152
axes[1, 1].set_title('Gouy Phase Shift')
153
axes[1, 1].grid(True, alpha=0.3)
154
155
plt.tight_layout()
156
save_plot('gaussian_beam_basic.pdf', 'Basic Gaussian beam propagation: envelope, intensity profiles, wavefront curvature, and Gouy phase.')
157
158
# Calculate beam quality factor
159
M2 = 1.0 # Ideal Gaussian
160
depth_of_focus = 2 * z_R
161
\end{pycode}
162
163
\section{2D Beam Propagation Visualization}
164
\begin{pycode}
165
# Create 2D visualization of beam propagation
166
z_2d = np.linspace(-3*z_R, 3*z_R, 200)
167
r_2d = np.linspace(-3*w0, 3*w0, 100)
168
169
Z, R_mesh = np.meshgrid(z_2d, r_2d)
170
171
# Calculate intensity distribution
172
I_2d = np.zeros_like(Z)
173
for i, zv in enumerate(z_2d):
174
w_z = beam_width(zv, w0, z_R)
175
I_2d[:, i] = (w0/w_z)**2 * np.exp(-2 * r_2d**2 / w_z**2)
176
177
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
178
179
# Plot 1: 2D intensity distribution (side view)
180
im = axes[0, 0].pcolormesh(Z*1000, R_mesh*1e6, I_2d, cmap='hot', shading='auto')
181
axes[0, 0].plot(z_2d*1000, beam_width(z_2d, w0, z_R)*1e6, 'w--', linewidth=1.5, label='$w(z)$')
182
axes[0, 0].plot(z_2d*1000, -beam_width(z_2d, w0, z_R)*1e6, 'w--', linewidth=1.5)
183
axes[0, 0].set_xlabel('$z$ (mm)')
184
axes[0, 0].set_ylabel('$r$ ($\\mu$m)')
185
axes[0, 0].set_title('Beam Intensity Distribution')
186
plt.colorbar(im, ax=axes[0, 0], label='Intensity')
187
188
# Plot 2: Cross-section at waist
189
theta = np.linspace(0, 2*np.pi, 100)
190
r_cross = np.linspace(0, 3*w0, 100)
191
R_c, THETA = np.meshgrid(r_cross, theta)
192
X = R_c * np.cos(THETA)
193
Y = R_c * np.sin(THETA)
194
I_cross = np.exp(-2 * R_c**2 / w0**2)
195
196
im2 = axes[0, 1].pcolormesh(X*1e6, Y*1e6, I_cross, cmap='hot', shading='auto')
197
circle = plt.Circle((0, 0), w0*1e6, fill=False, color='white', linestyle='--', linewidth=1.5)
198
axes[0, 1].add_patch(circle)
199
axes[0, 1].set_xlabel('$x$ ($\\mu$m)')
200
axes[0, 1].set_ylabel('$y$ ($\\mu$m)')
201
axes[0, 1].set_title('Cross-section at Waist')
202
axes[0, 1].set_aspect('equal')
203
204
# Plot 3: Power through aperture
205
aperture_radii = np.linspace(0, 3*w0, 100)
206
power_fraction = 1 - np.exp(-2 * aperture_radii**2 / w0**2)
207
208
axes[1, 0].plot(aperture_radii/w0, power_fraction*100, 'b-', linewidth=2)
209
axes[1, 0].axhline(y=86.5, color='gray', linestyle='--', alpha=0.7, label='$r = w_0$ (86.5\\%)')
210
axes[1, 0].axhline(y=99, color='gray', linestyle=':', alpha=0.7, label='$r = 1.5w_0$ (99\\%)')
211
axes[1, 0].axvline(x=1, color='red', linestyle='--', alpha=0.5)
212
axes[1, 0].axvline(x=1.5, color='red', linestyle=':', alpha=0.5)
213
axes[1, 0].set_xlabel('Aperture radius ($r/w_0$)')
214
axes[1, 0].set_ylabel('Transmitted power (\\%)')
215
axes[1, 0].set_title('Power Through Circular Aperture')
216
axes[1, 0].legend(fontsize=8)
217
axes[1, 0].grid(True, alpha=0.3)
218
219
# Plot 4: Peak intensity vs z
220
z_peak = np.linspace(-5*z_R, 5*z_R, 200)
221
I_peak = (w0 / beam_width(z_peak, w0, z_R))**2
222
223
axes[1, 1].plot(z_peak/z_R, I_peak, 'g-', linewidth=2)
224
axes[1, 1].axhline(y=0.5, color='gray', linestyle='--', alpha=0.7, label='Half maximum')
225
axes[1, 1].axvline(x=1, color='red', linestyle='--', alpha=0.5)
226
axes[1, 1].axvline(x=-1, color='red', linestyle='--', alpha=0.5)
227
axes[1, 1].set_xlabel('$z/z_R$')
228
axes[1, 1].set_ylabel('Peak intensity (normalized)')
229
axes[1, 1].set_title('Axial Intensity')
230
axes[1, 1].legend()
231
axes[1, 1].grid(True, alpha=0.3)
232
233
plt.tight_layout()
234
save_plot('gaussian_beam_2d.pdf', '2D beam visualization: intensity distribution, cross-section, power transmission, and axial intensity.')
235
\end{pycode}
236
237
\section{Focusing with a Lens}
238
\begin{pycode}
239
# Gaussian beam focusing with a lens
240
# Using ABCD matrix formalism
241
242
def transform_gaussian_beam(q_in, ABCD):
243
"""Transform Gaussian beam complex parameter q through ABCD matrix."""
244
A, B, C, D = ABCD[0,0], ABCD[0,1], ABCD[1,0], ABCD[1,1]
245
q_out = (A * q_in + B) / (C * q_in + D)
246
return q_out
247
248
def q_to_params(q, wavelength):
249
"""Extract beam waist position and size from complex beam parameter."""
250
# 1/q = 1/R - i*lambda/(pi*w^2)
251
inv_q = 1 / q
252
R = 1 / np.real(inv_q) if np.real(inv_q) != 0 else np.inf
253
w = np.sqrt(-wavelength / (np.pi * np.imag(inv_q)))
254
return R, w
255
256
# Input beam parameters
257
w0_input = 1e-3 # 1 mm beam waist
258
z_R_input = np.pi * w0_input**2 / wavelength
259
260
# Lens parameters
261
f = 100e-3 # 100 mm focal length
262
d1 = 200e-3 # Distance from waist to lens
263
d2_values = np.linspace(50e-3, 200e-3, 100)
264
265
# Calculate focused spot sizes
266
focused_waists = []
267
waist_positions = []
268
269
for d2 in d2_values:
270
# ABCD matrices
271
# Free propagation d1
272
M1 = np.array([[1, d1], [0, 1]])
273
# Thin lens
274
M_lens = np.array([[1, 0], [-1/f, 1]])
275
# Free propagation d2
276
M2 = np.array([[1, d2], [0, 1]])
277
278
# Total system
279
M_total = M2 @ M_lens @ M1
280
281
# Input complex beam parameter at waist
282
q_in = 1j * z_R_input
283
284
# Transform
285
q_out = transform_gaussian_beam(q_in, M_total)
286
287
# Extract parameters
288
R_out, w_out = q_to_params(q_out, wavelength)
289
focused_waists.append(w_out)
290
291
# Find waist position (where R -> infinity)
292
# Waist is at q purely imaginary
293
294
focused_waists = np.array(focused_waists)
295
296
# Theoretical focused waist (thin lens approximation)
297
w0_focused_theory = wavelength * f / (np.pi * w0_input)
298
299
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
300
301
# Plot 1: Focused beam waist vs distance after lens
302
axes[0, 0].plot(d2_values*1000, focused_waists*1e6, 'b-', linewidth=2)
303
axes[0, 0].axhline(y=w0_focused_theory*1e6, color='gray', linestyle='--', alpha=0.7,
304
label=f'Theory: {w0_focused_theory*1e6:.1f} $\\mu$m')
305
axes[0, 0].axvline(x=f*1000, color='red', linestyle='--', alpha=0.5, label=f'$f = {f*1000:.0f}$ mm')
306
axes[0, 0].set_xlabel('Distance after lens (mm)')
307
axes[0, 0].set_ylabel('Beam radius ($\\mu$m)')
308
axes[0, 0].set_title('Focused Beam Size')
309
axes[0, 0].legend()
310
axes[0, 0].grid(True, alpha=0.3)
311
312
# Plot 2: Beam propagation through focusing system
313
z_total = np.linspace(0, d1 + f*2, 300)
314
w_propagation = []
315
316
for z in z_total:
317
if z < d1:
318
# Before lens
319
q = 1j * z_R_input + z
320
else:
321
# After lens
322
M1 = np.array([[1, d1], [0, 1]])
323
M_lens = np.array([[1, 0], [-1/f, 1]])
324
M2 = np.array([[1, z - d1], [0, 1]])
325
M_total = M2 @ M_lens @ M1
326
q_in = 1j * z_R_input
327
q = transform_gaussian_beam(q_in, M_total)
328
329
R_z, w_z = q_to_params(q, wavelength)
330
w_propagation.append(w_z)
331
332
w_propagation = np.array(w_propagation)
333
334
axes[0, 1].plot(z_total*1000, w_propagation*1e6, 'b-', linewidth=2)
335
axes[0, 1].plot(z_total*1000, -w_propagation*1e6, 'b-', linewidth=2)
336
axes[0, 1].fill_between(z_total*1000, -w_propagation*1e6, w_propagation*1e6, alpha=0.3)
337
axes[0, 1].axvline(x=d1*1000, color='green', linestyle='-', linewidth=3, label='Lens')
338
axes[0, 1].set_xlabel('$z$ (mm)')
339
axes[0, 1].set_ylabel('Beam radius ($\\mu$m)')
340
axes[0, 1].set_title('Beam Focusing Through Lens')
341
axes[0, 1].legend()
342
axes[0, 1].grid(True, alpha=0.3)
343
344
# Plot 3: Effect of lens focal length on spot size
345
focal_lengths = np.linspace(20e-3, 200e-3, 100)
346
spot_sizes = wavelength * focal_lengths / (np.pi * w0_input)
347
348
axes[1, 0].plot(focal_lengths*1000, spot_sizes*1e6, 'g-', linewidth=2)
349
axes[1, 0].set_xlabel('Focal length (mm)')
350
axes[1, 0].set_ylabel('Minimum spot size ($\\mu$m)')
351
axes[1, 0].set_title('Spot Size vs Focal Length')
352
axes[1, 0].grid(True, alpha=0.3)
353
354
# Plot 4: Depth of focus of focused beam
355
NA = w0_input / f # Numerical aperture
356
DOF = 2 * wavelength / (NA**2)
357
358
# Intensity along axis near focus
359
z_near_focus = np.linspace(-3*DOF, 3*DOF, 200)
360
z_R_focused = np.pi * w0_focused_theory**2 / wavelength
361
I_axial = 1 / (1 + (z_near_focus/z_R_focused)**2)
362
363
axes[1, 1].plot(z_near_focus*1e6, I_axial, 'r-', linewidth=2)
364
axes[1, 1].axhline(y=0.5, color='gray', linestyle='--', alpha=0.7)
365
axes[1, 1].axvline(x=z_R_focused*1e6, color='blue', linestyle='--', alpha=0.5, label=f'$z_R = {z_R_focused*1e6:.1f}$ $\\mu$m')
366
axes[1, 1].axvline(x=-z_R_focused*1e6, color='blue', linestyle='--', alpha=0.5)
367
axes[1, 1].set_xlabel('Distance from focus ($\\mu$m)')
368
axes[1, 1].set_ylabel('Axial intensity (normalized)')
369
axes[1, 1].set_title('Depth of Focus')
370
axes[1, 1].legend()
371
axes[1, 1].grid(True, alpha=0.3)
372
373
plt.tight_layout()
374
save_plot('gaussian_beam_focusing.pdf', 'Gaussian beam focusing: spot size, beam propagation through lens, and depth of focus.')
375
\end{pycode}
376
377
\section{Higher-Order Hermite-Gaussian Modes}
378
\begin{pycode}
379
from scipy.special import hermite
380
381
# Higher-order mode analysis
382
def hermite_gaussian(x, y, z, m, n, w0, wavelength):
383
"""Calculate Hermite-Gaussian mode amplitude."""
384
z_R = np.pi * w0**2 / wavelength
385
w = w0 * np.sqrt(1 + (z/z_R)**2)
386
R = z * (1 + (z_R/z)**2) if z != 0 else np.inf
387
psi = np.arctan(z/z_R)
388
389
# Hermite polynomials
390
Hm = hermite(m)
391
Hn = hermite(n)
392
393
# Mode amplitude
394
E = (1/w) * Hm(np.sqrt(2)*x/w) * Hn(np.sqrt(2)*y/w) * np.exp(-(x**2 + y**2)/w**2)
395
396
return E
397
398
# Create mode patterns
399
x = np.linspace(-3*w0, 3*w0, 100)
400
y = np.linspace(-3*w0, 3*w0, 100)
401
X, Y = np.meshgrid(x, y)
402
403
fig, axes = plt.subplots(2, 3, figsize=(12, 8))
404
405
modes = [(0, 0), (1, 0), (0, 1), (1, 1), (2, 0), (2, 2)]
406
titles = ['TEM$_{00}$', 'TEM$_{10}$', 'TEM$_{01}$', 'TEM$_{11}$', 'TEM$_{20}$', 'TEM$_{22}$']
407
408
for ax, (m, n), title in zip(axes.flat, modes, titles):
409
E = hermite_gaussian(X, Y, 0, m, n, w0, wavelength)
410
I = np.abs(E)**2
411
412
im = ax.pcolormesh(X*1e6, Y*1e6, I, cmap='hot', shading='auto')
413
ax.set_xlabel('$x$ ($\\mu$m)')
414
ax.set_ylabel('$y$ ($\\mu$m)')
415
ax.set_title(title)
416
ax.set_aspect('equal')
417
418
plt.tight_layout()
419
save_plot('hermite_gaussian_modes.pdf', 'Hermite-Gaussian transverse modes TEM$_{mn}$ intensity patterns.')
420
\end{pycode}
421
422
\section{Beam Quality Analysis}
423
\begin{pycode}
424
# M^2 beam quality analysis
425
# Compare ideal Gaussian to real beam with M^2 > 1
426
427
M2_values = [1.0, 1.5, 2.0, 3.0]
428
colors_m2 = ['blue', 'green', 'orange', 'red']
429
430
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
431
432
# Plot 1: Beam width for different M^2
433
z_m2 = np.linspace(-5*z_R, 5*z_R, 200)
434
435
for M2, color in zip(M2_values, colors_m2):
436
w_m2 = w0 * np.sqrt(1 + (M2 * z_m2 / z_R)**2)
437
axes[0, 0].plot(z_m2/z_R, w_m2/w0, color=color, linewidth=2, label=f'$M^2 = {M2:.1f}$')
438
439
axes[0, 0].set_xlabel('$z/z_R$')
440
axes[0, 0].set_ylabel('$w(z)/w_0$')
441
axes[0, 0].set_title('Beam Width vs $M^2$')
442
axes[0, 0].legend()
443
axes[0, 0].grid(True, alpha=0.3)
444
445
# Plot 2: Divergence vs M^2
446
M2_range = np.linspace(1, 5, 100)
447
divergence = M2_range * wavelength / (np.pi * w0) * 1000 # mrad
448
449
axes[0, 1].plot(M2_range, divergence, 'b-', linewidth=2)
450
axes[0, 1].set_xlabel('$M^2$')
451
axes[0, 1].set_ylabel('Divergence (mrad)')
452
axes[0, 1].set_title('Far-field Divergence vs Beam Quality')
453
axes[0, 1].grid(True, alpha=0.3)
454
455
# Plot 3: Brightness (power density per solid angle)
456
P_total = 1 # Normalized power
457
brightness = P_total / (np.pi * (M2_range * wavelength / (np.pi * w0))**2)
458
brightness_norm = brightness / brightness[0]
459
460
axes[1, 0].plot(M2_range, brightness_norm, 'g-', linewidth=2)
461
axes[1, 0].set_xlabel('$M^2$')
462
axes[1, 0].set_ylabel('Brightness (normalized)')
463
axes[1, 0].set_title('Beam Brightness vs $M^2$')
464
axes[1, 0].grid(True, alpha=0.3)
465
466
# Plot 4: Focused spot size for different M^2
467
f_lens = 100e-3
468
w0_focused = M2_range * wavelength * f_lens / (np.pi * w0_input)
469
470
axes[1, 1].plot(M2_range, w0_focused*1e6, 'r-', linewidth=2)
471
axes[1, 1].set_xlabel('$M^2$')
472
axes[1, 1].set_ylabel('Focused spot size ($\\mu$m)')
473
axes[1, 1].set_title(f'Focused Spot Size ($f = {f_lens*1000:.0f}$ mm)')
474
axes[1, 1].grid(True, alpha=0.3)
475
476
plt.tight_layout()
477
save_plot('beam_quality.pdf', 'Beam quality analysis: effect of $M^2$ on propagation, divergence, brightness, and focusing.')
478
\end{pycode}
479
480
\section{Optical Resonator Stability}
481
\begin{pycode}
482
# Stability of optical resonators
483
# Stable if 0 <= g1*g2 <= 1, where g = 1 - L/R
484
485
def resonator_stability(g1, g2):
486
"""Return stability condition."""
487
return 0 <= g1 * g2 <= 1
488
489
# Create stability diagram
490
g1_range = np.linspace(-2, 2, 200)
491
g2_range = np.linspace(-2, 2, 200)
492
G1, G2 = np.meshgrid(g1_range, g2_range)
493
494
stability = np.logical_and(G1 * G2 >= 0, G1 * G2 <= 1)
495
496
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
497
498
# Plot 1: Stability diagram
499
axes[0, 0].contourf(G1, G2, stability.astype(int), levels=[0.5, 1.5], colors=['lightblue'])
500
axes[0, 0].contour(G1, G2, stability.astype(int), levels=[0.5], colors=['blue'], linewidths=2)
501
502
# Mark common resonator types
503
resonators = {
504
'Plane-plane': (1, 1),
505
'Confocal': (0, 0),
506
'Concentric': (-1, -1),
507
'Hemispherical': (1, 0),
508
'Concave-convex': (0.5, 2)
509
}
510
511
for name, (g1, g2) in resonators.items():
512
if resonator_stability(g1, g2):
513
axes[0, 0].plot(g1, g2, 'go', markersize=8)
514
else:
515
axes[0, 0].plot(g1, g2, 'rx', markersize=8)
516
axes[0, 0].annotate(name, (g1, g2), xytext=(5, 5), textcoords='offset points', fontsize=8)
517
518
axes[0, 0].set_xlabel('$g_1 = 1 - L/R_1$')
519
axes[0, 0].set_ylabel('$g_2 = 1 - L/R_2$')
520
axes[0, 0].set_title('Resonator Stability Diagram')
521
axes[0, 0].grid(True, alpha=0.3)
522
axes[0, 0].set_xlim([-2, 2])
523
axes[0, 0].set_ylim([-2, 2])
524
525
# Plot 2: Mode waist in symmetric resonator
526
L = 0.5 # Cavity length (m)
527
R_range = np.linspace(0.3, 2, 100) # Mirror ROC (m)
528
g = 1 - L / R_range
529
530
# Waist for symmetric resonator
531
w0_cavity = np.sqrt(wavelength * L / np.pi) * ((1 - g**2)**0.25 / np.sqrt(2 * (1 - g)))
532
w0_cavity = np.where(np.abs(g) < 1, w0_cavity, np.nan)
533
534
axes[0, 1].plot(R_range*1000, w0_cavity*1e3, 'b-', linewidth=2)
535
axes[0, 1].axvline(x=L*1000, color='gray', linestyle='--', alpha=0.7, label=f'$R = L$ (confocal)')
536
axes[0, 1].set_xlabel('Mirror ROC (mm)')
537
axes[0, 1].set_ylabel('Mode waist (mm)')
538
axes[0, 1].set_title(f'Cavity Mode Waist ($L = {L*1000:.0f}$ mm)')
539
axes[0, 1].legend()
540
axes[0, 1].grid(True, alpha=0.3)
541
542
# Plot 3: Mode at mirrors for symmetric resonator
543
w_mirror = np.sqrt(wavelength * L / np.pi) * (1 / (1 - g**2)**0.25)
544
w_mirror = np.where(np.abs(g) < 1, w_mirror, np.nan)
545
546
axes[1, 0].plot(R_range*1000, w_mirror*1e3, 'r-', linewidth=2)
547
axes[1, 0].axvline(x=L*1000, color='gray', linestyle='--', alpha=0.7)
548
axes[1, 0].set_xlabel('Mirror ROC (mm)')
549
axes[1, 0].set_ylabel('Mode size at mirror (mm)')
550
axes[1, 0].set_title('Mode Size at Mirrors')
551
axes[1, 0].grid(True, alpha=0.3)
552
553
# Plot 4: Free spectral range and finesse
554
FSR = 3e8 / (2 * L) # Free spectral range (Hz)
555
reflectivities = np.linspace(0.9, 0.999, 100)
556
finesse = np.pi * np.sqrt(reflectivities) / (1 - reflectivities)
557
558
axes[1, 1].semilogy(reflectivities * 100, finesse, 'g-', linewidth=2)
559
axes[1, 1].set_xlabel('Mirror reflectivity (\\%)')
560
axes[1, 1].set_ylabel('Finesse')
561
axes[1, 1].set_title(f'Cavity Finesse (FSR = {FSR/1e9:.1f} GHz)')
562
axes[1, 1].grid(True, alpha=0.3, which='both')
563
564
plt.tight_layout()
565
save_plot('resonator_stability.pdf', 'Optical resonator analysis: stability diagram, mode sizes, and cavity finesse.')
566
\end{pycode}
567
568
\section{Results Summary}
569
\begin{pycode}
570
# Generate results table
571
print(r'\begin{table}[htbp]')
572
print(r'\centering')
573
print(r'\caption{Summary of Gaussian Beam Parameters}')
574
print(r'\begin{tabular}{lll}')
575
print(r'\toprule')
576
print(r'Parameter & Symbol & Value \\')
577
print(r'\midrule')
578
print(f'Wavelength & $\\lambda$ & {wavelength*1e9:.0f} nm \\\\')
579
print(f'Beam waist & $w_0$ & {w0*1e6:.0f} $\\mu$m \\\\')
580
print(f'Rayleigh range & $z_R$ & {z_R*1000:.2f} mm \\\\')
581
print(f'Divergence half-angle & $\\theta$ & {np.rad2deg(theta_div):.4f}$^\\circ$ \\\\')
582
print(f'Depth of focus & $2z_R$ & {depth_of_focus*1000:.2f} mm \\\\')
583
print(f'Beam quality factor & $M^2$ & {M2:.1f} \\\\')
584
print(r'\midrule')
585
print(f'Input waist (focusing) & $w_{{0,in}}$ & {w0_input*1e3:.0f} mm \\\\')
586
print(f'Focal length & $f$ & {f*1000:.0f} mm \\\\')
587
print(f'Focused spot size & $w_{{0,focus}}$ & {w0_focused_theory*1e6:.1f} $\\mu$m \\\\')
588
print(f'Focused Rayleigh range & $z_{{R,focus}}$ & {z_R_focused*1e6:.1f} $\\mu$m \\\\')
589
print(r'\bottomrule')
590
print(r'\end{tabular}')
591
print(r'\end{table}')
592
\end{pycode}
593
594
\section{Statistical Summary}
595
\begin{itemize}
596
\item \textbf{Wavelength}: $\lambda = $ \py{f"{wavelength*1e9:.0f}"} nm
597
\item \textbf{Beam waist}: $w_0 = $ \py{f"{w0*1e6:.0f}"} $\mu$m
598
\item \textbf{Rayleigh range}: $z_R = $ \py{f"{z_R*1000:.2f}"} mm
599
\item \textbf{Divergence half-angle}: $\theta = $ \py{f"{np.rad2deg(theta_div)*1000:.2f}"} mrad
600
\item \textbf{Depth of focus}: $2z_R = $ \py{f"{depth_of_focus*1000:.2f}"} mm
601
\item \textbf{Power in $1/e^2$ radius}: 86.5\%
602
\item \textbf{Focused spot (diffraction limit)}: $w_0' = $ \py{f"{w0_focused_theory*1e6:.1f}"} $\mu$m
603
\item \textbf{Confocal cavity FSR}: \py{f"{FSR/1e9:.1f}"} GHz
604
\end{itemize}
605
606
\section{Conclusion}
607
Gaussian beam propagation is characterized by the Rayleigh range $z_R$, where the beam width increases by $\sqrt{2}$. The product $w_0 \cdot \theta = \lambda/\pi$ is minimum for an ideal Gaussian beam, representing the diffraction limit. Understanding beam propagation is essential for optical system design, including laser focusing, fiber coupling, and resonator mode analysis. The ABCD matrix formalism provides a powerful tool for analyzing complex optical systems. Higher-order Hermite-Gaussian modes exhibit characteristic multi-lobed intensity patterns and are important in resonator analysis and mode-selective applications.
608
609
\end{document}
610
611