Skip to content

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.