thunder4d.simulation

Driver: propagates a pulse through the cell and records diagnostics after every pass.

Pass convention (the same as the 1+1D code of the design helper): the simulation starts right after a mirror (injection plane) and one pass is a transit over \(d\) followed by a bounce on the next mirror, so \(N\) passes are \(N\) transits and \(N\) bounces. The input pulse is given at the cell centre and moved to the injection plane by a linear half pass. Diagnostics are taken at the cell centre: after every pass, the field is imaged back to the centre by a linear half pass (the far field of the beam leaving the cell after that pass). LensFrameSimulation (recommended) is a subclass with the same arguments, methods, history and saved file; only its mirror records are in frame coordinates.

class thunder4d.simulation.MPCSimulation(pulse, cell, *, solver=None, record_every=1, near_field=True, max_order=6, mode_reference='linear', save_fields=(), save_dir='.', record_mirror=True, slit=None, profile_wavelengths=(), profile_bandwidth=0.0, profile_axis='x', **solver_kw)[source]
Parameters:
  • pulse – input Pulse (copied), defined at the cell centre

  • cell – MPC

  • solver – an existing UPPESolver; otherwise one is created with **solver_kw (e.g. phi_max=0.02)

  • record_every (int) – record every n passes (pass 0 and the last pass always)

  • near_field (bool) – also record the near-field (collimated beam) quantities (a few seconds per record)

  • max_order (int) – highest Hermite–Gauss order in the modal decomposition

  • mode_reference – "linear" (linear eigenmode \(w_0(\lambda)\)) or a float waist at \(\lambda_0\) (e.g. the matched w0), scaled as \(\sqrt{\lambda/\lambda_0}\)

  • save_fields – pass numbers whose full 3D field is written to save_dir/field_passNNN.npy

  • record_mirror (bool) – record fluence and profiles at the mirror before each bounce

  • slit (float) – slit width [m] integrated around \(y = 0\) for \(S(x,\lambda)\) (None = one row)

  • profile_wavelengths – wavelengths [m] whose 1D profiles are recorded every pass, with the global profile

  • profile_bandwidth (float) – bandpass width [m] (0 = nearest spectral bin, of width \(\lambda^2/cT\))

  • profile_axis (str) – "x" or "y"

run(n_passes=None, verbose=True, max_seconds=None)[source]

Propagate n_passes passes (default: up to cell.n_passes). max_seconds stops cleanly after the pass that exceeds the wall-clock budget.

record(p, mirror_fluence=None, mirror_profiles=None)[source]

Record diagnostics for pass p (called automatically).

checkpoint(path)[source]

Pickle the full state (field, history, solver counters).

resume(path)[source]

Restore a checkpoint into a simulation built with the same grid and cell.

save(path, include_field=True)[source]

Write history, axes, metadata (and the final field) to a compressed .npz.

property done

True once cell.n_passes passes have been made.

property pulse

Current field as a Pulse.

Other attributes: Aw (field after the last pass, seen at the cell centre), state (the propagated field, right after the last bounce), history, passes_done, lam, x, theta, prof_coord (sorted axes of the recorded quantities), solver.

Recorded history

sim.history is a dict of lists with one entry per recorded pass. Wavelength-resolved quantities are interpolated on sim.lam.

Key

Shape per entry

Content

pass

scalar

pass number (0 = input)

energy

scalar

energy [J]

B

scalar

accumulated on-axis peak B-integral [rad]

peak_power

scalar

peak of \(P(t)\) [W]

spectrum

(Nλ,)

spatially integrated spectrum

fluence

(Nx, Ny)

fluence at the cell centre [J/m²]

fluence_mirror

(Nx, Ny) or None

fluence at the mirror before the bounce

sgram_x

(Nx, Nλ)

\(S(x,\lambda)\) at \(y = 0\) (or over slit)

sgram_theta

(Nθ, Nλ) or None

\(S(\theta,\lambda)\) at \(\theta_y = 0\)

eta00

(Nλ,)

HG₀₀ fraction vs wavelength

eta00_total

scalar

spectrally integrated HG₀₀ fraction

order_frac

(max_order+2,)

energy fraction per mode order

V_far, V_near

scalar

mean spectral homogeneity at the cell centre (far field) / of the collimated beam (near field)

wx, wy, M2x, M2y

(Nλ,)

second-moment radii and \(M^2\) vs wavelength

w_peak_x, w_peak_y

scalar

second-moment radius [m] at the spectral peak of the input pulse (same colour every pass)

M2x_mean, M2y_mean

scalar

spectrally weighted \(M^2\)

prof_far

(nλ+1, Nx)

1D cuts at the cell centre = far field (bands + global)

prof_far_proj

(nλ+1, Nx)

1D projections at the cell centre (far field)

prof_near

(nλ+1, Nθ)

1D cuts of the collimated beam = near field (angle)

prof_mirror

(nλ+1, Nx) or None

mirror-plane 1D cuts (None at pass 0)

band_energy

(nλ+1,)

energy in each band, last = total [J]

wall_s

scalar

elapsed wall-clock time [s]

Saved file

sim.save(path) writes a compressed .npz with:

  • every non-empty history key, stacked over passes;

  • prof_mirror and fluence_mirror for passes 1 … N only (before each bounce);

  • the axes lam, x, t, theta and, if profiles were recorded, prof_coord, prof_wavelengths, prof_bandwidth;

  • metadata R, d, n_passes, gas, pressure_bar, n2, lambda0 and grid = [Nx, Ny, Nt, dx, dy, dt];

  • Aw_final if include_field=True.