532 nm · ring cavity M1/M2 flat (T = 1 %), M3 R = 1 m on PZT · π/2 converter from two LJ1703RM · real N-BK7 thicknesses in air
In short: Light can be trapped between three mirrors so that only beams of one particular shape keep building up and pass through. This simulation picks one beam shape at a time, holds the mirrors at the right spacing with a feedback lock, and then uses two curved lenses to twist the beam into a ring-shaped or donut-shaped beam.
Input beam in the cavity mode basis (HGnm, n horizontal, m vertical):
Scan = transmission vs laser detuning over one FSR (log scale), from the input's mode content. Click a peak to lock to it. Refl and trans photodiodes are placed for PDH and transmission locking; error signals are not shown yet.
π/2 converter needs a 90° Gouy split between the two lens axes and a stigmatic beam on both sides. Shift ML, CL1 or CL2 to break either condition.
How do you make a clean higher-order mode on demand? A triangular ring cavity is PDH-locked to a chosen Hermite-Gauss mode, and a π/2 converter of two Thorlabs LJ1703RM cylindrical lenses turns HG11 into LG(1,0) and HG10 into LG(0,±1). Finesse/Python gives the cavity physics; a separate JavaScript 3D bench lays it out to scale for hands-on misalignment.
RunLocks; report transmitted power, purity and field/intensity images.bs surfaces with no substrate. The input beam is the cavity eigenmode traced back to the laser, so it is perfectly mode-matched by construction.1. Frequency-domain modal cavity model (Finesse 3). Finesse expands every field in HG_nm modes, up to order maxtem, around Gaussian bases traced from the cavity eigenmode. It solves the linear steady-state equations for the carrier and each modulation sideband at every sweep point. Handled: the .kat files and the inline KatScript in build_model:
- Laser: P = 1 W, then 0.05 m of space to mod EOM (f = 25 MHz, midx = 0.2, phase modulation), then 0.15 m to M1.
- M1 and M2: bs with R = 0.99 and T = 0.01, at AoI 42.1447°.
- M3: R = 0.99999, T = 10⁻⁵, AoI 5.7106°, Rc = 1 m.
- Spaces: 0.05 m between M1 and M2, two legs of 0.251247 m, round trip 0.5525 m.
- cav FP M1.p3.o defines the eigenmode. The pd detectors are trans at M2.p3.o and refl at M1.p2.o. ad detectors are set for each HG_nm.
2. Geometry of the triangle. Leg = √(H² + (d/2)²). The apex angle is 2·atan(d/2H). AoI(M3) is half the apex, and AoI(M1,2) = (180° − apex)/4. Handled: closed form in Python with d = 50 mm and H = 250 mm. These give the AoIs used in the .kat files.
3. Higher-order-mode resonances and image parity. The round-trip phase of HG_nm is φ_nm = φ₀ − (n·ψ_x + m·ψ_y). The ring has an odd number of reflections, which flips x, so odd-n modes pick up an extra π. Handled: Finesse's FP.gouy_x = 243.59°, which includes the flip, and gouy_y = 63.24°. The predicted lock point is M3.phi = wrap(−(nψ_x + mψ_y))·1/(2cos AoI₃). M3 moves along its normal at 5.71°, so 1° of tuning gives 2cos(5.71°) degrees of round-trip phase. The results are 0°, −31.7779°, 58.4940° and 26.7161° for HG00, 01, 10 and 11. These are mirror-tuning values; the equivalent laser-frequency offset has the opposite sign, f = +(nψ_x + mψ_y)/360°·FSR (wrapped), because raising the frequency is equivalent to lengthening the cavity (checked with a Finesse 3 laser-frequency scan of a test cavity: HG10 appears at +ψ_rt/360°·FSR).
4. Cavity transmission. The transmitted amplitude is t = √(T₁T₂)/(1 − r e^{−iφ}), with r = √(R₁R₂R₃). The finesse is F = π√r/(1 − r) ≈ 312 and FWHM = FSR/F. Handled: Finesse computes FP.FSR, FWHM and finesse. The 3D bench uses this closed-form Airy function and the same F formula.
5. Pound-Drever-Hall lock. The reflected light is demodulated at 25 MHz to give an error signal that is antisymmetric about each resonance. Handled:
- pd1 PDH_I M1.p2.o f=EOM.f phase=0.
- A 600-point scan near each resonance gives the local slope.
- Lock("cav_lock", PDH_I, M3.phi, gain = −1/slope, accuracy = 10⁻⁹), started 0.3 FWHM off resonance, then RunLocks(method="proportional") followed by Noxaxis.
- Result: P_trans = 0.9792 W of 1 W for every mode. The carrier holds J₀(0.2)² ≈ 0.980 and the sidebands are not resonant. Purity is 0.99998.
6. Input misalignment and mode content. A tilted steering mirror adds tilt and offset at the cavity, which project onto HG10 (yaw, tangential) and HG01 (pitch). Handled: in the .kat file, bs SM R=1 alpha=45 sits 0.14 m before M1. The .kat file itself sets xbeta = 20 µrad and ybeta = 12 µrad. The Python script overrides these with 60 and 40 µrad. maxtem is 4, and M3.phi is swept from −90° to 90° in 6000 points. ad detectors at M1.p1.i measure the input content: HG00 93.0 %, HG10 4.0 %, HG01 0.9 %. Transmitted peaks are HG00 0.929 W, HG10 40 mW (+175.5 MHz), HG01 9 mW (−95.3 MHz), HG11 0.5 mW (+80.2 MHz), and HG20/HG02 about 1.3 mW together near −191 MHz.
7. π/2 cylindrical-lens converter. Two cylindrical lenses of focal length f are spaced d = √2·f with their axes at 45° to the HG axes. The input waist sits at the midpoint with z_R = (1 + 1/√2)f. The converter adds a π/2 Gouy difference between the axes, so HG_mn becomes LG with ℓ = m − n and p = min(m, n). Handled (Python):
- Lens values: f = R/(n − 1) = 38.8/0.51947 = 74.69 mm, and tc = (75.0 − 67.4) × 1.5168 = 11.53 mm.
- Layout: reduced vertex spacing 105.6 mm, physical vertex gap 113.5 mm, flat gap 90.5 mm. z_R = 127.5 mm and w0 = 146.9 µm.
- Input field: synthesised from the Finesse-locked amplitudes up to order 2, on a 512 × 512 grid of width 40·w0.
- Lenses: thin phase exp(+ik u²/2f) at each curved vertex, with u = (x + y)/√2.
- Propagation: exact angular spectrum, exp(−i(k_z − k)z).
- Purity: overlap with normalised LG_pℓ built with SciPy genlaguerre at the output plane.
- Mode matching from the cavity to the converter: ML (f = 250 mm) 86.3 mm after M2, solved by _solve_mode_match from the Finesse q at M2.
8. 3D-bench optics engine (no Finesse). The chief ray is traced with exact 3D Snell refraction and reflection at planes, spheres and cylinders. The indices are N-BK7 (Sellmeier, 1.51947), air (1.000278) and LiNbO₃ (n_e = 2.234). The beam is a general astigmatic Gaussian in Arnaud X/Θ form, with W = ΘX⁻¹ = nQ⁻¹: - Free space: X += (L/n)Θ. - Each surface: X′ = AX and Θ′ = CX + DΘ, using the local angle of incidence and curvature tensor. A = P₂P₁⁻¹, D = P₂⁻ᵀP₁ᵀ and C = −Δ·P₂⁻ᵀKP₁⁻¹, where Δ = n₂(d₂·N) − n₁(d₁·N).
Handled: - Cavity: Newton iteration (6 steps, finite-difference Jacobian) finds the closed orbit, including tilted mirrors. The round-trip ABCD matrix gives the eigenmode per axis: 274.7 × 275.6 µm. Per-axis Gouy phases are accumulated in small steps, and the parity comes from the basis sign. - Input coupling: a 96 × 96 numerical overlap of the traced input with cavity HG_nm for n + m ≤ 6 gives 99.997 %. - Lock: the locked output is Σ c_nm·t(f_L − f_nm)·HG_nm, with P_trans = 20 mW × Σ|…|² and P_refl as the remainder. - Converter: 128 × 128 grid. A paraxial (Fresnel) angular spectrum propagates through tc = 11.5 mm of glass at n = 1.519, the flat gap and the camera distance. Each convex face is a thin phase with power (n − n_air)/R. - Converter purity is computed against ideal HG and LG targets.
triangular_cavity_mode_scan.kat, triangular_cavity_lock_HG11.kat, triangular_cavity_misaligned_scan.kat: standalone KatScript models.triangular_cavity_hom_lock.py: builds the model inline, prints the parameters, and produces the mode scan, PDH signals, locks, images (02–05), lock_results.csv, and schematics 01 and 08 via cavity_schematic.py (Snell-traced substrates and converter layout).mode_converter_hg11.py: Finesse lock → mode amplitudes → NumPy angular-spectrum converter → GIF 06 and summary 07.misaligned_cavity_scan.py: SM tilt, one-FSR scan, CCD images at the peaks → figure 09 and misaligned_scan.csv.engine.js: ray and beam physics, Hermite/Laguerre polynomials, FFT.model.js: parts, the DES layout, cavity, decomposition, lock, converter.app.js: three.js scene, UI, scan plot, images, parts list.clamps.js: shared post, pedestal and fork placement.design.js / design2.js: Node solvers for Y_IN, L1/L2 and the converter spacing. Their results are pasted into DES.build.py: inlines everything into shell.html.cav, mod, pd1 (demodulated at the EOM frequency) and ad detectors. Inject tem modes and lock M3.phi on PDH_I.pip install -r requirements.txt, then python triangular_cavity_hom_lock.py, python mode_converter_hg11.py [--mode 10] and python misaligned_cavity_scan.py [--yaw 100 --pitch 0]. For the 3D bench, run python build.py in 3D/src and open the HTML file.| Parameter | Value | Source |
|---|---|---|
| Wavelength λ | 532 nm | design choice |
| M1/M2 transmission | T = 1 % (impedance matched) | design choice |
| M3 | Rc = 1 m, T = 10⁻⁵, on PZT | design choice |
| AoI M1/M2 / M3 | 42.1447° / 5.7106° | design choice (from d = 50 mm, H = 250 mm) |
| Round trip / FSR | 552.5 mm / 542.6 MHz (vacuum) | design choice |
| FWHM / finesse | 1.74 MHz / 312 | design choice (from T, R) |
| Round-trip Gouy x / y | 243.59° (incl. flip) / 63.24° | Siegman 1986 (computed by Finesse) |
| PDH modulation | 25 MHz, index 0.2 | design choice |
| maxtem | 3 (locks), 4 (misaligned scan) | design choice |
| Laser power | 1 W (Finesse), 20 mW (3D) | design choice |
| Steering-mirror tilt (scan) | 60 µrad yaw, 40 µrad pitch (py); 20/12 µrad (.kat) | design choice |
| Converter lens LJ1703RM | R = 38.8 mm, tc = 11.53 mm, f = 74.69 mm at 532 nm | datasheet |
| Converter waist / z_R | 146.9 µm / 127.5 mm | Beijersbergen 1993 |
| Vertex / flat gap | 113.5 mm / 90.5 mm (Python) | Beijersbergen 1993 |
| Mode-matching lens ML | f = 250 mm, 86.3 mm after M2 | design choice |
Every interactive page loads three shared files. engine.js is the optics math, kit.js is the three.js scene, stand-in hardware, beam drawing and parts table, and clamps.js places the posts and forks. Units are mm in a table frame (x, y, z up). Each experiment's physics lives in its own model file. The engine only does the optics that a model explicitly asks for.
make(λ).cloneB) at a beamsplitter and traces each branch with its own surface list. Surfaces have no apertures, so the model must handle clipping.The kit's photodiode and camera objects are bodies on posts and compute nothing. Photodiode voltages, quadrant read-outs, spectra and noise are all computed in each model file. These calculations are often analytic and use no engine at all, as in the Faraday, EOM and direction-finder pages. Labels are CSS2D text set by the app.
Each stand-in part and post stack registers a row: reference, category, part number, description. A stack registers a TR post, a PH40 or PH50 holder (chosen for the beam height), a BE1/M base, and a CF125C/M fork unless the post sits directly on a hole. partsTable() groups and counts identical rows, sorts them by category, and writes the HTML table and the CSV.
Each fork's M6 screw must land on a 25 mm-grid hole 26.4–49.6 mm from the post. Forks perpendicular to the beam are preferred. A sliding part keeps its hole while that hole still fits, then re-clamps. Forks may not overlap other forks, pedestals or registered footprints ("obstacles"). Conflicts turn red, and a guard stops posts from colliding. All of this is mechanical layout only; it has no optical effect.
Every part drawn on the table is listed here, including post lengths picked for the 76.2 mm beam height. Part numbers are Thorlabs suggestions; verify them before ordering. "custom" means a coating vendor. Mount offsets are approximate, so check post lengths against the datasheets.
Merges two lines of work: a triangular (ring) cavity used to select and lock higher-order Hermite-Gauss modes by deliberate misalignment and mode mismatch, and an astigmatic π/2 cylindrical-lens mode converter that turns HG modes into LG modes. Mode-converter sensing of cavity mismatch is the copyright holder's own published work (refs 1–2).