treams_rs.torch¶
PyTorch adapter: physics objects and records as autograd operations on the
CPU, in first-order forward and reverse mode. Forward mode and the first
backward share the Rust context saved by the forward. The first backward
releases that context; repeated backward (retain_graph=True) reruns the
Rust forward from copies of the inputs.
Tensors must be CPU float32, float64,
complex64 or complex128 (TypeError for other dtypes, ValueError for other
devices). Native computation and outputs use float64/complex128; gradients
retain each input's dtype.
Differentiate a scattering cross section:
import torch
import treams_rs as tr
radius = torch.tensor(0.2, requires_grad=True)
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)
sphere.cross_sections(wave).scattering.backward()
gradient = radius.grad
A pullback maps 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[torch]. Forward mode supports
torch.func.jvp and torch.autograd.forward_ad. Higher derivatives,
vectorized transforms and torch.compile are not available. Run another
record with wrap.
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.
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.
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.
illuminate¶
illuminate(local: Any, coupling: Any, incident: Any) -> Any
Solve only the requested incident columns, differentiable in all three inputs.
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.
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.
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.
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.
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.
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_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.
stack¶
stack(layers: Any) -> SMatrix
Cascade layers from the negative to positive side of the port normal.
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.
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).
wrap¶
wrap(record: Record) -> Callable[..., Output]
Turn a record into a PyTorch function with first-order derivatives.
For example, wrap(diff.solve) differentiates a linear solve. Custom
records: https://yaugenst.github.io/treams-rs/latest/differentiation/custom-records/
Args
record: function of the dynamic inputs that returns(value, context)or(value, pullback). The value is an array, a scalar or a flat tuple of them. The pullback returns one gradient per dynamic input, in argument order. Forward mode additionally requires a context withpushforward(*input_tangents). Bind labels and options with a closure orfunctools.partial.
Returns
A function of tensors or array-likes that returns a tensor, or a tuple of tensors for several outputs.