Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
1bf57eb
SEP 31: in progress
jtravs Oct 23, 2026
3f356c9
Pulses: sample a SpatialPulse normalised over its whole incident plane
jtravs Oct 23, 2026
7c2edfa
General modal launch: an incident beam keeps only what the channels c…
jtravs Oct 23, 2026
5101f1f
Docs: incident beams launch the captured share of their energy
jtravs Oct 23, 2026
ab08384
SEP 31: Part II report for phase 1, the incident-energy correction
jtravs Oct 23, 2026
ffaa29e
SEP 31: record the phase 1 docs build
jtravs Oct 23, 2026
b54329e
SEP 31 transport: linear elements on a spatial plane
jtravs Oct 23, 2026
1518d03
SEP 31 transport: ordered transport with a sequential ledger
jtravs Oct 23, 2026
e06de69
SEP 31 transport: tests against analytic and independent references
jtravs Oct 23, 2026
c4d36ca
Coupling: the field plane, its port and temporal remapping (SEP 31)
jtravs Oct 23, 2026
6e7b9dc
Plane exchange: output schema 24, field_plane and same-basis relaunch
jtravs Oct 23, 2026
f3dcb14
Docs: plane exchange, the coupling chapter and output schema 24
jtravs Oct 24, 2026
5f7bdaa
SEP 31: Part II report for phase 2, plane exchange
jtravs Oct 24, 2026
b0b3e67
Merge the SEP 31 transport core
jtravs Oct 24, 2026
ea6d05f
SEP 31 transport: field planes in and out, coupling refusals
jtravs Oct 24, 2026
e7e62f2
Docs: transport between planes, its API entries and the solid transpo…
jtravs Oct 24, 2026
1bec4b9
SEP 31: Part II report for phase 4, the transport core
jtravs Oct 24, 2026
2e86ff2
Docs: the transport report's API page and clean cross-references
jtravs Oct 24, 2026
30b36cf
Coupling: models, couple, admission budget and Outcouple (SEP 31 phas…
jtravs Oct 24, 2026
2199712
Driver: incident beams are coupled under a declared vector model
jtravs Oct 24, 2026
b4b85ba
Coupling: name the module coupler, so the function couple is not shad…
jtravs Oct 24, 2026
593c952
Docs: coupling models, admission budget and report (SEP 31 phase 3)
jtravs Oct 24, 2026
6a05a32
Merge the SEP 31 transport core on field planes
jtravs Oct 24, 2026
4a43859
Merge SEP 34 medium flux (2c625c5) into SEP 31
jtravs Oct 24, 2026
9bd24ca
SEP 31: plain wording in the phase reports
jtravs Oct 24, 2026
356e022
Coupling: carry the rebuilt AdiabaticAdmission as a plane's path cert…
jtravs Oct 24, 2026
0422429
Tutorial: nonlinear beam preparation and coupling into a capillary
jtravs Oct 24, 2026
85a9012
Docs: link the capillary coupling tutorial from the guides
jtravs Oct 24, 2026
20ab95b
Docs: list the capillary coupling tutorial in the free-space gallery
jtravs Oct 24, 2026
a1599b9
Coupling: an honest capillary envelope and the review's admission fixes
jtravs Oct 24, 2026
1922165
Tests: the eight SEP 31 compositions as short integrated runs
jtravs Oct 24, 2026
6abc0bb
Docs: SEP 31 phase 5 -- compositions, conventions, accuracy, capabili…
jtravs Oct 24, 2026
5a45be6
Merge branch 'sep31/tutorial' into feature/sep-0031-simulation-coupling
jtravs Oct 24, 2026
5cb7462
SEP 31: Part II report for the capillary coupling tutorial
jtravs Oct 24, 2026
3d7c1cc
Example: graded-index launch as an incident SpatialPulse
jtravs Oct 24, 2026
2d4b97c
Docs: format the coupling guide's code blocks
jtravs Oct 24, 2026
a0e0e85
Tests: exclude the coupling extraction from solprop.sol; allow roundi…
jtravs Oct 24, 2026
5d6ab63
Merge remote-tracking branch 'origin/feature/sep-0034-medium-flux' in…
jtravs Oct 24, 2026
141dabf
SEP 31: record the graded-index example's re-run
jtravs Oct 24, 2026
0257839
Tests: cover the plane, port and extraction refusals
jtravs Oct 24, 2026
12abb59
Tests: cover the coupler's and models' refusals
jtravs Oct 24, 2026
6c6eeff
Coupling: refuse modified-noise planes and same-grid fields at the wi…
jtravs Oct 24, 2026
602c598
Tests: move the transport sequence helper out of the conftest
jtravs Oct 24, 2026
9642d71
Coupling: admit a beam into a weakly guiding fibre; widen the flux sp…
jtravs Oct 24, 2026
a965c0c
Coupling: record a facet envelope for vector_paraxial into step-index…
jtravs Oct 24, 2026
5b45300
Docs: the vector model's step-index facet envelope; SEP 31 decision A1
jtravs Oct 24, 2026
95045ec
Merge branch 'sep31/vector-envelope' into feature/sep-0031-simulation…
jtravs Oct 24, 2026
7f596c6
Coupling: bound the vector facet envelope over every field in the cone
jtravs Oct 24, 2026
6b07f02
Merge remote-tracking branch 'origin/main' into feature/sep-0031-simu…
jtravs Oct 24, 2026
4b096fd
Coupling: form the general guide's cone phase matrix in blocks
jtravs Oct 24, 2026
ea10836
Merge remote-tracking branch 'origin/main' into feature/sep-0031-simu…
jtravs Oct 24, 2026
204799e
Merge remote-tracking branch 'origin/main' into feature/sep-0031-simu…
jtravs Oct 24, 2026
a62e035
SEP 31: Final after phase 5; the remaining coupling work moves to the…
jtravs Oct 24, 2026
f785658
optmat 0.9.0: resolve a rate's family without building every model
jtravs Oct 24, 2026
11aba7e
Import scipy.signal and pyplot only where they are used
jtravs Oct 24, 2026
9364fd0
Evaluate set-up Chebyshev tables with NumPy until numba is loaded
jtravs Oct 24, 2026
53ea2ce
Record the shorter start-up
jtravs Oct 24, 2026
62e9a47
optmat 0.9.1: ionisation parameters read one gas's fit
jtravs Oct 24, 2026
78e57a5
Import air's equation of state from optmat.gas.eos, which exports it
jtravs Oct 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,88 @@ The first public release. It contains:
`SimulationSettings.adiabatic_accuracy`). `poynting_spectrum` is removed:
`beam_spectrum` is the axial-flux spectrum. Kernel schema 35 (`flux`) and output
schema 23 (`flux_model`, `flux_plan`).
- **Incident beams into general modal guides**
([SEP 31](https://solprop.readthedocs.io/en/latest/dev/seps/archive/sep-0031-simulation-coupling.html),
phases 1 and 3). `from_waveguide(provider=..., incident=SpatialPulse(...),
coupling=CouplingModel("vector_paraxial", model_error=...))` and `prop_waveguide`
launch the share of an incident beam that the guide's channels capture. The beam's
energy is met over its whole plane in the core medium, and the light that misses is
lost rather than restored. The coupling's `CouplingReport` is recorded in
`configuration["launch"]`, and `SpatialPulse.incident` samples a beam normalised over
its own plane. The node-sampled `transverse=` profile, its rescaling to `energy=`, the
3 % uncaptured warning, `LAUNCH_UNCAPTURED_WARNING` and `IncidentLaunch` are removed;
a strongly guiding core is refused by the vector model's contrast screen.
- **Plane exchange between simulations**
([SEP 31](https://solprop.readthedocs.io/en/latest/dev/seps/archive/sep-0031-simulation-coupling.html),
phase 2). `solprop.coupling` holds `FieldPlane`, a coherent field at one plane with
its reference, geometry, metric, basis identity and provenance; `regrid`, the direct
finite-time Fourier remap between temporal grids with its loss report and no
renormalisation; and `InputPort`. `processing.field_plane` reads a saved plane back
(refusing a modified-noise run's, whose auxiliary noise phase it does not reconstruct),
`Simulation.input_port()` describes a simulation's entrance and `with_input` takes a
launch bound to it, recording `configuration["coupling"]` and drawing no new noise.
Output schema 24 records each run's plane-reference record (`RunMetadata.reference`).
- **Coupling models**
([SEP 31](https://solprop.readthedocs.io/en/latest/dev/seps/archive/sep-0031-simulation-coupling.html),
phase 3). `couple(plane, port, model=CouplingModel(kind, model_error=...))` is the one
path from a field plane to a launch bound to a port, returning the launch and an
immutable `CouplingReport`. `same_basis` copies an identical basis, applies a declared
energy-preserving `BasisChange` or recovers a general modal plane by the flux pairing;
`scalar_paraxial` fits Gaussian, analytic or sampled beams into a capillary's HE1m
modes, one capillary's exit into another of any radius, and one weakly guiding
step-index fibre into another, in the common paraxial measure; `vector_paraxial`
couples into a general modal guide with the forward H closure. Each is admitted
against its energy budget: angular tails, the weak-guidance contrast screen or a
recorded pair envelope (`CAPILLARY_ENVELOPE`, `STEP_INDEX_ENVELOPE`), metric defects,
the H closure, a passive-map certificate and numerical errors; uncaptured energy is
reported only where a common positive metric exists. `FieldPlane.from_analytic`
samples an analytic field with its support and domain checks, `FieldPlane.from_pulse`
takes a reference `index=`, `field_plane(run, source=...)` carries an ordinary mode
set's scalar profiles (`ScalarModeBasis`), and `Outcouple` synthesises a guide's exit
field on a spatial grid under a declared interface model. Ports state the models they
admit. The phase-2 `same_basis` function is removed in favour of `couple`.
- **Transport between planes**
([SEP 31](https://solprop.readthedocs.io/en/latest/dev/seps/archive/sep-0031-simulation-coupling.html),
phase 4). `coupling.transport` carries a radial or Cartesian `FieldPlane` through an
ordered sequence of linear elements -- `FreeSpace` (exact angular-spectrum
propagation, with an explicit `"angular"` or `"fresnel"` output plane), `ThinLens`,
`Aperture`, `TransmissionMask`, `Alignment`, `PolarisationTransform`, `Mirror`,
`PlanarInterface` and `SpectralTransfer` (any `optics` transfer function or `Chain`)
-- and returns the plane with its reference, geometry, medium, metric and provenance
updated and a sequential ledger in joules. Thin screens carry their angular-flux
certificate; undersampled phases, wrapped rays and evanescent content are refused
unless their removal is declared, and a same-grid field filling the window's outer
band is refused beyond `FreeSpace(edge_tolerance=...)` (default 1e-4). Refusals raise `CouplingError`.
- **Coupled workflows**
([SEP 31](https://solprop.readthedocs.io/en/latest/dev/seps/archive/sep-0031-simulation-coupling.html),
phase 5). The eight compositions of the coupling chapter -- capillary into capillary,
a nonlinear gas gap into a capillary, fibre into fibre, Gaussian, analytic and
Cartesian beams into a guide, a guide's far field, and SPM, compression and relay
optics into a second capillary -- run as short integrated tests that assert their
energy ledgers, with sources and receivers on different CPU backends. A plane's path
certificate (`FieldPlane.certificate`, `CouplingReport.certificate`,
`TransportReport.source_certificate`) is the rebuilt `AdiabaticAdmission`, not its raw
record. `CAPILLARY_ENVELOPE` now bounds the scalar model against Marcatili's leaky core
field (bound 6e-3 at its range's top, delta = 1e-2, scaled by the pair's delta) rather
than against the scalar profile itself; bins outside an envelope's range, including a
fibre's V across the band, are counted in full; the modal overlap quadrature enters
the budget as `2 delta + delta^2`. `scalar_paraxial` also admits a radial or
Cartesian beam into a weakly guiding step-index fibre (LP01, V 1.5 to 2.4, contrast
to 0.01) within `STEP_INDEX_BEAM_ENVELOPE`, the scalar overlap against the beam's
full-vector flux coupling into the exact HE11 pair maximised over every field in the
admitted cone (bound 1e-2 at contrast 0.01, scaled by the fibre's contrast).
`same_basis`'s flux recovery of a general modal plane allows the plane's own metric
defect as well as the port's when it checks that the field lies in the port's span,
and reports both.
the budget as `2 delta + delta^2`.
`VECTOR_STEP_INDEX_ENVELOPE` bounds `vector_paraxial` into a step-index guide
against an independent full-vector mode-matching solution of the entrance facet,
maximised over every incident field in the admitted cone (bound 3.0e-3 at contrast
0.05, twice the Fresnel ceiling a mode near cutoff approaches, V 1.5 to 8, scaled by
the squared contrast); its item is counted and a guide outside its range is refused
by name. A step-index
port carries `InputPort.normalised_frequency`; a graded-index guide keeps an
uncounted item without a value.
- **Media and responses.**
- Gases, gas mixtures, glasses and metals from the [optmat](https://github.com/LupoLab/optmat)
material library.
Expand Down Expand Up @@ -73,6 +155,11 @@ The first public release. It contains:
([SEP 29](https://solprop.readthedocs.io/en/latest/dev/seps/archive/sep-0029-compiled-backend-distribution.html)).
- Each backend is tested against the reference implementation within derived error
bounds.
- A short start-up: a run on the native backend imports neither Numba nor
`scipy.signal`, plotting imports `matplotlib.pyplot` only when it draws, and an
optmat rate builds only the model it uses (optmat 0.9.1, which reads only the data a
model needs). A five-centimetre capillary run with ionisation is under way in about
3 s on an Apple M5 Max, from 5.5 s.
- **The native backend.**
- `NativeBackend` runs one trial step per native call, with states, views and FFT
plans resident in the execution space; `NativeBatchBackend` runs fixed-schedule
Expand Down
19 changes: 14 additions & 5 deletions benchmarks/guides.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from benchmarks.records import SuiteError
from solprop.boundaries import absorber
from solprop.constants import C
from solprop.coupling import CouplingModel
from solprop.driver import Simulation
from solprop.grid import FieldGrid
from solprop.modes import (
Expand All @@ -37,6 +38,7 @@
from solprop.modes.material import JsonValue
from solprop.physdata import fused_silica
from solprop.profiles import PiecewiseLinear
from solprop.pulses import GaussianPulse, SpatialPulse

__all__ = ["ScaledPermittivity", "advanced", "coupled", "grin", "moving", "step_index"]

Expand Down Expand Up @@ -222,17 +224,24 @@ def grin(*, nonlinear: bool) -> Simulation:
/ C
)
period = 2 * np.pi / float(np.mean(-np.diff(beta)))
beam = np.zeros((nodes.xy.shape[0], 3))
beam[:, 0] = np.exp(-((np.hypot(nodes.xy[:, 0], nodes.xy[:, 1]) / 12e-6) ** 2))
# The incident beam's energy is over its whole plane; the channels launch
# the share they capture, coupled under the vector paraxial model.
beam = SpatialPulse(
GaussianPulse(
wavelength=wavelength,
fwhm=300e-15,
energy=5e5 * 300e-15 * np.sqrt(np.pi / (4 * np.log(2))),
),
12e-6,
)
return Simulation.from_waveguide(
(),
0.1,
provider=guide,
grid=grid,
transverse=beam,
incident=beam,
coupling=CouplingModel("vector_paraxial", model_error=0.2),
lambda0=wavelength,
fwhm=300e-15,
energy=5e5 * 300e-15 * np.sqrt(np.pi / (4 * np.log(2))),
noise="input",
seed=41,
dz_max=period / 10,
Expand Down
4 changes: 3 additions & 1 deletion docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ In scripts and library code, import from the home modules listed below.
| module | what it holds |
|---|---|
| {mod}`solprop.output` | the in-memory and HDF5 output handlers, the run's metadata record, `open_file` and resuming a run, live snapshots (`SnapshotController`, `read_snapshot`, `restore_snapshot`; [the output page](../guide/results/output.md)), and the raw TDSE response archive (`TDSEArchive`, `open_tdse_archive`; [the TDSE response](../guide/media/tdse.md#the-raw-response-archive)) |
| {mod}`solprop.processing` | post-processing of a saved run: fields, spectra, pulse metrics, coherence, compression, and the physical fields of a general modal run |
| {mod}`solprop.processing` | post-processing of a saved run: fields, spectra, pulse metrics, coherence, compression, the physical fields of a general modal run, and `field_plane`, a saved plane read back for coupling |
| {mod}`solprop.coupling` | coupling simulations through a field plane: `FieldPlane` (from a run, a `SpatialPulse`, an analytic field or arrays), `regrid`, `InputPort`, `couple` under a `CouplingModel` with its `CouplingReport`, the scalar profiles `ScalarModeBasis`, the recorded pair envelopes and `Outcouple`; `transport` through the linear elements `FreeSpace`, `ThinLens`, `Aperture`, `TransmissionMask`, `Alignment`, `PolarisationTransform`, `Mirror`, `PlanarInterface` and `SpectralTransfer` ([coupling simulations](../guide/workflows/coupling.md); [the transport report](transport.md)) |
| {mod}`solprop.stats` | the statistics recorded at the saved planes, and `StatsSpec` to choose them |
| {mod}`solprop.plotting` | the standard figures: propagation maps, slices, spectrograms, statistics |
| {mod}`solprop.optics` | linear optics applied to a pulse outside a propagation: materials, chirped mirrors, grating and prism pairs |
Expand All @@ -73,6 +74,7 @@ design behind both is in the [developer documentation](../dev/index.md).
species
tabulated
scans
transport
```

## Complete generated reference
Expand Down
19 changes: 19 additions & 0 deletions docs/api/transport.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Transport between planes

{func}`solprop.coupling.transport` carries a radial or Cartesian
{class}`~solprop.coupling.plane.FieldPlane` through an ordered sequence of the linear
elements of {mod}`solprop.coupling.elements` and returns the transported plane with its
{class}`~solprop.coupling.transport.TransportReport`, the sequential ledger in joules
([transporting a plane](../guide/workflows/coupling.md#transporting-a-plane-between-planes)).

Because the function has the same name as its module, `solprop.coupling.transport`
refers to the function, not the module; the module's report class is documented on this
page. Both names are importable from {mod}`solprop.coupling`.

```{eval-rst}
.. autoclass:: solprop.coupling.transport.TransportReport
:members:
```

Transport between planes was proposed and carried out by
[SEP 31](../dev/seps/archive/sep-0031-simulation-coupling.md).
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading