treams_rs.advect¶
Advect adapter: physics objects and records differentiated by Advect, on the CPU and in first-order forward and reverse mode. Derivative directions reuse the data stored by their forward invocation; a new optimization step records the new inputs. Inputs may be float64, complex128, float32 or complex64; the Rust code computes in double precision, outputs are float64 or complex128, and each gradient has the dtype of its input.
Framework inputs select Advect through the ordinary API:
import advect as ad
import advect.numpy as np
import treams_rs as tr
def objective(radius):
sphere = tr.sphere_tmatrix(k0=2.0, lmax=2, radius=radius, material=3.0)
wave = tr.plane_wave([0, 0, 1], "positive_helicity", k0=2.0)
return sphere.cross_sections(wave).scattering
value, gradient = ad.value_and_grad(objective)(np.asarray(0.2))
The Rust core computes each gradient analytically with a pullback: a map from
the gradient with respect to an output to the gradients with respect to the
inputs. treams_rs.diff defines records, contexts and pullbacks.
Install treams-rs[advect]. Higher derivatives, staging and
checkpointing are not available. Mode cutoffs, integer labels and topology are
static. Pass inputs as arrays (scalars as np.asarray(x)) and keep traced
values inside Advect: converting them to float or NumPy loses derivatives.
Advect 0.3.1 or later reuses the native context from the forward invocation,
including its factorizations, for every direction on a linear map.
Plain Python and NumPy inputs retain NumPy behavior; constant physics objects
are promoted when combined with Advect values. Use this explicit namespace
when constants alone should produce Advect objects, or for its record helpers.
Advect has no public wrap. Run a custom record through
treams_rs.jax.wrap, treams_rs.torch.wrap or
treams_rs.autograd.wrap, or compose the expert functions here.
Framework adapters guide: https://yaugenst.github.io/treams-rs/latest/differentiation/frameworks/
BandModes¶
Bloch wavenumbers along the basis normal and matching right eigenvectors.
Units: wavenumbers in inverse length, the unit of k0; eigenvectors
dimensionless, with eigenvectors[:, i] the mode of wavenumbers[i].
Fields are complex NumPy arrays for SMatrix.bands, and framework arrays in
advect, jax and torch.
BandModes.wavenumbers¶
BandModes.wavenumbers: T
BandModes.eigenvectors¶
BandModes.eigenvectors: T
Cluster¶
Particles at framework-valued positions, before their interaction is solved.
Build it as Cluster(particles, *, positions). particles is a
sequence of TMatrix objects in global bases of one wave family, with one
polarization convention, k0 and medium. positions holds one Cartesian
position per particle, shape (particles, 3), and may carry gradients.
The cluster basis labels each mode with its particle index; its
basis.positions are zero placeholders, and positions holds the
centres.
Cluster.solve¶
Cluster.solve() -> TMatrix
The T-matrix of the coupled particles, for any illumination.
Cluster.scatter¶
Cluster.scatter(incident: PlaneWave | Wave) -> Wave
The scattered wave of one illumination, without the full coupled T-matrix.
Cluster.factor¶
Cluster.factor() -> _ClusterFactor
Prepare coupling and particle blocks for repeated illumination solves.
Framework inputs retain their derivatives. Each scatter call records its native factorization; only constant NumPy clusters retain LU factors.
CrossSections¶
Scattering and extinction cross sections; absorption is their difference.
Units: areas (length squared) from TMatrix and widths (length) from CylindricalTMatrix, in the length unit of 1/k0. Fields are floats for TMatrix and CylindricalTMatrix, and framework arrays in advect, jax and torch.
CrossSections.absorption¶
CrossSections.absorption: T
Extinguished power minus scattered power, with the same normalization.
CrossSections.scattering¶
CrossSections.scattering: T
CrossSections.extinction¶
CrossSections.extinction: T
CylindricalBasis¶
Ordered modes (pidx, kz, m, pol) around parallel z-directed axes.
Mirrors treams.CylindricalWaveBasis. Rows (kz, m, pol) imply
pidx=0. kz is a finite real axial wavenumber in inverse length units,
|m| <= 128 and pol is 0 or 1. The axis positions have shape (particles, 3)
in the matching length unit. Exact duplicate modes are removed in order.
The wave or operator that uses the basis sets the polarization convention:
helicity labels 0/1 mean negative/positive, parity labels
magnetic/electric.
CylindricalBasis.index¶
CylindricalBasis.index(mode: CylindricalMode, start: int=0, stop: int | None=None) -> int
Index of mode, like tuple.index; ValueError when it is absent.
CylindricalBasis.count¶
CylindricalBasis.count(mode: CylindricalMode) -> int
Number of times mode occurs: 0 or 1, because modes are distinct.
CylindricalBasis.isdisjoint¶
CylindricalBasis.isdisjoint(other: CylindricalBasis) -> bool
Whether the bases share no mode; both need one family and geometry.
CylindricalBasis.lattice¶
CylindricalBasis.lattice: Lattice | None = None
Lattice of a periodic arrangement, or None.
CylindricalBasis.kpar¶
CylindricalBasis.kpar: WaveVector | None = None
Bloch vector of a periodic arrangement, or None.
CylindricalBasis.modes¶
CylindricalBasis.modes: tuple[CylindricalMode, ...]
The mode labels, in order.
CylindricalBasis.__init__¶
CylindricalBasis(modes: Iterable[Sequence[float]], positions: ArrayLike=((0, 0, 0),))
CylindricalBasis.pidx¶
CylindricalBasis.pidx: NDArray[np.int64]
Particle index of each mode, shape (modes,).
A read-only column cached per basis, like pol; call .copy() to
edit it.
CylindricalBasis.m¶
CylindricalBasis.m: NDArray[np.int64]
Azimuthal order of each mode, shape (modes,).
A read-only column cached per basis, like pol; call .copy() to
edit it.
CylindricalBasis.pol¶
CylindricalBasis.pol: NDArray[np.int64]
Label pol (0 or 1) of each mode, shape (modes,); read-only and cached.
CylindricalBasis.isglobal¶
CylindricalBasis.isglobal: bool
Whether every mode has the same particle index.
CylindricalBasis.defaultdim¶
CylindricalBasis.defaultdim(nkz: int, mmax: int, nmax: int=1) -> int
Return 2*nkz*(2*mmax+1)*nmax channels for distinct axial labels.
CylindricalBasis.defaultmmax¶
CylindricalBasis.defaultmmax(dim: int, nkz: int=1, nmax: int=1) -> int
Invert defaultdim for positive nkz/nmax; reject incomplete mode sets.
CylindricalBasis.default¶
CylindricalBasis.default(kzs: ArrayLike, mmax: int, nmax: int=1, positions: ArrayLike | None=None) -> CylindricalBasis
Create pol 0 and 1 of orders -mmax..mmax for each axial label.
Kzs is a scalar or one-dimensional real wavenumber array. Order is particle, kz in input order, m, then pol=(1, 0); duplicate labels are removed. Require 0 <= mmax <= 128 and nmax >= 1. Positions have shape (nmax, 3), defaulting to zeros, in the length unit inverse to kzs.
CylindricalBasis.diffr_orders¶
CylindricalBasis.diffr_orders(kz: float, mmax: int, lattice: float | Lattice, bmax: float, nmax: int=1, positions: ArrayLike | None=None) -> CylindricalBasis
Modes at the axial diffraction orders of a chain with period along z.
Mirrors treams.CylindricalWaveBasis.diffr_orders. The axial
wavenumbers are kz + 2 pi j / period for every integer j with
|2 pi j / period| <= bmax, each with orders -mmax..mmax and both pol,
ordered as in default. lattice is the period or a 1D Lattice. The
basis keeps the lattice and the Bloch vector kz.
CylindricalBasis.kz¶
CylindricalBasis.kz: NDArray[np.float64]
Axial wavenumber label of each mode, shape (modes,).
A read-only column cached per basis, like pol; call .copy() to
edit it.
CylindricalBasis.zms¶
CylindricalBasis.zms: tuple[NDArray[np.float64], NDArray[np.int64], NDArray[np.int64]]
The columns (kz, m, pol), as treams' zms.
Lattice¶
Lattice vectors as rows, along named Cartesian axes.
Mirrors treams.Lattice. The array is a scalar period (1D), the
diagonal of 2 or 3 lengths, or a square 2x2 or 3x3 matrix of row vectors.
alignment names the Cartesian axes of the rows: "z" (default),
"x" or "y" in 1D; "xy" (default), "yz" or "zx" in 2D;
"xyz" in 3D. Lattice(lattice, "xy") selects the sublattice of a 3D
lattice along x and y. The Rust core computes the volume and the reciprocal
vectors.
Lattice.__init__¶
Lattice(arr: ArrayLike | Lattice, alignment: str | None=None)
Lattice.dim¶
Lattice.dim: int
Number of lattice dimensions, 1 to 3.
Lattice.volume¶
Lattice.volume: float
Signed pitch, area or volume.
Lattice.reciprocal¶
Lattice.reciprocal: NDArray[np.float64]
Reciprocal row vectors satisfying a @ b.T = 2 pi I.
Lattice.square¶
Lattice.square(pitch: float, alignment: str | None=None) -> Lattice
Square lattice with side pitch.
Args
pitch: Lattice constant.alignment: Plane of the lattice:"xy"(default),"yz"or"zx". The rows lie along its first and second axis.
Lattice.cubic¶
Lattice.cubic(pitch: float, alignment: str | None=None) -> Lattice
Cubic lattice with side pitch; the alignment can only be "xyz".
Lattice.rectangular¶
Lattice.rectangular(x: float, y: float, alignment: str | None=None) -> Lattice
Rectangular lattice with sides x and y.
Args
x: Length along the first axis of the alignment.y: Length along the second axis of the alignment.alignment: Plane of the lattice:"xy"(default),"yz"or"zx". The rows lie along its first and second axis.
Lattice.orthorhombic¶
Lattice.orthorhombic(x: float, y: float, z: float, alignment: str | None=None) -> Lattice
Orthorhombic lattice with sides x, y and z.
The alignment can only be "xyz".
Lattice.hexagonal¶
Lattice.hexagonal(pitch: float, height: float | None=None, alignment: str | None=None) -> Lattice
Hexagonal lattice with side pitch, 2D or, with height, 3D.
The rows are (pitch, 0) and (pitch/2, sqrt(3) pitch/2) in the plane of
the alignment. height adds the row (0, 0, height) and needs the
alignment "xyz".
Args
pitch: Lattice constant in the plane.height: Period along the third axis; None for a 2D lattice.alignment: Plane of a 2D lattice:"xy"(default),"yz"or"zx".
Lattice.permute¶
Lattice.permute(n: int=1) -> Lattice
Permute the axes cyclically, x -> y -> z, n times.
Lattice.rotate¶
Lattice.rotate(phi: float) -> Lattice
Rotate around z; the resulting span must remain Cartesian aligned.
Lattice.isdisjoint¶
Lattice.isdisjoint(other: Lattice) -> bool
Whether the two lattices share no Cartesian axis.
Lattice.alignment¶
Lattice.alignment: str
Cartesian axes of the rows, for example "xy".
Material¶
Isotropic reciprocal material with relative epsilon, mu and chirality kappa.
Mirrors treams.Material. All three parameters are dimensionless complex
scalars. A single scalar specifies epsilon with mu=1 and kappa=0; a
tuple/list specifies (epsilon, mu, kappa), with omitted trailing values
taking those defaults. Passing another Material copies its three values.
Instances are immutable. Call or iterate the object to get the parameters
in that order.
Material.__init__¶
Material(epsilon: Any=1, mu: Any=1, kappa: Any=0)
Material.from_refractive_index¶
Material.from_refractive_index(n: complex=1, impedance: complex | None=None, kappa: complex=0) -> Material
Construct epsilon=n/impedance and mu=n*impedance.
n is the mean refractive index and impedance is relative to vacuum.
Omitting impedance uses 1/n, giving mu=1. Kappa stays dimensionless.
Material.from_helicity_indices¶
Material.from_helicity_indices(ns: tuple[complex, complex]=(1, 1), impedance: complex | None=None) -> Material
Construct from negative/positive-helicity indices (n_minus, n_plus).
Their mean gives n and half their difference gives kappa. Omitting
impedance uses the same nonmagnetic convention as from_refractive_index.
Material.n¶
Material.n: complex
Square root of epsilon*mu, with sign chosen for nonnegative imaginary part.
Material.nmp¶
Material.nmp: NDArray[np.complex128]
Shape-(2,) complex128 refractive indices for the labels pol 0 and 1.
Start from the principal square root of epsilon*mu minus/plus kappa, then choose each sign for a nonnegative imaginary part. Array order is negative/positive helicity; default mode bases instead list label 1 first.
Material.impedance¶
Material.impedance: complex
Principal square root of mu/epsilon, relative to vacuum impedance.
Material.isreal¶
Material.isreal: bool
Whether epsilon, mu and kappa are all real, as for a lossless medium.
Material.ischiral¶
Material.ischiral: bool
Whether the chirality kappa is nonzero; parity channels need it zero.
Material.ks¶
Material.ks(k0: float) -> NDArray[np.complex128]
Return k0 * nmp in negative/positive-helicity order, shape (2,).
The vacuum angular wavenumber k0 is 2*pi/wavelength, in inverse units of the lengths used elsewhere in the simulation.
Material.kzs¶
Material.kzs(k0: float, kx: ArrayLike, ky: ArrayLike, pol: ArrayLike=(0, 1)) -> NDArray[np.complex128]
Axial wavevectors on the outgoing branch (nonnegative imaginary part).
Material.krhos¶
Material.krhos(k0: float, kz: ArrayLike, pol: ArrayLike=(0, 1)) -> NDArray[np.complex128]
Radial wavevectors on the same outgoing branch as kzs.
Material.epsilon¶
Material.epsilon: Any
Relative permittivity.
Material.mu¶
Material.mu: Any
Relative permeability.
Material.kappa¶
Material.kappa: Any
Chirality parameter, dimensionless.
PeriodicResponse¶
Solved response of a periodic array, ready for conversion to plane-wave ports.
solve_periodic returns it. response is the TMatrix of one unit
cell with the lattice interaction solved; lattice and kpar are
framework arrays and carry gradients.
PeriodicResponse.array¶
PeriodicResponse.array: Any
Solved response in local multipole channels.
PeriodicResponse.basis¶
PeriodicResponse.basis: Basis
Local multipole labels of the periodic response.
PeriodicResponse.k0¶
PeriodicResponse.k0: Any
Vacuum wavenumber.
PeriodicResponse.medium¶
PeriodicResponse.medium: Material
Embedding material.
PeriodicResponse.polarization¶
PeriodicResponse.polarization: str
Polarization convention.
PeriodicResponse.scatter¶
PeriodicResponse.scatter(incident: Any) -> PeriodicWave
Scatter an illumination whose plane-wave orders match this Bloch vector.
PeriodicResponse.to_cylindrical¶
PeriodicResponse.to_cylindrical(basis: CylindricalBasis) -> TMatrix
Represent a spherical z-periodic response in outgoing cylindrical modes.
PeriodicResponse.to_smatrix¶
PeriodicResponse.to_smatrix(basis: PlaneWavePorts | None=None, *, diffraction_orders: Any=None, orders: Any=None) -> SMatrix
Convert to fixed ports or integer diffraction orders following cell/Bloch changes.
Spherical orders have shape (groups,2); cylindrical orders are a vector
for one fixed axial sector. Order ports include both helicities (1,0).
The returned transverse_wavevectors retain framework derivatives.
orders is an alias of diffraction_orders.
PlaneWave¶
Plane wave with real direction and helicity or parity amplitudes.
Direction, amplitudes, k0 and medium may carry gradients. Fixed directions support incidence along a polarization axis; direction derivatives require off-axis incidence, where the native polarization gauge is differentiable.
PlaneWave.array¶
PlaneWave.array: Any
The framework-valued wave coefficients.
PlaneWave.material¶
PlaneWave.material: Material
treams name of medium.
PlaneWave.poltype¶
PlaneWave.poltype: str
treams name of polarization.
PlaneWave.efield¶
PlaneWave.efield(points: Any=None, *, r: Any=None) -> Any
Electric field at points (..., 3), differentiable in points and wave values.
PlaneWave.hfield¶
PlaneWave.hfield(points: Any=None, *, r: Any=None) -> Any
Magnetic field in relative vacuum impedance units.
PlaneWave.dfield¶
PlaneWave.dfield(points: Any=None, *, r: Any=None) -> Any
Electric displacement divided by vacuum permittivity.
PlaneWave.bfield¶
PlaneWave.bfield(points: Any=None, *, r: Any=None) -> Any
Magnetic flux density times vacuum light speed.
PlaneWave.gfield¶
PlaneWave.gfield(pol: int, points: Any=None, *, r: Any=None) -> Any
Helicity-resolved G field, normalized as in treams for this wave family.
PlaneWave.ffield¶
PlaneWave.ffield(pol: int, points: Any=None, *, r: Any=None) -> Any
G field with the chiral index weighting in the helicity convention.
PlaneWave.medium¶
PlaneWave.medium: Material
Medium in which the wave travels.
PlaneWave.polarization¶
PlaneWave.polarization: str
Polarization convention, "helicity" or "parity".
PlaneWave.coefficients¶
PlaneWave.coefficients: Any
PlaneWave.with_polarization¶
PlaneWave.with_polarization(polarization: str) -> PlaneWave
Represent the same plane wave with helicity or parity amplitudes.
PlaneWave.in_basis¶
PlaneWave.in_basis(basis: Basis, *, positions: Any=None, singular: bool | None=None) -> Wave
Expand into regular multipole waves of basis at positions.
positions defaults to basis.positions; singular=True
raises ValueError.
PlaneWave.kind¶
PlaneWave.kind = 'up'
Directional plane-wave kind in the treams convention.
PlaneWave.modetype¶
PlaneWave.modetype = 'up'
Same as PlaneWave.kind.
Directional plane-wave kind in the treams convention.
PlaneWaveBasis¶
Ordered plane modes (qx, qy, qz, pol) with complex unit directions.
Mirrors treams.PlaneWaveBasisByUnitVector. Directions are normalized by
the algebraic norm sqrt(q.q), without complex conjugation; zero or null
directions are invalid. Labels pol are 0 or 1; the wave or operator that
uses the basis sets the polarization convention. The basis stores
directions, not wavevectors; kvecs scales them with k0 and the medium.
Exact duplicate rows are removed in order.
PlaneWaveBasis.index¶
PlaneWaveBasis.index(mode: tuple[complex, complex, complex, int], start: int=0, stop: int | None=None) -> int
Index of mode, like tuple.index; ValueError when it is absent.
PlaneWaveBasis.count¶
PlaneWaveBasis.count(mode: tuple[complex, complex, complex, int]) -> int
Number of times mode occurs: 0 or 1, because modes are distinct.
PlaneWaveBasis.isdisjoint¶
PlaneWaveBasis.isdisjoint(other: PlaneWaveBasis) -> bool
Whether the bases share no mode; both need one family and geometry.
PlaneWaveBasis.lattice¶
PlaneWaveBasis.lattice: Lattice | None = None
Lattice of a periodic arrangement, or None.
PlaneWaveBasis.kpar¶
PlaneWaveBasis.kpar: WaveVector | None = None
Bloch vector of a periodic arrangement, or None.
PlaneWaveBasis.modes¶
PlaneWaveBasis.modes: tuple[tuple[complex, complex, complex, int], ...]
The mode labels, in order.
PlaneWaveBasis.__init__¶
PlaneWaveBasis(modes: Iterable[Sequence[complex]])
PlaneWaveBasis.qx¶
PlaneWaveBasis.qx: NDArray[np.complex128]
x component of each unit direction, shape (modes,).
PlaneWaveBasis.qy¶
PlaneWaveBasis.qy: NDArray[np.complex128]
y component of each unit direction, shape (modes,).
PlaneWaveBasis.qz¶
PlaneWaveBasis.qz: NDArray[np.complex128]
z component of each unit direction, shape (modes,).
PlaneWaveBasis.pol¶
PlaneWaveBasis.pol: NDArray[np.int64]
Label pol (0 or 1) of each mode, shape (modes,); read-only and cached.
PlaneWaveBasis.default¶
PlaneWaveBasis.default(kvecs: ArrayLike) -> PlaneWaveBasis
Normalize shape-(n, 3) directions and include pol 0 and 1.
A single shape-(3,) vector is accepted. Each direction contributes labels (1, 0), in that order. Complex directions allow evanescent waves.
PlaneWaveBasis.kvecs¶
PlaneWaveBasis.kvecs(k0: float, material: MaterialLike=1, modetype: str | None=None) -> tuple[NDArray[np.complex128], NDArray[np.complex128], NDArray[np.complex128]]
Return (kx, ky, kz), each shape (modes,), in inverse length units.
Each direction is scaled by its medium wavenumber at the vacuum angular
wavenumber k0. The direction fixes the propagation, so modetype has no
effect; it is accepted for a signature shared with PlaneWavePorts.kvecs.
PlaneWaveBasis.rotate¶
PlaneWaveBasis.rotate(phi: float) -> PlaneWaveBasis
Rotate direction labels around z, preserving their pol labels.
Quarter turns are exact, matching the rotated lattice metadata.
PlaneWaveBasis.permute¶
PlaneWaveBasis.permute(n: int=1) -> PlaneWaveBasis
Permute the direction components cyclically, x -> y -> z, n times.
Labels pol stay; lattice and Bloch vector permute along.
PlaneWaveBasis.bycomp¶
PlaneWaveBasis.bycomp(k0: float, alignment: str='xy', material: MaterialLike=1) -> PlaneWavePorts
The same modes as PlaneWavePorts, which store two wavevector components.
Mirrors treams.PlaneWaveBasisByUnitVector.bycomp. The components named
by alignment ("xy", "yz" or "zx") of every wavevector at
k0 in material must be real.
PlaneWaveBasis.isglobal¶
PlaneWaveBasis.isglobal = True
Always True: plane waves have no expansion positions.
PlaneWavePorts¶
Ordered plane modes (k1, k2, pol) storing two real wavevector components.
Mirrors treams.PlaneWaveBasisByComp. The alignment "xy", "yz"
or "zx" names the stored Cartesian components (k1, k2), in inverse
length units. Labels pol are 0 or 1; the wave or operator that uses the
basis sets the polarization convention. kvecs adds the third component
from k0, the medium and the direction up or down, including evanescent
waves. Exact duplicate modes are removed in order.
PlaneWavePorts.index¶
PlaneWavePorts.index(mode: tuple[float, float, int], start: int=0, stop: int | None=None) -> int
Index of mode, like tuple.index; ValueError when it is absent.
PlaneWavePorts.count¶
PlaneWavePorts.count(mode: tuple[float, float, int]) -> int
Number of times mode occurs: 0 or 1, because modes are distinct.
PlaneWavePorts.isdisjoint¶
PlaneWavePorts.isdisjoint(other: PlaneWavePorts) -> bool
Whether the bases share no mode; both need one family and geometry.
PlaneWavePorts.lattice¶
PlaneWavePorts.lattice: Lattice | None = None
Lattice of a periodic arrangement, or None.
PlaneWavePorts.kpar¶
PlaneWavePorts.kpar: WaveVector | None = None
Bloch vector of a periodic arrangement, or None.
PlaneWavePorts.modes¶
PlaneWavePorts.modes: tuple[tuple[float, float, int], ...]
The mode labels, in order.
PlaneWavePorts.__init__¶
PlaneWavePorts(modes: Iterable[Sequence[float]], alignment: str='xy')
PlaneWavePorts.default¶
PlaneWavePorts.default(kpars: ArrayLike, alignment: str='xy') -> PlaneWavePorts
Include labels (1, 0) for each shape-(n, 2) transverse wavevector.
A single shape-(2,) pair is accepted. Components are real and dimensional, in the Cartesian order specified by alignment (xy, yz or zx).
PlaneWavePorts.diffr_orders¶
PlaneWavePorts.diffr_orders(kpar: ArrayLike, lattice: ArrayLike, bmax: float, *, alignment: str | None=None) -> PlaneWavePorts
Pol 0 and 1 of all reciprocal vectors with length <= bmax.
The cutoff applies before adding the Bloch vector. Opposite diffraction orders are adjacent, following treams ordering for rectangular lattices.
PlaneWavePorts.normal_axis¶
PlaneWavePorts.normal_axis: int
Cartesian axis normal to the stored component plane.
PlaneWavePorts.components¶
PlaneWavePorts.components: NDArray[np.float64]
The two real stored components, in alignment order.
PlaneWavePorts.kx¶
PlaneWavePorts.kx: NDArray[np.float64] | None
x component of each wavevector, shape (modes,); None if not stored.
PlaneWavePorts.ky¶
PlaneWavePorts.ky: NDArray[np.float64] | None
y component of each wavevector, shape (modes,); None if not stored.
PlaneWavePorts.kz¶
PlaneWavePorts.kz: NDArray[np.float64] | None
z component of each wavevector, shape (modes,); None if not stored.
PlaneWavePorts.rotate¶
PlaneWavePorts.rotate(phi: float) -> PlaneWavePorts
Rotate xy direction labels around z, preserving their pol labels.
Quarter turns are exact, matching the rotated lattice metadata.
PlaneWavePorts.permute¶
PlaneWavePorts.permute(n: int=1) -> PlaneWavePorts
Permute the alignment cyclically, xy -> yz -> zx, n times.
The stored components and labels pol stay; lattice and Bloch vector permute along.
PlaneWavePorts.pol¶
PlaneWavePorts.pol: NDArray[np.int64]
Label pol (0 or 1) of each mode, shape (modes,); read-only and cached.
PlaneWavePorts.kvecs¶
PlaneWavePorts.kvecs(k0: float, material: MaterialLike=1, modetype: str='up') -> tuple[NDArray[np.complex128], NDArray[np.complex128], NDArray[np.complex128]]
Return (kx, ky, kz), each shape (modes,), at vacuum wavenumber k0.
The missing normal component uses the medium's outgoing square-root
branch. modetype='down' reverses that component; 'up' keeps it.
Stored transverse components remain unchanged, in inverse length units.
PlaneWavePorts.byunitvector¶
PlaneWavePorts.byunitvector(k0: float, material: MaterialLike=1, modetype: str='up') -> PlaneWaveBasis
The same modes as a PlaneWaveBasis of unit directions.
Mirrors treams.PlaneWaveBasisByComp.byunitvector. The third component
comes from k0, material and modetype ("up" or "down"), as
in kvecs.
PlaneWavePorts.isglobal¶
PlaneWavePorts.isglobal = True
Always True: plane waves have no expansion positions.
PortWave¶
Plane-wave amplitudes on the ports of one side of an S-matrix.
SMatrix.scatter returns two in a ScatteredPorts. positive is True
for the wave on the positive side, which travels along the positive
normal. The amplitudes, k0, the exterior medium and the transverse
wavevectors of diffraction-order ports may carry gradients.
PortWave.basis¶
PortWave.basis: PlaneWavePorts | None
Fixed port basis, or None for ports following diffraction orders.
PortWave.modes¶
PortWave.modes: tuple[tuple[int, int], ...]
(group, pol) label of each port.
PortWave.transverse_wavevectors¶
PortWave.transverse_wavevectors: Any
In-plane wavevector components, one row per port group.
PortWave.ports¶
PortWave.ports: PortSet
Plane-wave ports, shared with the S-matrix.
PortWave.array¶
PortWave.array: Any
The framework-valued wave coefficients.
PortWave.material¶
PortWave.material: Material
treams name of medium.
PortWave.poltype¶
PortWave.poltype: str
treams name of polarization.
PortWave.efield¶
PortWave.efield(points: Any=None, *, r: Any=None) -> Any
Electric field at points (..., 3), differentiable in points and wave values.
PortWave.hfield¶
PortWave.hfield(points: Any=None, *, r: Any=None) -> Any
Magnetic field in relative vacuum impedance units.
PortWave.dfield¶
PortWave.dfield(points: Any=None, *, r: Any=None) -> Any
Electric displacement divided by vacuum permittivity.
PortWave.bfield¶
PortWave.bfield(points: Any=None, *, r: Any=None) -> Any
Magnetic flux density times vacuum light speed.
PortWave.gfield¶
PortWave.gfield(pol: int, points: Any=None, *, r: Any=None) -> Any
Helicity-resolved G field, normalized as in treams for this wave family.
PortWave.ffield¶
PortWave.ffield(pol: int, points: Any=None, *, r: Any=None) -> Any
G field with the chiral index weighting in the helicity convention.
PortWave.medium¶
PortWave.medium: Material
Medium in which the wave travels.
PortWave.polarization¶
PortWave.polarization: str
Polarization convention, "helicity" or "parity".
PortWave.coefficients¶
PortWave.coefficients: Any
One amplitude per port, a framework array.
PortWave.kind¶
PortWave.kind: str
Propagation direction along the port normal.
PortWave.modetype¶
PortWave.modetype: str
treams name of kind.
PortWave.in_basis¶
PortWave.in_basis(basis: Basis, *, positions: Any=None, singular: bool | None=None, kind: str | None=None) -> Wave
Expand port amplitudes into regular multipoles, retaining their phases.
PortWave.with_polarization¶
PortWave.with_polarization(polarization: str) -> PortWave
Change the polarization convention with a fixed basis matrix.
PortWave.k0¶
PortWave.k0: Any
Vacuum wavenumber.
PortWave.positive¶
PortWave.positive: bool
True on the positive side of the S-matrix, False on the negative side.
PowerBalance¶
Transmitted and reflected power as fractions of the incident power.
Units: none; a lossless network gives transmission + reflection = 1. Fields are floats for SMatrix.power, and framework arrays in advect, jax and torch.
PowerBalance.absorption¶
PowerBalance.absorption: T
Fraction not carried by transmitted or reflected power.
PowerBalance.transmission¶
PowerBalance.transmission: T
PowerBalance.reflection¶
PowerBalance.reflection: T
SMatrix¶
S-matrix of framework arrays: the four blocks of a planar system.
The constructors smatrix, interface, slab, multilayer_slab,
propagation and stack of advect, jax and torch build it, and
cascade and PeriodicResponse.to_smatrix return one. The ports and
the polarization convention are fixed; the blocks, k0 and the media may
carry gradients.
SMatrix.basis¶
SMatrix.basis: PlaneWavePorts | None
Fixed port basis, or None for ports following diffraction orders.
SMatrix.modes¶
SMatrix.modes: tuple[tuple[int, int], ...]
(group, pol) label of each port.
SMatrix.transverse_wavevectors¶
SMatrix.transverse_wavevectors: Any
In-plane wavevector components, one row per port group.
SMatrix.ports¶
SMatrix.ports: PortSet
Plane-wave ports of both sides.
SMatrix.negative_medium¶
SMatrix.negative_medium: Material
Exterior on the negative side of the plane normal.
SMatrix.positive_medium¶
SMatrix.positive_medium: Material
Exterior on the positive side of the plane normal.
SMatrix.with_polarization¶
SMatrix.with_polarization(polarization: str) -> SMatrix
Convert the port polarization convention using a static basis matrix.
SMatrix.scatter¶
SMatrix.scatter(*, negative: Any=None, positive: Any=None) -> ScatteredPorts[PortWave]
Scatter one coherent illumination supplied on either or both sides.
SMatrix.power¶
SMatrix.power(incident: Any, *, side: str | None=None) -> PowerBalance[Any]
Transmission/reflection for port amplitudes; fixed port wavevectors.
SMatrix.cascade¶
SMatrix.cascade(next_layer: SMatrix) -> SMatrix
Compose adjacent systems whose port wavevectors have the same dependence.
Fixed basis ports cannot be mixed with diffraction-order ports: matching their current wavevectors does not match their derivatives. Use a fixed basis for both systems, or diffraction orders for both.
SMatrix.bands¶
SMatrix.bands(period: Any) -> BandModes[Any]
Principal-branch normal Bloch wavenumbers and right vectors.
SMatrix.array¶
SMatrix.array: Any
Blocks of shape (2, 2, ports, ports); index 0 is the positive side.
SMatrix.k0¶
SMatrix.k0: Any
Vacuum wavenumber.
SMatrix.polarization¶
SMatrix.polarization: str
Polarization convention, "helicity" or "parity".
ScatteredPorts¶
Outgoing waves on the positive and negative side of the stack normal.
Units: plane-wave amplitudes in the normalization of the incident wave. Fields are Wave objects for SMatrix.scatter, and PortWave objects in advect, jax and torch.
ScatteredPorts.positive¶
ScatteredPorts.positive: W
ScatteredPorts.negative¶
ScatteredPorts.negative: W
SphericalBasis¶
Ordered modes (pidx, l, m, pol) and Cartesian expansion positions.
Mirrors treams.SphericalWaveBasis. Rows (l, m, pol) imply pidx=0.
Positions have shape (particles, 3) in the simulation's length unit; a
shape-(3,) position is also accepted. Require 1 <= l <= 128, -l <= m <= l
and pol in {0, 1}. Exact duplicate modes are removed in order. The wave or
operator that uses the basis sets the polarization convention: helicity
labels 0/1 mean negative/positive, parity labels magnetic/electric.
Selecting modes keeps the positions.
SphericalBasis.index¶
SphericalBasis.index(mode: SphericalMode, start: int=0, stop: int | None=None) -> int
Index of mode, like tuple.index; ValueError when it is absent.
SphericalBasis.count¶
SphericalBasis.count(mode: SphericalMode) -> int
Number of times mode occurs: 0 or 1, because modes are distinct.
SphericalBasis.isdisjoint¶
SphericalBasis.isdisjoint(other: SphericalBasis) -> bool
Whether the bases share no mode; both need one family and geometry.
SphericalBasis.lattice¶
SphericalBasis.lattice: Lattice | None = None
Lattice of a periodic arrangement, or None.
SphericalBasis.kpar¶
SphericalBasis.kpar: WaveVector | None = None
Bloch vector of a periodic arrangement, or None.
SphericalBasis.modes¶
SphericalBasis.modes: tuple[SphericalMode, ...]
The mode labels, in order.
SphericalBasis.__init__¶
SphericalBasis(modes: Iterable[Sequence[float]], positions: ArrayLike=((0, 0, 0),))
SphericalBasis.pidx¶
SphericalBasis.pidx: NDArray[np.int64]
Particle index of each mode, shape (modes,).
A read-only column cached per basis, like pol; call .copy() to
edit it.
SphericalBasis.m¶
SphericalBasis.m: NDArray[np.int64]
Azimuthal order of each mode, shape (modes,).
A read-only column cached per basis, like pol; call .copy() to
edit it.
SphericalBasis.pol¶
SphericalBasis.pol: NDArray[np.int64]
Label pol (0 or 1) of each mode, shape (modes,); read-only and cached.
SphericalBasis.isglobal¶
SphericalBasis.isglobal: bool
Whether every mode has the same particle index.
SphericalBasis.defaultdim¶
SphericalBasis.defaultdim(lmax: int, nmax: int=1) -> int
Return 2*lmax*(lmax+2)*nmax channels for a complete default basis.
SphericalBasis.defaultlmax¶
SphericalBasis.defaultlmax(dim: int, nmax: int=1) -> int
Invert defaultdim; reject dimensions that omit part of a mode shell.
SphericalBasis.default¶
SphericalBasis.default(lmax: int, nmax: int=1, positions: ArrayLike | None=None) -> SphericalBasis
Create complete spherical mode shells at nmax expansion positions.
Order is particle, l=1..lmax, m=-l..l, then pol=(1, 0). The dimension is
2*lmax*(lmax+2)*nmax. Require 0 <= lmax <= 128 and nmax >= 1; lmax=0
makes an empty basis. Positions have shape (nmax, 3), defaulting to zeros,
and use the simulation's length unit.
SphericalBasis.ebcm¶
SphericalBasis.ebcm(lmax: int, nmax: int=1, mmax: int=-1, positions: ArrayLike | None=None) -> SphericalBasis
Complete mode shells in EBCM order: particle, then m, degree and pol=(1, 0).
Mirrors treams.SphericalWaveBasis.ebcm. Orders run over -mmax..mmax
and degrees over max(1, |m|)..lmax; mmax=-1 uses lmax. Require
0 <= mmax <= lmax <= 128 and nmax >= 1. Positions have shape (nmax, 3),
zeros by default.
SphericalBasis.l¶
SphericalBasis.l: NDArray[np.int64]
Degree of each mode, shape (modes,).
A read-only column cached per basis, like pol; call .copy() to
edit it.
SphericalBasis.lms¶
SphericalBasis.lms: tuple[NDArray[np.int64], NDArray[np.int64], NDArray[np.int64]]
The columns (l, m, pol), as treams' lms.
TMatrix¶
T-matrix of framework arrays: regular incident to singular scattered waves.
Singular waves are the outgoing ones. The constructors tmatrix,
sphere_tmatrix, multilayer_sphere_tmatrix, cylinder_tmatrix and
multilayer_cylinder_tmatrix of the adapters build it, and
Cluster.solve returns one; PeriodicResponse.response holds the
solved unit cell of solve_periodic. The basis labels are
fixed; the matrix, k0, the medium and the positions may carry gradients.
Every method uses positions and ignores basis.positions.
TMatrix.scatter¶
TMatrix.scatter(incident: PlaneWave | Wave) -> Wave
Scatter an incident wave; returns the singular (scattered) wave.
TMatrix.cross_sections¶
TMatrix.cross_sections(incident: PlaneWave | Wave, *, flux: Any=0.5) -> CrossSections[Any]
Named cross sections (area), or cylindrical widths (length).
The exterior must be nonabsorbing and propagating, and achiral for a
parity response. For a cylindrical response, cross_widths makes the
length units explicit.
TMatrix.cross_widths¶
TMatrix.cross_widths(incident: PlaneWave | Wave, *, flux: Any=0.5) -> CrossSections[Any]
Named cylindrical scattering/extinction/absorption widths in length units.
TMatrix.with_polarization¶
TMatrix.with_polarization(polarization: str) -> TMatrix
Convert the response convention with a fixed analytic basis transform.
TMatrix.shape¶
TMatrix.shape: tuple[int, ...]
Shape of the response matrix.
TMatrix.isglobal¶
TMatrix.isglobal: bool
Whether the response has one expansion centre.
TMatrix.ks¶
TMatrix.ks: Any
Embedding wavenumbers of the two helicities.
TMatrix.interaction¶
TMatrix.interaction: _Interaction
Finite multiple scattering within the local multipole basis.
TMatrix.latticeinteraction¶
TMatrix.latticeinteraction: _PeriodicInteraction
Periodic coupling, solve, factor and illuminate methods.
TMatrix.rotate¶
TMatrix.rotate(phi: Any, theta: Any=0, psi: Any=0) -> TMatrix
Rotate local multipole channels by differentiable z-y-z Euler angles.
TMatrix.translate¶
TMatrix.translate(r: Any) -> TMatrix
Represent the response about expansion centres shifted by r.
TMatrix.in_basis¶
TMatrix.in_basis(basis: Basis) -> TMatrix
Represent this response in another fixed multipole basis.
TMatrix.average_cross_sections¶
TMatrix.average_cross_sections: CrossSections[Any]
Rotationally and polarization-averaged spherical cross sections.
TMatrix.average_cross_widths¶
TMatrix.average_cross_widths: CrossSections[Any]
Cylindrical mean over azimuth and propagating axial/polarization channels.
TMatrix.circular_dichroism¶
TMatrix.circular_dichroism: Any
Absorption contrast between the two helicities.
TMatrix.duality_breaking¶
TMatrix.duality_breaking: Any
Fraction of the scattering norm that changes helicity.
TMatrix.electromagnetic_chirality¶
TMatrix.electromagnetic_chirality: Any
Normalized electromagnetic chirality from helicity-block singular values.
TMatrix.material¶
TMatrix.material: Material
Upstream name of the embedding medium.
TMatrix.poltype¶
TMatrix.poltype: str
Upstream name of the polarization convention.
TMatrix.xs_ext_avg¶
TMatrix.xs_ext_avg: Any
Upstream name of the mean extinction cross section.
TMatrix.xs_sca_avg¶
TMatrix.xs_sca_avg: Any
Upstream name of the mean scattering cross section.
TMatrix.xw_ext_avg¶
TMatrix.xw_ext_avg: Any
Upstream name of the mean extinction cross width.
TMatrix.xw_sca_avg¶
TMatrix.xw_sca_avg: Any
Upstream name of the mean scattering cross width.
TMatrix.xs¶
TMatrix.xs(illu: Any, flux: Any=0.5) -> tuple[Any, Any]
Upstream cross sections as (scattering, extinction).
TMatrix.xw¶
TMatrix.xw(illu: Any, flux: Any=0.5) -> tuple[Any, Any]
Upstream cross widths as (scattering, extinction).
TMatrix.changepoltype¶
TMatrix.changepoltype(poltype: str | None=None) -> TMatrix
Change polarization convention, defaulting to the other convention.
TMatrix.array¶
TMatrix.array: Any
Matrix of shape (modes, modes), a framework array.
TMatrix.basis¶
TMatrix.basis: Basis
Fixed mode labels of the rows and columns.
TMatrix.k0¶
TMatrix.k0: Any
Vacuum wavenumber.
TMatrix.medium¶
TMatrix.medium: Material
Embedding medium.
TMatrix.polarization¶
TMatrix.polarization: str
Polarization convention, "helicity" or "parity".
TMatrix.positions¶
TMatrix.positions: Any
Expansion centres, shape (positions, 3), a framework array.
TMatrix.cd¶
TMatrix.cd() -> Any
Same as TMatrix.circular_dichroism.
Absorption contrast between the two helicities.
TMatrix.db¶
TMatrix.db() -> Any
Same as TMatrix.duality_breaking.
Fraction of the scattering norm that changes helicity.
TMatrix.chi¶
TMatrix.chi() -> Any
Same as TMatrix.electromagnetic_chirality.
Normalized electromagnetic chirality from helicity-block singular values.
Wave¶
Multipole wave of framework arrays: coefficients with basis, medium and kind.
The constructor wave of advect, jax and torch builds it, and
TMatrix.scatter, Cluster.scatter and in_basis return one. The
basis labels and the kind are fixed; the coefficients, k0, the medium and
the positions may carry gradients. Every method uses positions and
ignores basis.positions.
Wave.array¶
Wave.array: Any
The framework-valued wave coefficients.
Wave.material¶
Wave.material: Material
treams name of medium.
Wave.poltype¶
Wave.poltype: str
treams name of polarization.
Wave.efield¶
Wave.efield(points: Any=None, *, r: Any=None) -> Any
Electric field at points (..., 3), differentiable in points and wave values.
Wave.hfield¶
Wave.hfield(points: Any=None, *, r: Any=None) -> Any
Magnetic field in relative vacuum impedance units.
Wave.dfield¶
Wave.dfield(points: Any=None, *, r: Any=None) -> Any
Electric displacement divided by vacuum permittivity.
Wave.bfield¶
Wave.bfield(points: Any=None, *, r: Any=None) -> Any
Magnetic flux density times vacuum light speed.
Wave.gfield¶
Wave.gfield(pol: int, points: Any=None, *, r: Any=None) -> Any
Helicity-resolved G field, normalized as in treams for this wave family.
Wave.ffield¶
Wave.ffield(pol: int, points: Any=None, *, r: Any=None) -> Any
G field with the chiral index weighting in the helicity convention.
Wave.medium¶
Wave.medium: Material
Medium in which the wave travels.
Wave.polarization¶
Wave.polarization: str
Polarization convention, "helicity" or "parity".
Wave.coefficients¶
Wave.coefficients: Any
One coefficient per basis mode, a framework array.
Wave.kind¶
Wave.kind: str
Radial kind: "regular" (incident) or "singular" (outgoing).
Wave.modetype¶
Wave.modetype: str
treams name of kind.
Wave.in_basis¶
Wave.in_basis(basis: Basis, *, positions: Any=None, singular: bool | None=None, kind: str | None=None) -> Wave
Re-expand into another multipole basis; the field stays the same.
Wave.with_polarization¶
Wave.with_polarization(polarization: str) -> Wave
Change the static multipole polarization convention.
Wave.basis¶
Wave.basis: Basis
Fixed mode labels.
Wave.k0¶
Wave.k0: Any
Vacuum wavenumber.
Wave.positions¶
Wave.positions: Any
Expansion centres, shape (positions, 3), a framework array.
angular¶
angular(z: ArrayLike, *, degree: ArrayLike, order: ArrayLike, function: str='legendre') -> NDArray[np.complex128]
Integer-degree angular functions, differentiable in z.
bands¶
bands(smats: ArrayLike, period: ArrayLike) -> tuple[NDArray[np.complex128], NDArray[np.complex128]]
Normal Bloch wavenumbers and eigenvectors, differentiable in smats and period.
bessel¶
bessel(z: Any, *, order: ArrayLike, function: str='j', spherical: bool=False, derivative: bool=False) -> Any
Broadcast Bessel values, differentiable in z; the order stays fixed.
chirality_density¶
chirality_density(ks: ArrayLike, normal: ArrayLike, z: ArrayLike=(0.0, 0.0)) -> NDArray[np.complex128]
Compact up/down/cross chirality coefficients, differentiable in ks, normal and z.
coordinates¶
coordinates(points: ArrayLike, *, function: str | None=None, kind: str | None=None) -> NDArray[np.float64]
Coordinate conversion of points, differentiable in the points.
function is a conversion such as "car2sph", as in
diff.coordinates; kind is an alias.
cylinder¶
cylinder(kzs: ArrayLike, mmax: int, k0: ArrayLike, radii: ArrayLike, epsilon: ArrayLike, mu: ArrayLike | None=None, kappa: ArrayLike | None=None) -> NDArray[np.complex128]
Differentiable multilayer/chiral cylinder T-matrix.
kzs holds the sorted distinct axial wavenumbers, as in treams'
TMatrixC.cylinder(kzs, ...).
cylinder_tmatrix¶
cylinder_tmatrix(*, k0: Any, kz: Any, mmax: int, radius: Any, material: Any, medium: Any=1.0, polarization: str='helicity') -> TMatrix
Homogeneous cylinder; axial mode labels are fixed configuration.
cylindrical_channels¶
cylindrical_channels(positions: ArrayLike, ks: ArrayLike, kx: ArrayLike, period: ArrayLike, *, basis: CylindricalBasis, kz_labels: ArrayLike, polarizations: ArrayLike, poltype: str | None=None) -> NDArray[np.complex128]
Differentiable cylindrical radiation, holding axial mode labels fixed.
cylindrical_translation¶
cylindrical_translation(krr: ArrayLike, phi: ArrayLike, z: ArrayLike, kz: ArrayLike, *, order: ArrayLike, singular: bool=True) -> NDArray[np.complex128]
Cylindrical translation coefficients, differentiable in krr, phi, z and kz.
ebcm_qmat¶
ebcm_qmat(radii: ArrayLike, slopes: ArrayLike, ks: ArrayLike, zs: ArrayLike, *, theta: ArrayLike, weights: ArrayLike, destination: Modes, source: Modes | None=None, singular: bool=True, radial_area_factor: bool=True) -> NDArray[np.complex128]
Axisymmetric EBCM surface integral, differentiable in radii, slopes, ks and zs.
eig¶
eig(operator: ArrayLike) -> tuple[NDArray[np.complex128], NDArray[np.complex128]]
Eigenvalues and phase-fixed eigenvectors of a complex matrix, differentiable.
At repeated eigenvalues only equally weighted sums of those eigenvalues, without eigenvector dependence, have a gradient. Individual eigenmodes have no gradient there.
eigvals¶
eigvals(operator: ArrayLike) -> NDArray[np.complex128]
Differentiable eigenvalues, without an eigenvector phase constraint.
Values are sorted by real part, then imaginary part. Forward mode requires distinct real parts to keep that order fixed. Reverse mode also supports equal loss weights at ordering ties and repeated eigenvalues.
expansion¶
expansion(destination_positions: ArrayLike, source_positions: ArrayLike, ks: ArrayLike, *, destination: SphericalBasis | CylindricalBasis, source: SphericalBasis | CylindricalBasis, poltype: str | None=None, singular: bool=False, kzs: ArrayLike | None=None) -> NDArray[np.complex128]
Expansion matrix, differentiable in the positions, ks and optional axial groups.
kzs holds the sorted distinct axial wavenumbers of both bases, one value
per group, like kzs of TMatrixC.cylinder in treams (kz of the
field functions holds one value per mode). One value moves the entire
matching group in both bases. Values must remain distinct; changing which
modes couple is a discrete operation.
ffield¶
ffield(pol: int, coefficients: ArrayLike, points: ArrayLike, positions: ArrayLike, ks: ArrayLike, *, basis: SphericalBasis | CylindricalBasis, poltype: str | None=None, singular: bool=False, kz: ArrayLike | None=None) -> NDArray[np.complex128]
Weighted F samples, differentiating the chiral index weights as well.
Arguments as for field; kz holds one value per mode.
field¶
field(coefficients: ArrayLike, points: ArrayLike, positions: ArrayLike, ks: ArrayLike, *, basis: SphericalBasis | CylindricalBasis, poltype: str | None=None, singular: bool=False, kz: ArrayLike | None=None) -> NDArray[np.complex128]
Electric field at points, differentiable in every array argument.
positions are the expansion centres. For a cylindrical basis, kz
(one value per mode, like basis.kz) makes the axial wavenumbers
differentiable.
For routine scattering prefer Cluster(...).scatter(incident).efield(points).
Raw scattered coefficients are singular (outgoing) waves and require
singular=True; singular=False means regular incident waves. ks contains medium
wavenumbers for negative/positive helicity, both k0 in vacuum. Helicity
labels do not mean opposite propagation directions or opposite signs of k.
The raw path agrees with the physical wave API:
import numpy as np
import treams_rs.advect as tr
k0 = 2.0
sphere = tr.sphere_tmatrix(k0=k0, lmax=2, radius=0.2, material=3.0)
incident = tr.plane_wave([0, 0, 1], "positive_helicity", k0=k0)
scattered = sphere.scatter(incident)
points = [[0.4, 0.1, 0.3]]
raw = tr.field(scattered.coefficients, points, scattered.basis.positions,
[k0, k0], basis=scattered.basis, singular=True)
np.testing.assert_allclose(raw, scattered.efield(points))
field_operator¶
field_operator(points: ArrayLike, positions: ArrayLike, ks: ArrayLike, *, basis: SphericalBasis | CylindricalBasis, poltype: str | None=None, singular: bool=False, kz: ArrayLike | None=None) -> NDArray[np.complex128]
Full field matrix at the expansion centres positions.
For a cylindrical basis, kz (one value per mode, like basis.kz)
makes the axial wavenumbers differentiable.
fresnel¶
fresnel(ks: ArrayLike, kzs: ArrayLike, zs: ArrayLike) -> NDArray[np.complex128]
Differentiable chiral planar-interface coefficients.
gfield¶
gfield(pol: int, coefficients: ArrayLike, points: ArrayLike, positions: ArrayLike, ks: ArrayLike, *, basis: SphericalBasis | CylindricalBasis, poltype: str | None=None, singular: bool=False, kz: ArrayLike | None=None) -> NDArray[np.complex128]
Weighted G field samples with upstream scaling, differentiable like field.
Arguments as for field; kz holds one value per mode.
hfield¶
hfield(coefficients: ArrayLike, points: ArrayLike, positions: ArrayLike, ks: ArrayLike, impedance: ArrayLike, *, basis: SphericalBasis | CylindricalBasis, poltype: str | None=None, singular: bool=False, kz: ArrayLike | None=None) -> NDArray[np.complex128]
Magnetic samples, including impedance derivatives through the linear weights.
Arguments as for field; kz holds one value per mode.
illuminate¶
illuminate(local: Any, coupling: Any, incident: Any) -> Any
Solve only the requested incident columns, differentiable in all three inputs.
incgamma¶
incgamma(z: ArrayLike, *, n: ArrayLike) -> NDArray[np.complex128]
Upper incomplete gamma function, differentiable in z; n stays fixed.
interaction¶
interaction(local: Any, coupling: Any) -> Any
Solve (I - T C) X = T, differentiable in T (local) and C (coupling).
interface¶
interface(*, basis: PlaneWavePorts, k0: Any, negative_medium: Any, positive_medium: Any, polarization: str='helicity') -> SMatrix
Interface from negative to positive side of the port normal.
interface_coefficients¶
interface_coefficients(ks: ArrayLike, zs: ArrayLike, q: ArrayLike, *, alignment: str='xy', fixed_q: bool=False) -> NDArray[np.complex128]
Coefficients of one planar interface, differentiable in ks, zs and q.
intkambe¶
intkambe(z: ArrayLike, eta: ArrayLike, *, n: ArrayLike) -> NDArray[np.complex128]
Kambe integral, differentiable in z and eta; n stays fixed.
lattice_expansion¶
lattice_expansion(destination_positions: ArrayLike, source_positions: ArrayLike, ks: ArrayLike, kpar: ArrayLike, a: ArrayLike, *, destination: SphericalBasis | CylindricalBasis, source: SphericalBasis | CylindricalBasis, poltype: str | None=None, eta: complex=0, kzs: ArrayLike | None=None) -> NDArray[np.complex128]
Lattice expansion (periodic coupling), differentiable in positions, ks, kpar and a.
The Ewald split eta is a numerical constant; its exact physical derivative is zero.
Optional kzs holds the sorted distinct axial wavenumbers of both bases,
one value per group, as in expansion. Groups must remain distinct.
lattice_expansion_from_table¶
lattice_expansion_from_table(values: ArrayLike, *, destination: SphericalBasis, source: SphericalBasis | None=None, poltype: str | None=None) -> NDArray[np.complex128]
Couple a custom differentiable lattice table to spherical modes, differentiable in values.
lattice_sum¶
lattice_sum(k: ArrayLike, kpar: ArrayLike, a: ArrayLike, r: ArrayLike, eta: ArrayLike=0, *, dim: int, degree: ArrayLike=0, order: ArrayLike=0, spherical: bool=True, part: str='full', shell: ArrayLike=0) -> NDArray[np.complex128]
Lattice sum, differentiable in k, kpar, a, r and eta.
The wave labels and the direct-shell index stay fixed.
layer_stack¶
layer_stack(ks: ArrayLike, zs: ArrayLike, q: ArrayLike, thickness: ArrayLike, *, alignment: str='xy', fixed_q: bool=False) -> NDArray[np.complex128]
Compact S-matrix of a layer stack, differentiable in ks, zs, q and thickness.
The output holds one (2, 2, 2, 2) block per transverse wavevector.
mie¶
mie(degree: int, sizes: ArrayLike, epsilon: ArrayLike, mu: ArrayLike, kappa: ArrayLike) -> NDArray[np.complex128]
Differentiable spherical Mie coefficient matrix.
mie_cyl¶
mie_cyl(kz: ArrayLike, order: int, k0: ArrayLike, radii: ArrayLike, epsilon: ArrayLike, mu: ArrayLike, kappa: ArrayLike) -> NDArray[np.complex128]
Differentiable cylindrical Mie coefficient matrix.
multilayer_cylinder_tmatrix¶
multilayer_cylinder_tmatrix(*, k0: Any, kz: Any, mmax: int, radii: Any, materials: Any, medium: Any=1.0, polarization: str='helicity') -> TMatrix
Concentric cylinders with fixed axial labels and dynamic layers.
multilayer_slab¶
multilayer_slab(*, basis: PlaneWavePorts, k0: Any, thicknesses: Any, materials: Any, negative_medium: Any=1.0, positive_medium: Any=1.0, polarization: str='helicity') -> SMatrix
Interior layers in increasing normal order, one material per thickness.
multilayer_sphere_tmatrix¶
multilayer_sphere_tmatrix(*, k0: Any, lmax: int, radii: Any, materials: Any, medium: Any=1.0, polarization: str='helicity') -> TMatrix
Concentric layers, one material per radius, with a separate exterior.
oriented_chirality¶
oriented_chirality(transverse: ArrayLike, normal: ArrayLike, z: ArrayLike=(0.0, 0.0), *, polarizations: ArrayLike, axis: int=2) -> NDArray[np.complex128]
Signed helicity chirality forms, differentiable in transverse, normal and z.
particle_cluster¶
particle_cluster(local: Sequence[ArrayLike], positions: ArrayLike, ks: ArrayLike, *, bases: Sequence[SphericalBasis | CylindricalBasis], poltype: str | None=None) -> NDArray[np.complex128]
Interacting T-matrix of particles with their own local matrices.
Differentiable in the local matrices, the positions and ks.
periodic_to_cw¶
periodic_to_cw(destination_positions: ArrayLike, source_positions: ArrayLike, ks: ArrayLike, kz: ArrayLike, period: ArrayLike, *, destination: CylindricalBasis, source: SphericalBasis, poltype: str | None=None) -> NDArray[np.complex128]
Periodic spherical-to-cylindrical radiation, including moving Fourier labels.
kz holds one axial wavenumber per destination mode, like
destination.kz.
plane_expansion¶
plane_expansion(positions: ArrayLike, vectors: ArrayLike, *, destination: SphericalBasis | CylindricalBasis, polarizations: ArrayLike, poltype: str | None=None, fixed_vectors: bool=False) -> NDArray[np.complex128]
Plane-wave expansion into multipoles, differentiable in positions and wavevectors.
plane_field¶
plane_field(coefficients: ArrayLike | None, points: ArrayLike, vectors: ArrayLike, *, polarizations: ArrayLike, poltype: str | None=None, fixed_vectors: bool=False) -> NDArray[np.complex128]
Plane-wave field or field operator, differentiable in amplitudes, points and wavevectors.
fixed_vectors removes the wavevectors from the differentiable inputs.
plane_permutation¶
plane_permutation(vectors: ArrayLike, *, polarizations: ArrayLike, n: int=1, poltype: str | None=None) -> NDArray[np.complex128]
Cyclic-axis polarization coefficients, differentiable in the complex wavevectors.
plane_phases¶
plane_phases(points: ArrayLike, vectors: ArrayLike) -> NDArray[np.complex128]
Plane-wave translation phases, differentiable in the points and wavevectors.
plane_wave¶
plane_wave(direction: Any, pol: Any, *, k0: Any, medium: Any=1.0, polarization: str='helicity') -> PlaneWave
Plane wave with dynamic real direction, frequency, medium and amplitudes.
propagation¶
propagation(*, distance: Any, basis: PlaneWavePorts, k0: Any, medium: Any=1.0, polarization: str='helicity') -> SMatrix
Propagation through a homogeneous medium, differentiable in the distance and the wavevectors.
propagation_matrix¶
propagation_matrix(vectors: ArrayLike, distance: ArrayLike) -> NDArray[np.complex128]
Differentiable propagation for upgoing wavevectors and a Cartesian displacement.
rotation¶
rotation(angles: ArrayLike, *, destination: SphericalBasis | CylindricalBasis, source: SphericalBasis | CylindricalBasis | None=None) -> NDArray[np.complex128]
Euler-angle derivatives; cylindrical theta must remain fixed at zero.
slab¶
slab(*, basis: PlaneWavePorts, k0: Any, thickness: Any, material: Any, negative_medium: Any=1.0, positive_medium: Any=1.0, polarization: str='helicity') -> SMatrix
One layer with differentiable geometry and explicit exterior media.
smatrix¶
smatrix(array: Any, *, basis: PlaneWavePorts, k0: Any, negative_medium: Any=1.0, positive_medium: Any=1.0, polarization: str='helicity') -> SMatrix
Wrap scattering blocks (2,2,modes,modes) with explicit exterior media.
smatrix_add¶
smatrix_add(lower: ArrayLike, upper: ArrayLike) -> NDArray[np.complex128]
Differentiable Redheffer composition, with arrays shaped (2, 2, n, n).
smatrix_cd¶
smatrix_cd(matrices: ArrayLike, incident: ArrayLike, ks: ArrayLike, zs: ArrayLike, q: ArrayLike, *, modes: Sequence[tuple[int, int]], axis: int=2, poltype: str | None=None, modetype: str='up', fixed_q: bool=False) -> NDArray[np.complex128]
Same as smatrix_circular_dichroism.
Circular dichroism in transmission and in total outgoing power.
Returns the two contrasts (P1 - P0) / (P0 + P1): first of the transmitted
power, then of the transmitted plus reflected power. P0 belongs to
incident and P1 to the same illumination in the opposite helicity (or
with the sign of pol 0 flipped in the parity convention). One Rust power
evaluation covers both illuminations, and every input is differentiable.
smatrix_circular_dichroism¶
smatrix_circular_dichroism(matrices: ArrayLike, incident: ArrayLike, ks: ArrayLike, zs: ArrayLike, q: ArrayLike, *, modes: Sequence[tuple[int, int]], axis: int=2, poltype: str | None=None, modetype: str='up', fixed_q: bool=False) -> NDArray[np.complex128]
Circular dichroism in transmission and in total outgoing power.
Returns the two contrasts (P1 - P0) / (P0 + P1): first of the transmitted
power, then of the transmitted plus reflected power. P0 belongs to
incident and P1 to the same illumination in the opposite helicity (or
with the sign of pol 0 flipped in the parity convention). One Rust power
evaluation covers both illuminations, and every input is differentiable.
smatrix_from_array¶
smatrix_from_array(response: ArrayLike, channels: ArrayLike) -> NDArray[np.complex128]
Differentiable radiation of an effective multipole response into plane waves.
smatrix_illuminate¶
smatrix_illuminate(lower: ArrayLike, upper: ArrayLike, up: ArrayLike, down: ArrayLike) -> NDArray[np.complex128]
Outgoing/internal up/down fields for mode-by-illumination incident arrays.
smatrix_periodic¶
smatrix_periodic(smats: ArrayLike) -> NDArray[np.complex128]
Periodic transfer matrix; its gradient reuses the forward factorization.
smatrix_tr¶
smatrix_tr(matrices: ArrayLike, incident: ArrayLike, ks: ArrayLike, zs: ArrayLike, q: ArrayLike, *, modes: Sequence[tuple[int, int]], axis: int=2, poltype: str | None=None, modetype: str='up', fixed_q: bool=False) -> NDArray[np.complex128]
Differentiable T/R rows for illumination columns and complete port geometry.
solve¶
solve(operator: Any, rhs: Any) -> Any
Solve A X = B by LU decomposition, differentiable in A and B.
solve_periodic¶
solve_periodic(unit_cell: TMatrix | Cluster, *, lattice: Any, kpar: Any, eta: complex=0) -> PeriodicResponse
Solve periodic coupling once, then use response.to_smatrix(ports).
Lattice vectors and the Bloch wavevector remain dynamic framework values.
sph_harm¶
sph_harm(theta: ArrayLike, phi: ArrayLike, *, degree: ArrayLike, order: ArrayLike) -> NDArray[np.complex128]
Normalized spherical harmonic, differentiable in theta and phi.
sphere¶
sphere(lmax: int, k0: Any, radii: Any, epsilon: Any, mu: Any=None, kappa: Any=None) -> Any
Multilayer chiral sphere T-matrix in the helicity basis.
Differentiable in k0, the radii and the layer materials.
sphere_cluster¶
sphere_cluster(lmax: int, k0: ArrayLike, radii: ArrayLike, epsilon: ArrayLike, positions: ArrayLike) -> NDArray[np.complex128]
Differentiable interacting T-matrix of homogeneous spheres in vacuum.
sphere_tmatrix¶
sphere_tmatrix(*, k0: Any, lmax: int, radius: Any, material: Any, medium: Any=1.0, polarization: str='helicity') -> TMatrix
Homogeneous sphere with differentiable geometry, material and frequency.
spherical_channels¶
spherical_channels(positions: ArrayLike, ks: ArrayLike, q: ArrayLike, area: ArrayLike, *, basis: SphericalBasis, polarizations: ArrayLike, poltype: str | None=None, fixed_q: bool=False) -> NDArray[np.complex128]
Differentiable spherical incidence/radiation channels.
fixed_q treats q as a static constant; this supports exactly normal incidence. Direction gradients otherwise require nonzero transverse wavevectors.
spherical_translation¶
spherical_translation(kr: ArrayLike, theta: ArrayLike, phi: ArrayLike, *, destination: Sequence[ArrayLike], source: Sequence[ArrayLike], poltype: str | None=None, singular: bool=True) -> NDArray[np.complex128]
Spherical translation coefficients, differentiable in kr, theta and phi.
stack¶
stack(layers: Any) -> SMatrix
Cascade layers from the negative to positive side of the port normal.
svdvals¶
svdvals(operator: ArrayLike) -> NDArray[np.float64]
Singular values of a complex matrix in descending order, differentiable.
tmatrix¶
tmatrix(array: Any, *, basis: SphericalBasis | CylindricalBasis, k0: Any, medium: Any=1.0, polarization: str='helicity', positions: Any=None) -> TMatrix
Wrap a user response (modes,modes) with fixed labels and dynamic physical metadata.
tmatrix_metric¶
tmatrix_metric(operator: ArrayLike, ks: ArrayLike=(1.0, 1.0), *, polarizations: ArrayLike, metric: str | None=None, kind: str | None=None) -> NDArray[np.float64]
Global helicity metric of a T-matrix, differentiable in operator and ks.
metric is "cd", "db" or "chi", as in diff.tmatrix_metric; kind
is an alias.
vector_coordinates¶
vector_coordinates(vectors: ArrayLike, points: ArrayLike, *, function: str | None=None, kind: str | None=None) -> NDArray[np.complex128]
Vector-frame conversion, differentiable in the vectors and the points.
function is a conversion such as "car2sph", as in
diff.vector_coordinates; kind is an alias.
vector_wave¶
vector_wave(*arguments: ArrayLike, function: str, degree: ArrayLike=0, order: ArrayLike=0, pol: ArrayLike | None=None, polarization: ArrayLike | None=None) -> NDArray[np.complex128]
Vector waves and harmonics, differentiable in every continuous argument.
pol is the pol index 0 or 1 (default 0); polarization is an alias.
wave¶
wave(coefficients: Any, *, basis: SphericalBasis | CylindricalBasis, k0: Any, medium: Any=1.0, kind: str='regular', polarization: str='helicity', positions: Any=None) -> Wave
Multipole coefficients of shape (modes,) or (modes, illuminations).
wignerd¶
wignerd(phi: ArrayLike, theta: ArrayLike, psi: ArrayLike, *, degree: ArrayLike, row: ArrayLike, column: ArrayLike) -> NDArray[np.complex128]
Wigner D elements, differentiable in the three complex Euler angles.