UltrafastEngine

Optical components

The engine has models of what common optical components do to the beam, without ray tracing. Each one is made from the same parts as the rest of the engine: interface terms (Fresnel or coatings, s/p in the Jones basis), a bulk element (dispersion, absorption, and nonlinearity or a spatial model when there is a beam), and Jones terms. So overrides, provenance, the loss budget and the transverse models all work for them too. Every key is listed in the option reference.

element what it models
Gaussian beam tracking q parameters (x and y) through the whole system, so later elements get the right beam
Spatio-temporal couplings angular dispersion, spatial chirp and pulse-front tilt from gratings, prisms and tilted plates, carried with the tracked beam, and the dispersion they add
mirror with radiusOfCurvatureM focusing with off-axis astigmatism; aberration: Zernike / figure
plate (window) a plane-parallel plate: two surfaces, the bulk, optional ghost replicas
ndFilter neutral density, absorptive or reflective, OD or OD(λ)
waveplate with material thick multi-order, true zero-order and compound zero-order plates with full dispersion
thinFilmPolarizer (tfp) a physical quarter-wave stack at its design angle (TMM), transmitted or reflected port
faradayRotator non-reciprocal rotation with Verdet dispersion, plus the crystal's dispersion and B-integral
wavefront a Zernike / random wavefront error at one plane
chirpedMirror with rippleGddFs2 the GDD ripple of dispersive mirrors and complementary pairs

Gaussian beam tracking

When the run (or the system) has a Gaussian inputBeam, the engine follows its complex beam parameters q_x and q_y through every element:

"inputBeam": { "kind": "gaussian", "w0M": 1.0e-3, "zWaistM": 0.0, "m2": 1.1 },   // waist measured from the system input
"physics": { "beamTracking": "auto" }                                            // "auto" (default) | "on" | "off"

The q parameters are kept in reduced form q/n (vacuum-equivalent distances), so the ABCD law needs no index bookkeeping: a length L in a medium of index n adds L/n, a thin lens subtracts 1/f, a mirror in a medium of index n subtracts 2n/R. A tilted flat interface magnifies the tangential axis by cos θ₂ / cos θ₁; a grating with linesPerMm by cos θ_out / cos θ_in. Grating pairs, crystals, gain media and plates are crossed with their own length and index (the crystal and gain compilers report the index they use). The thermal lens of a pumped gain element is applied to the tracked beam (Gain: thermal lens).

What uses the tracked beam:

  • every nonlinear bulk / gap, crystal, plate and spatial element without a beam of its own (a note says "beam: the tracked Gaussian beam"), so the intensity there follows the real focusing;
  • gain and amplifier elements without beam, modeRadiusM or a carried profile take their signal mode radius from it;
  • surfaces without beamRadiusM: fluence, peak intensity and LIDT margins, clipping on apertures;
  • cameras and sampled instruments on a 1-D beam (the camera images the tracked beam at its location);
  • the ghost-overlap estimate of plates.

Each element reports trackedBeamRadiusXM, trackedBeamRadiusYM and the wavefront curvatures trackedCurvatureXM/YM at its exit (summary.json → elements[].values). An element with its own beam uses it; tracking carries on unchanged.

Simple astigmatism only: the principal axes are x and y. A fold plane at an arbitrary angle is snapped to the nearer axis (with a note). The thermal lens of a gain element is included. The lens is a graded-index duct per slice (exact ABCD, not a thin lens). A multipass amplifier puts its thermal lens on the tracked beam only when given the path between passes (thermalLens.track, passGapM); a regenerative amplifier takes it the same way with an integer roundTrips (Gain media).

Spatio-temporal couplings

With the beam tracked, the engine also follows how its colours separate: per axis, the spatial dispersion E = dx/dω (where each frequency's beam is) and the angular dispersion F = dθ/dω (where it goes), from the carrier's ray. This is the ray-pulse matrix formalism of Kostenbauder (IEEE J. Quantum Electron. 26, 1148 (1990)): every element with ABCD matrix and its own dispersion E_el, F_el maps

E' = A E + B F + E_el, F' = C E + D F + F_el

(reduced angles n θ, as for q). The elements that disperse:

element own dispersion
grating with linesPerMm (and order, default −1) sin θ_out = sin θ_in + m λ / Λ; dθ_out/dλ = m / (Λ cos θ_out); magnification cos θ_out / cos θ_in
interface / surface (refract) at an angle Snell's law between dispersive media: n₂ dθ₂/dω = (sin θ₁ dn₁/dω − sin θ₂ dn₂/dω) / cos θ₂
plate / window at an angle its two faces: spatial chirp ~ L sin θ / n, and a GDD above that of the carrier path (see Plate)
gratingPair with passes: 1 the output's spatial chirp G cos α / cos²β · dβ/dω

Angles are signed in the unfolded beam: the same sign on both faces of a parallel plate, opposite signs on the faces of a prism (its exit face is tilted the other way). A grating that undoes the dispersion of a first one has aoiDeg = the first's diffraction angle and the opposite order:

{ "id": "g1", "type": "grating", "linesPerMm": 1200, "aoiDeg": -45,     "order": 1 },   // leaves at +31.93 deg
{ "id": "gap", "type": "gap", "lengthM": 0.1178 },                                         // slant distance
{ "id": "g2", "type": "grating", "linesPerMm": 1200, "aoiDeg": 31.9307, "order": -1 }    // back to -45 deg: no angular dispersion

A prism is two interfaces and the glass between them; for a 60° fused-silica prism entered at 55°:

{ "id": "f1", "type": "interface", "before": "Air", "after": "FusedSilica", "aoiDeg": 55 },
{ "id": "glass", "type": "bulk", "material": "FusedSilica", "lengthM": 0.01 },
{ "id": "f2", "type": "interface", "before": "FusedSilica", "after": "Air", "aoiDeg": -25.60 }   // internal angle 34.40 - 60 (n = 1.450 at 1030 nm)

What the pulse gets. The 1-D spectrum A(ω) is the field on each frequency's own (chief) ray; the beam is U(x, ω) = A(ω) u_q(x − E Δω) exp(i k₀ F Δω (x − E Δω)). Keeping A on the chief ray costs a spectral phase, which the element applies to the pulse (a note gives it in fs² and fs³). It is computed exactly: five rays around the carrier are traced with the beam through gaps, lenses and tilted surfaces (Snell's law, the grating equation, the tilt of the surface), each collecting its optical phase, and differences across the bundle give GDD, TOD and FOD of each element. Inside a medium each ray has refracted by its own index, also at normal incidence, so a glass path L counts as L / n. To second order this is k₀ B F² for a length B (reduced) of free space, −k₀ E² / f for a lens, k₀ (A C E² + 2 B C E F + B D F²) for a general ABCD step and 2 k₀ F_el a E_in at a dispersing surface. After a system that cancels the couplings the sum is Kostenbauder's time element: Treacy's phase for two gratings (GDD −k₀ L F², and the TOD comes out too) and 0 for a 4f zero-dispersion stretcher. Fifth and higher orders are not applied; gratingPair remains the exact phase.

A prism element is the two faces and the glass in one element (material, apexDeg, signed aoiDeg, pathM for the glass on the carrier's ray, fresnel); its note gives the exit angle, which is the aoiDeg of a second prism that undoes the dispersion.

Reports (summary.json → elements[].values, per axis X / Y, when non-zero):

key meaning
trackedAngularDispersionXRadPerM dθ/dλ in the medium after the element (rad per m of wavelength; 1 µrad/nm = 1000)
trackedSpatialChirpXMPerM dx/dλ (m per m of wavelength; 1 mm/nm = 10⁶)
trackedPulseFrontTiltXSPerM, trackedPulseFrontTiltXDeg slope dt/dx of the intensity-weighted arrival time across the beam, and the tilt angle atan(c dt/dx / n)

The pulse-front tilt is computed from the pulse's actual spectrum: the Gaussian field above, its power-weighted group delay at 96 points across the beam (the first moment, exact and free of the time window), and a straight-line fit. It contains the tilt from angular dispersion (Hebling: tan γ = λ dθ/dλ) and the tilt from spatial chirp with temporal chirp (Akturk et al., Opt. Express 13, 8642 (2005)).

physics.spatioTemporal: "auto" (default) tracks the couplings and applies their dispersion -- unless an element has traced groupDelayS (a ray-traced system already contains it; a note says so); "on" always applies it; "track" only reports; "off" does neither. "profile" puts the coupling in the field itself: on a cartesian grid, each grating or tilted interface tilts every stored frequency of the carried profile by its exact deviation and applies the magnification, the spatial elements after it spread the colours, and no phase comes from the tracker (the two descriptions must not be added). It needs a fine sampling: the tilt may change by less than π/2 across the beam between stored frequencies (profileTiltStepRad; a warning says so), which takes a long time window and a large spectralSamples, and a grid wide enough for the spread beam. Couplings need beam tracking (a Gaussian inputBeam). A spaceTime instrument on a 1-D beam shows I(x, t) and S(x, λ) of the tracked Gaussian field with its couplings.

Validated (BeamTrackingTests): angular dispersion and pulse-front tilt of a grating against the grating equation and Hebling (0.2 %); two gratings against gratingPair (Treacy GDD 0.1 %, spatial chirp 0.2 %); pulse-front tilt from spatial chirp and GDD against the Gaussian result 2 φ₂ E σ² / (w² + 2 E² σ²) (0.5 %); a prism against Snell's law at both faces (0.5 %); a 4f zero-dispersion stretcher (GDD < 10⁻⁶ of k₀ f F²); Treacy's TOD from the ray bundle (0.5 %); a prism pair's −k₀ L F² (1 %); two gratings on a grid in "profile" mode against the tracker's spatial chirp and Treacy's GDD (3 %): a wave-optics check of the rays.

Curved and off-axis mirrors

{ "id": "cm1", "type": "mirror", "radiusOfCurvatureM": 1.0, "aoiDeg": 8, "planeOfIncidenceDeg": 90 }

At angle of incidence θ a spherical mirror has the tangential focal length f_t = R cos θ / 2 (in the plane of incidence) and the sagittal one f_s = R / (2 cos θ). planeOfIncidenceDeg is the angle of the s direction from x (90°, the default, folds in the x-z plane, so x is tangential). The astigmatism acts on the tracked beam and on a carried transverse profile. A radial grid cannot hold astigmatism: it gets the mean power, with a note (use a cartesian model). A lens can be astigmatic too (focalLengthXM, focalLengthYM).

Aberrations

Mirrors, surfaces and lenses accept an aberration; the wavefront element is a pure wavefront error:

"aberration": {
  "zernikeNollWaves": [0, 0, 0, 0.05, 0, 0.12],   // Noll order from Z1 (piston), waves rms at referenceWavelengthM
  "radiusM": 5e-3,                               // normalisation radius
  "surface": true,                               // numbers are surface height: x 2 cos(aoi) on a mirror, x (n2 - n1) refracting
  "randomRmsM": 5e-9, "correlationLengthM": 2e-3, "seed": 3   // random figure (cartesian grids)
}

The wavefront is an optical path difference W(x, y), applied as a phase ω W / c at every frequency (non-dispersive: exact for mirrors). On spatial grids it changes the carried profile: radial grids keep only the axisymmetric terms (Z1, Z4, Z11, Z22, ...), cartesian grids keep all of them and the random figure. On a 1-D beam nothing changes: the element reports the wavefront rms over the beam (piston and tilt removed) and the Maréchal estimate of the Strehl ratio, strehlEstimate = exp(-(2π σ / λ)²), for the tracked beam (or beamRadiusM). The Zernike polynomials are evaluated beyond radiusM too, so choose a radius that covers the beam.

Plate

{ "id": "window", "type": "plate", "material": "FusedSilica", "thicknessM": 6.35e-3, "aoiDeg": 0,
  "coating": "AR1030", "ghosts": { "orders": 1 }, "wedgeDeg": 0 }

Front surface → bulk over the internal path d / cos θ_t (dispersion, absorption, and with a beam its nonlinearity or a spatial model) → back surface. coatingFront / coatingBack override coating.

Tilted plates and their phase. At an angle every colour refracts at its own internal angle, so the phase through the plate is the plane-wave phase k_z(ω) d = (ω/c) d √(n² − n_o² sin²θ) (n_o: the surrounding medium), plus the air path each colour crosses between its own exit point and the plane normal to the carrier ray through the carrier's exit point, (ω/c) n_o sin θ d tan θ_t. The engine applies exactly this, with or without an inputBeam; with a tracked beam the ray bundle supplies the same phase. Its GDD at 40° and 70° for 5 mm of fused silica at 1030 nm is 0.3 and 1.0 fs² above what the path d / cos θ_t at the carrier would give. The same holds for the thin-film polariser's substrate.

Ghost reflections

With "ghosts": true (or an object) the part of the beam reflected twice inside the plate (back surface, then front surface) leaves with the main beam. The transmitted field becomes

E (1 + Σ_k η_k g^k exp(i k ψ(ω))), g = r_back r'_front, ψ = 2 n(ω) ω d cos θ_t / c,

per s and p, with the extra internal absorption of each round trip. The replica follows the main pulse by 2 n_g d cos θ_t / c (49 ps for 5 mm of fused silica) with the relative intensity |g|² (R² ≈ 1.1·10⁻³ for bare fused silica). η_k is the mode overlap of the replica with the main beam: its lateral offset 2 k d tan θ_t cos θ and the tilt of a wedge (2 k n α) reduce it, η = exp(-s²/2w²) exp(-(π w δ/λ)²/2), with w from the tracked beam, ghosts.beamRadiusM or beamRadiusM (full overlap and a note when none is known). ghosts.overlap sets it directly; frontReflectance / backReflectance replace the coatings' values. The grid planner widens the time window for the replicas down to grid.satelliteLevel (default 1e-8, combinations of several elements' ghosts included; see Run spec). The reflectances come from the coatings at each wavelength (a table or stack coating gives a spectrally varying ghost); weak ghosts far outside a manual window are reported by name, and grid.tail carries them on a long linear grid: Delayed light.

Ghosts of other elements. bulk, crystal, gain, amplifier and thick lens elements accept ghosts too: the double reflection at their two end faces at normal incidence, with the delay 2 n_g L / c and the level R_front R_back (Fresnel against air by default; give your AR coatings as frontReflectance / backReflectance, e.g. 0.002 each for -54 dB). ghosts.material names the index when the element does not (crystals defined inline), wedgeDeg tilts the replicas off the beam. Mirrors and single surfaces have no ghosts of their own: a back-reflection between two separate surfaces is a cavity -- model the pair as a plate of the gap's medium.

Because the replica is part of the field, everything downstream sees it: a later nonlinear element converts a post-pulse that overlaps a stretched pulse into a pre-pulse after compression (intensity ∝ B²; the test Ghost_KerrMediumCreatesPrePulsePartner checks it) -- the mechanism behind many measured pre-pulses.

ndFilter

{ "id": "nd1", "type": "ndFilter", "od": 1.0, "kind": "absorptive", "material": "N-BK7", "thicknessM": 2e-3 }
{ "id": "nd2", "type": "ndFilter", "od": [0.3, 0.5], "wavelengthsM": [1000e-9, 1060e-9], "kind": "reflective" }
  • absorptive: the OD is distributed over the glass (power transmission 10^-OD over the internal path), so a nonlinear filter sees the decaying intensity. The default substrate N-BK7 stands in for the dispersion of absorbing ND glass: give your glass (or its index table) as material.
  • reflective: a metallic coating on the front surface transmits 10^-OD; the rest is booked as "ndFilter (reflected)". Default substrate fused silica, 1 mm.
  • OD per wavelength: the absorbance is interpolated (not the transmission).
  • Ghosts as for a plate; for a reflective filter the front surface reflects strongly from inside (ghosts.frontReflectance, default 0.5).
  • Tilt the filter (aoiDeg) as in the lab to avoid back-reflections.

Waveplates

Without material a waveplate is the dispersionless design model (retardance ∝ ω). With a birefringent material it is a real plate with both indices' dispersion:

{ "id": "hwp", "type": "waveplate", "material": "Quartz", "plate": "half", "order": 10, "axisDeg": 22.5 }          // multi-order
{ "id": "qwp", "type": "waveplate", "material": "Quartz", "retardanceWaves": 0.25, "construction": "compound",
  "plateThicknessM": 1.0e-3, "designWavelengthM": 1030e-9 }                                                        // compound zero-order
{ "id": "wp", "type": "waveplate", "material": "MgF2", "thicknessM": 2.1e-3 }                                   // explicit thickness

J = R(θ) diag(exp(i n_f ω d / c), exp(i n_s ω d / c)) R(-θ) per plate (fast / slow axis from the sign of the birefringence); a compound plate adds a second plate of thickness d2 = d1 - λ_d Γ / Δn with crossed axes. The retardance follows Δn(λ) exactly, a thick plate is correspondingly chromatic, and the two axes have different group delays (|Δn_g| d / c: about 30 fs per mm of quartz at 1 µm, enough to split a short pulse). The note reports the retardance at the carrier and that delay. Crystals: Quartz, MgF2, Sapphire, Calcite, YVO4, aBBO; or give indexOrdinary and indexExtraordinary models.

Thin-film polarisers

{ "id": "tfp", "type": "thinFilmPolarizer", "output": "transmitted", "aoiDeg": 56, "axisDeg": 0 }

The default stack model is a physical (HL)^N H quarter-wave stack (HfO2 / SiO2, pairs 12) evaluated with the transfer-matrix method at the actual angle and wavelength. A quarter-wave stack reflects s over a wide band and p over a narrower one, so the stack is centred where the operating wavelength (designWavelengthM, default the carrier) lies between the p and the s band edges (bandPosition 0..1 within that range): s is reflected, p transmitted, and both change with angle, wavelength and bandwidth as a real TFP's do. The note gives Tp, Ts and Rs at the carrier. output: "transmitted" continues through the substrate (thicknessM, substrate); "reflected" takes the s port. axisDeg is the transmitted (p) axis in the lab. model: "ideal" uses transmissionP, transmissionS, reflectanceS.

Faraday rotators

{ "id": "fr", "type": "faradayRotator", "rotationDeg": 45, "material": "TGG", "lengthM": 0.02, "beam": {...} }
{ "id": "fr2", "type": "faradayRotator", "verdetRadPerTM": -40, "fieldT": 1.1, "lengthM": 0.018 }

The rotation follows θ(λ) = θ_d (λ_d² - λ0²) / (λ² - λ0²) (verdetPoleWavelengthM, 258 nm for TGG; "none" for a constant angle). It is non-reciprocal: in the engine's transported basis two passes add (an isolator's double pass gives 90°); "direction": -1 is a beam travelling against the field. With a material and lengthM the crystal's dispersion and, with a beam, its B-integral are included -- often the limiting nonlinearity of an isolator. The built-in TGG index is an approximate two-point fit and has no n2: give your crystal's data.

GDD ripple

{ "id": "cm", "type": "chirpedMirror", "gddFs2": -250, "bounces": 6,
  "rippleGddFs2": 30, "ripplePeriodNm": 25, "ripplePhaseRad": 0, "complementaryPairs": true }

GDD_r(ω) = A sin(2π (ω - ω0) / Ω + φ) per bounce, i.e. the phase -A (Ω / 2π)² sin(...). Complementary pairs alternate φ and φ + π, so an even number of bounces cancels the ripple. The coating kind "gddRipple" gives the same for a mirror coating (with an optional reflectance ripple).

Multi-pass cell mode (cellMode)

A Herriott or quasi-concentric cell is stable only for a beam whose complex parameter q reproduces itself after one round trip. In the empty cell this is the Kogelnik-Li eigenmode; at high peak power the Kerr lens of the gas or the glass plates changes it, and the matched mode depends on the power. cellMode finds it, so no trial runs in the radial model are needed. It is a command (uf_command), reached from Python as ultrafast.cells.cell_mode(...) and from C# as Lasers.CellModeSolver.Solve.

from ultrafast import cells
r = cells.cell_mode(1030e-9, mirror_radius=0.35, separation=0.54)                      # empty cell: waist 220 um, 459 um on the mirrors
r = cells.cell_mode(800e-9, mirror_radius=1.5, separation=2.9, peak_power=2e9, gas={"species": "Ar", "pressureBar": 0.4})
r["matched"], r["mode"]["waistRadiusM"], r["bIntegralTotalRad"]

Keys (SI): wavelengthM, mirrorRadiusM or mirrorRadiiM [R1, R2] (concave, positive), separationM (or reentrant {roundTrips N, order k}: d = R (1 - cos(pi k / N)), the Herriott closing condition N theta = 2 pi k with theta = 2 arccos(g)), passes (traversals; the total B-integral is passes / 2 round trips), peakPowerW, gas {species, pressureBar, temperatureK, n2M2PerW} (index and n2 from the gas library), plates (thicknessM, positionM of the centre from mirror 1, material or index, n2M2PerW), lensModel, slices (Kerr lenses per medium segment, 12). The launch plane is just after mirror 1. The reply has emptyCell and mode (waistRadiusM, waistDistanceFromLaunchM, radiusAtLaunchM, radiusAtMirror1M, radiusAtMirror2M, reduced q), matched, stability ((A + D) / 2), residual, bIntegralPerRoundTripRad, overlapEmptyModeWithMatchedMode (power coupling of the empty-cell mode into the matched one), shiftOfWaistRadius. If the Kerr lens drives the round trip out of its stability range, matched is false with a message instead of a mode.

Method. The round trip is a product of reduced-coordinate ABCD matrices (mirrors 2n/R, media length/n). A Kerr slice of length dz has the thin-lens power 1/f = n2 dz I0 / w^2 with I0 = 2P / (pi w^2), w the beam radius at the slice. This is the second-moment lens: it reproduces the Vlasov-Petrishchev-Talanov evolution of the rms radius, and agrees with the radial Kerr propagation of the engine to 0.3 % in the test KerrLensOfTheHelper_ReproducesTheRadialModelsRmsRadius (the on-axis parabolic lens, lensModel: "paraxial", is 4 times stronger and does not). The self-consistent mode is found by a damped fixed point over the lens powers with continuation in the power (10 steps).

Limits. Round beams (astigmatism at the injection angle is not included); the peak power only (the wings of a pulse see a weaker lens, so the match holds at the peak); instantaneous Kerr effect, no dispersion, ionisation or loss; mirrors at normal incidence.