Skip to content

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 with pushforward(*input_tangents). Bind labels and options with a closure or functools.partial.

Returns

A function of tensors or array-likes that returns a tensor, or a tuple of tensors for several outputs.