solprop.backends.spatial#
Collect spatial host statistics through bounded transverse reconstruction chunks.
Module Attributes
Bytes a compiled far-field pass's band partials may hold (SEP 23 section 6). |
|
Columns per unit of a line's far-field pass: a plane's unit is a whole row. |
|
The axis statistics |
|
The axis statistics Kokkos's far-field pass forms from its |
Functions
|
Return how many frequency bins the collar diagnostic reconstructs at a time. |
|
Measure the fraction of the beam's field norm in the declared spatial collar. |
|
Collect spatial statistics without retaining a full physical-space field. |
|
Return the column edges of a compiled far-field pass's bands. |
|
Lay out the slots a compiled far-field pass accumulates for a request. |
|
Return the slots and bands a compiled far-field pass holds for a problem. |
|
Return the rounding budget of a signed local fluence (SEP 34 section 5.1). |
|
Compose the fixed radial rate into one spectral-space matrix. |
|
Return the widths of a signed local fluence, refusing a negative profile. |
|
Take a planar state from its |
|
Project spectra at the planar nodes onto the |
|
Take a planar state from its |
|
Synthesise a planar state's field at the |
Classes
|
Where each quantity of a compiled far-field pass lives in its slots. |
|
Hold a problem's far-field tables, formed at construction, for its statistics. |
- solprop.backends.spatial.AXIS_FOLDED = frozenset({'on_axis_intensity', 'on_axis_spectrum'})#
The axis statistics
numba_cpu’s far-field pass forms from itsW = 1slot.
- solprop.backends.spatial.AXIS_SPECTRUM_ONLY = frozenset({'on_axis_spectrum'})#
The axis statistics Kokkos’s far-field pass forms from its
W = 1slot.Kokkos forms
on_axis_intensityin its own spatial statistics pass, so its slot count leaves that name out.
- solprop.backends.spatial.FAR_FIELD_BAND_BUDGET = 134217728#
Bytes a compiled far-field pass’s band partials may hold (SEP 23 section 6).
The band count is
min(n_units, budget // (8 n_slots n_omega)), at least one: fixed by the shapes and this constant, never by the thread count, so the order of every sum is the same whatever the pool.
- class solprop.backends.spatial.FarFieldLayout(beam, absorbed, regions, apertures, stride, collected, amplitude, axis, n_slots)[source]#
Bases:
objectWhere each quantity of a compiled far-field pass lives in its slots.
The slot order of SEP 23 section 6, present slots only: the beam spectrum, the four absorbed-power channels, the regions, then per aperture its collected spectrum and its on-axis amplitude, then the on-axis amplitude itself (the
W = 1slot). An amplitude is the real and imaginary parts per polarisation of the electric sumsum_c alpha_c W E_c, then those of its magnetic closuresum_c alpha_c W conj(eta_c) E_c(SEP 34),4 n_polslots. An absent quantity is-1.- Attributes:
- beam, absorbed, regionsint
The first slot of each, or -1.
- aperturesint
The first aperture’s first slot, or -1.
- strideint
Slots per aperture.
- collected, amplitudeint
Offsets within an aperture’s slots, or -1.
- axisint
The first of the
4 n_polslots of the on-axis amplitude and its closure, or -1.- n_slotsint
Slots in all, positive.
- class solprop.backends.spatial.FarFieldTables(problem)[source]#
Bases:
objectHold a problem’s far-field tables, formed at construction, for its statistics.
A backend builds one when it is constructed, which forms
solprop.translate.spatial.aperture_tables()for the problem’s own spec – refusing a geometry the far-field statistics do not admit before any step – and handsfor_spec()the spec of each statistics call. The periodic channel and the reference backend’s filtered specs carry the problem’s own apertures and regions, and get the held tables; a different spec handed to the run loop gets tables formed for it.- Parameters:
- problemsolprop.translate.problem.KernelProblem
The problem the backend executes.
- Raises:
- OutputError
If the problem’s spec names a far-field statistic its geometry does not admit (
solprop.translate.spatial.aperture_tables()).
- for_spec(spec)[source]#
Return the tables a statistics call’s spec reads.
- Parameters:
- specsolprop.stats.StatsSpec
The spec of this call.
- Returns:
- solprop.spatial.ApertureTables or None
The held tables when the spec carries the problem’s own apertures and regions and they were formed, tables formed for this spec otherwise, and
Nonewhen it names no far-field statistic.
- solprop.backends.spatial.LINE_BLOCK = 64#
Columns per unit of a line’s far-field pass: a plane’s unit is a whole row.
- solprop.backends.spatial.collar_block(problem)[source]#
Return how many frequency bins the collar diagnostic reconstructs at a time.
A block of the physical field on every node holds at most as many complex samples, with its working copies (the strided slice, the transform’s output and the weighted power: three block volumes), as one node chunk of the response pass holds of one temporal column,
node_chunk * n_pol * n_to. The chunk is what the run’snode_budgetadmits, so the diagnostic’s transient is bounded by the same budget.- Parameters:
- problemsolprop.translate.problem.KernelProblem
A Cartesian or planar problem.
- Returns:
- int
Bins per block, at least one and at most
n_omega.
- solprop.backends.spatial.collar_field_fraction(problem, field)[source]#
Measure the fraction of the beam’s field norm in the declared spatial collar.
A named electric-field-norm boundary diagnostic, the share of
integral |E_a|^2 dA dton the collar’s nodes: it says how much field reaches the transverse boundary. It is not a fraction of the physical axial flux, which the nonlocal admittance need not localise on those nodes (SEP 34 section 5.1).- Parameters:
- problemsolprop.translate.problem.KernelProblem
Plain geometry, temporal scaling and scalar synthesis data.
- fieldnumpy.ndarray
One internal spatial spectrum, with the problem’s state dimensions.
- Returns:
- float
Field-norm fraction on nodes where the spatial window is below one. Zero for an empty beam, absent geometry or a disabled spatial window.
Notes
On the Cartesian and planar kinds the physical field is reconstructed by block of frequency (
collar_block()), never as the whole volume: each node’s fluence is a sum over frequency, so blocks accumulate it exactly, up to the order of the sum (SEP 22 section 6.3), and the transient is one block, bounded by the node chunk the run’snode_budgetadmits. The radial kind synthesises by node chunk, as before.
- solprop.backends.spatial.collect_spatial(spec, grid, transform, field, *, z, flux, profiles=None, physical=None, tables=None, operator=None, axis=None, closure=None)[source]#
Collect spatial statistics without retaining a full physical-space field.
Every field statistic is the axial Poynting flux of the medium at the plane (SEP 34): energy and spectra weigh each column and bin by the real admittance
c Re(k_z)/omegaof the plane’s root, and local statistics pair the field with its magnetic closure, synthesised from the complex admittance.- Parameters:
- specsolprop.stats.StatsSpec
Requested spatial saved-field statistics or scalar profiles.
- gridsolprop.grid.TimeGrid
Temporal reconstruction and spectral energy measure.
- transformsolprop.translate.modal.Transform
Scalar radial synthesis and plain geometry data from the seam.
- fieldnumpy.ndarray
One internal spatial spectrum, shape
(n_modes, n_pol, n_omega).- zfloat
Current propagation position in m.
- fluxsolprop.translate.spatial.FluxPlan or None
The run’s plane measure; required by every field statistic.
- profilescollections.abc.Mapping or None, optional
Named scalar paths, where requested.
- physicalnumpy.ndarray or None, optional
Borrowed Cartesian physical-space spectrum, reconstructed into a compiled backend’s persistent scratch. Shape agrees with
field.- tablessolprop.spatial.ApertureTables or None, optional
The far-field tables (
FarFieldTables), needed by the far-field statistics of SEP 23.- operatorsolprop.translate.spatial.SeparableOperator or None, optional
The run’s separable linear operator, whose rates
absorbed_powerneeds.- axistuple of numpy.ndarray or None, optional
The on-axis amplitude
sum_c alpha_c E_cin V/m and its magnetic closuresum_c alpha_c conj(eta_c) E_c, each of shape(n_pol, n_omega), when a compiled pass has formed them (SEP 23 section 6); the axis statistics then read them instead of forming them here.- closurenumpy.ndarray or None, optional
The spectrum’s magnetic closure
conj(eta) Eat this plane, when a compiled pass has formed it; the local statistics then read it.
- Returns:
- dict
Scalar or small array values, without the backend’s batch axis.
- Raises:
- BackendError
If geometry, the plane measure or a requested statistic dependency is missing, or a width is asked of a fluence negative beyond its rounding.
Notes
The far-field statistics are one pass of
solprop.spatial.aperture_statistics()over the columns, in chunks of the transform’snode_chunk, reading the plane’s root throughsolprop.translate.spatial.axial_factors(), the root the stages use.
- solprop.backends.spatial.far_field_bands(n_x, n_y, n_slots, n_omega)[source]#
Return the column edges of a compiled far-field pass’s bands.
The units are whole rows on a plane and blocks of
LINE_BLOCKcolumns on a line (n_y == 1); the bands are contiguous runs of units, as many as the units or asFAR_FIELD_BAND_BUDGETadmits, whichever is fewer, and at least one. Nothing here depends on the thread count.- Parameters:
- n_x, n_yint
The transverse grid’s samples; column
ix + n_x*iy.- n_slotsint
The pass’s slots.
- n_omegaint
Frequency bins.
- Returns:
- numpy.ndarray
Ascending column edges, int64, shape
(n_bands + 1,), from 0 ton_x*n_y.
Examples
>>> from solprop.backends.spatial import far_field_bands >>> far_field_bands(4, 3, 2, 8).tolist() [0, 4, 8, 12] >>> far_field_bands(130, 1, 2, 8).tolist() [0, 64, 128, 130]
- solprop.backends.spatial.far_field_layout(names, *, n_apertures, n_regions, n_pol, axis_folded=frozenset({'on_axis_intensity', 'on_axis_spectrum'}))[source]#
Lay out the slots a compiled far-field pass accumulates for a request.
- Parameters:
- namescollections.abc.Collection of str
The statistics asked for; any that the pass does not form are ignored.
- n_apertures, n_regionsint
The request’s table rows.
- n_polint
The state’s polarisation components.
- axis_foldedcollections.abc.Collection of str, optional
The axis statistics that read the
W = 1slot:AXIS_FOLDEDonnumba_cpu(the default),AXIS_SPECTRUM_ONLYon the native backend.
- Returns:
- FarFieldLayout or None
The layout, or
Nonewhen the pass has nothing to form.
Examples
>>> from solprop.backends.spatial import far_field_layout >>> layout = far_field_layout( ... ("beam_spectrum", "aperture_spectrum", "on_axis_spectrum"), ... n_apertures=2, n_regions=0, n_pol=1, ... ) >>> layout.beam, layout.apertures, layout.stride, layout.axis, layout.n_slots (0, 1, 1, 3, 7)
- solprop.backends.spatial.far_field_partials(problem, *, axis_folded=frozenset({'on_axis_intensity', 'on_axis_spectrum'}))[source]#
Return the slots and bands a compiled far-field pass holds for a problem.
Sized from the problem’s own request at construction: its names, tables and polarisations. A Cartesian or line problem whose request forms nothing in the pass (and any other kind) holds none.
- Parameters:
- problemsolprop.translate.problem.KernelProblem
The translated problem.
- axis_foldedcollections.abc.Collection of str, optional
The axis statistics the backend’s pass forms, as for
far_field_layout().
- Returns:
- tuple of int
(n_slots, n_bands), both zero when nothing is held. The partials holdn_bands * n_slots * n_omegafloat64 values and their band sumn_slots * n_omega.
- solprop.backends.spatial.fluence_budget(magnitude, n_terms)[source]#
Return the rounding budget of a signed local fluence (SEP 34 section 5.1).
A node’s fluence
(eps0 c/2) dt sum Re(E G*)sumsn_pol n_tproducts of two syntheses over the columns;n_termscounts both sums. A synthesis (a transverse FFT or a dense sum, then the temporal FFT) errs normwise: each node’s value carries rounding of the whole field’s size, which in a beam’s wings far exceeds the value itself. Eight rounding units per term, relative to the largest magnitude(eps0 c/2) dt sum |E| |G|over the nodes, bound every node’s error.- Parameters:
- magnitudenumpy.ndarray
The fluence magnitude at each node in J/m^2.
- n_termsint
n_pol * n_t + n_modes.
- Returns:
- numpy.ndarray
The budget in J/m^2 at each node.
- solprop.backends.spatial.radial_absorber_matrix(transform, pad_scale)[source]#
Compose the fixed radial rate into one spectral-space matrix.
- Parameters:
- transformsolprop.translate.modal.Transform
Scalar radial forward/inverse matrices and plain spatial rate data.
- pad_scalefloat
Temporal oversampling factor already folded into synthesis.
- Returns:
- numpy.ndarray
F diag(-alpha/2) Bin m^-1, shape(n_r, n_r), or an empty matrix when spatial absorption is absent. No temporal scaling remains.
Notes
The radial rate is independent of time and z. It therefore commutes with temporal Fourier transforms, allowing this construction-time composition. It remains a term in N, separate from the material polarization prefactor. Cartesian rates use transverse FFTs instead of this dense matrix.
- solprop.backends.spatial.signed_fluence_widths(geometry, fluence, budget, axis_fluence)[source]#
Return the widths of a signed local fluence, refusing a negative profile.
A fluence negative by more than its rounding budget (
fluence_budget()) has no width (SEP 34 section 5.1); within the budget it is rounding and is read as zero.- Parameters:
- geometrysolprop.translate.spatial.SpatialGeometry
Radial, Cartesian, line or planar geometry.
- fluencenumpy.ndarray
Signed fluence in J/m^2 at the nodes.
- budgetnumpy.ndarray
Its rounding budget at each node.
- axis_fluencefloat
The on-axis fluence in J/m^2, which the radial widths read.
- Returns:
- tuple of float
Second-moment, 1/e^2 and FWHM widths in m, as the geometry’s width helper defines them.
- Raises:
- BackendError
If the fluence is negative beyond its budget anywhere.
- solprop.backends.spatial.slab_columns(transform, rows)[source]#
Take a planar state from its
(p, y)rows back to(p, k_y)columns.- Parameters:
- transformsolprop.translate.modal.Transform
A transform with
"slab"geometry.- rowsnumpy.ndarray
Spectra with the
n_p * n_yrows first, the channel fastest.
- Returns:
- numpy.ndarray
The unscaled forward raw DFT in y, the same shape.
- solprop.backends.spatial.slab_projection(transform, physical)[source]#
Project spectra at the planar nodes onto the
(p, k_y)columns.- Parameters:
- transformsolprop.translate.modal.Transform
A transform with
"slab"geometry.- physicalnumpy.ndarray
Spectra at the nodes
ix + n_x*iy, first axisn_x*n_y.
- Returns:
- numpy.ndarray
The slab projection in x, then the forward DFT in y, first axis
n_p*n_y.
- solprop.backends.spatial.slab_rows(transform, columns)[source]#
Take a planar state from its
(p, k_y)columns to its(p, y)rows.The inverse raw DFT in y alone, scaled by
1/n_y. A row is a modal amplitude in sqrt(W/m) at one y sample, whose time signal is real on a field grid, so every per-row temporal operation – a temporal absorber, the y collar – is exact here.- Parameters:
- transformsolprop.translate.modal.Transform
A transform with
"slab"geometry.- columnsnumpy.ndarray
Spectra with the
n_p * n_ycolumns first, the channel fastest.
- Returns:
- numpy.ndarray
The same shape, rows
p + n_p*iy.
- solprop.backends.spatial.slab_synthesis(transform, columns)[source]#
Synthesise a planar state’s field at the
(x, y)nodes.The inverse DFT in y, then the slab synthesis in x – the two commute, and this order transforms the smaller axis first. The synthesis carries the temporal pad scale, so the result is the field the response pass needs on the fine grid.
- Parameters:
- transformsolprop.translate.modal.Transform
A transform with
"slab"geometry.- columnsnumpy.ndarray
Spectra with the
n_p * n_ycolumns first.
- Returns:
- numpy.ndarray
Spectra at the nodes
ix + n_x*iy, shape(n_x*n_y, ...).