solprop.modes.tabulated#

Build waveguide modes from loaded effective-index arrays.

An evacuated table gains its fill through n_eff**2 = n_v**2 + chi_g; a filled table already contains the whole linear response. Both hollow modes retain Marcatili’s transverse field. See docs/guide/waveguides/tabulated-modes.md.

Module Attributes

MIN_TABLE_POINTS

Fewest samples required by the house cubic interpolant.

Functions

sample_index_table(mode, omega, *[, z, ...])

Sample a mode into a dense index snapshot with analytic Hermite slopes.

Classes

IndexTable(omega, neff_values[, area, ...])

Interpolate a passive mode's complex index and optional effective area.

TabulatedHollowMode(radius[, gas, pressure, ...])

Add a gas fill to an evacuated table using fixed transverse wavenumber.

TabulatedMode(radius[, gas, pressure, kind, ...])

Use a filled table's whole linear response with Marcatili transverse fields.

class solprop.modes.tabulated.IndexTable(omega, neff_values, area=None, loss_interpolation='log')[source]#

Bases: Displayed

Interpolate a passive mode’s complex index and optional effective area.

Real refractivity and area use cubic splines in angular frequency. Loss uses a cubic spline of its logarithm by default; linear means a cubic spline of the imaginary index itself, with negative interpolated values clamped. No evaluation extrapolates. Constructor arrays are sorted and copied.

Parameters:
omegaarray_like

Positive finite angular frequencies in rad/s, shape (n_nodes,), at least four distinct samples, in either order.

neff_valuesarray_like

Finite complex effective indices, shape (n_neff_nodes,) matching omega. Imaginary parts must be non-negative (strictly positive for logarithmic interpolation). Stored as read-only complex128.

areaarray_like or None, optional

Positive finite effective areas in m^2, shape (n_area_nodes,) matching omega, or no area. Stored as read-only float64.

loss_interpolation{‘log’, ‘linear’}, optional

Imaginary-index interpolation policy, default 'log'.

Examples

>>> table = IndexTable.from_wavelength(
...     [500e-9, 600e-9, 700e-9, 800e-9], [1.45 + 1e-9j] * 4)
>>> table.neff(table.omega).real.tolist()
[1.45, 1.45, 1.45, 1.45]
alpha(omega)[source]#

Return the power attenuation of the interpolated index.

Parameters:
omegaarray_like

Angular frequencies in rad/s, shape (n_omega,), inside the table.

Returns:
numpy.ndarray

Non-negative intensity attenuation in 1/m, shape (n_omega,).

area: Float[ndarray, 'n_area_nodes'] | None = None#
beta(omega)[source]#

Return the propagation constant of the interpolated index.

Parameters:
omegaarray_like

Angular frequencies in rad/s, shape (n_omega,), inside the table.

Returns:
numpy.ndarray

Propagation constant in rad/m, shape (n_omega,).

dbeta_domega(omega)[source]#

Return the inverse group velocity of the interpolated index.

Parameters:
omegaarray_like

Angular frequencies in rad/s, shape (n_omega,), inside the table.

Returns:
numpy.ndarray

Inverse group velocity in s/m, shape (n_omega,).

dneff_domega(omega)[source]#

Return the frequency derivative of the interpolated index.

Parameters:
omegaarray_like

Angular frequencies in rad/s, shape (n_omega,), inside the table.

Returns:
numpy.ndarray

Complex derivative in s/rad, shape (n_omega,).

effective_area(omega)[source]#

Return the interpolated effective-area column.

Parameters:
omegaarray_like

Angular frequencies in rad/s, shape (n_omega,), inside the table.

Returns:
numpy.ndarray

Effective areas in m^2, shape (n_omega,).

Raises:
ModeError

If no area exists, the query is outside the table, or interpolation produces a non-positive or non-finite area.

classmethod from_loss(wavelength, index, loss_db_per_m, *, area=None, loss_interpolation='log')[source]#

Build a table from wavelengths, real indices and power loss in dB/m.

Parameters:
wavelengtharray_like

Positive wavelengths in m, shape (n_nodes,).

indexarray_like

Finite real indices at the wavelengths, same shape.

loss_db_per_marray_like

Finite non-negative power loss in dB/m, same shape.

areaarray_like or None, optional

Positive effective areas in m^2, same shape.

loss_interpolation{‘log’, ‘linear’}, optional

Imaginary-index interpolation policy.

Returns:
IndexTable

Table with Im n = wavelength * loss * ln(10) / (40 pi).

Raises:
ModeError

If samples differ in shape, are complex, non-finite or declare gain.

classmethod from_wavelength(wavelength, neff, *, area=None, loss_interpolation='log')[source]#

Build a table from wavelengths and complex indices in either order.

Parameters:
wavelengtharray_like

Positive finite wavelengths in m, shape (n_nodes,).

neffarray_like

Passive complex indices, shape (n_neff_nodes,) matching wavelengths.

areaarray_like or None, optional

Positive effective areas in m^2 at the same samples.

loss_interpolation{‘log’, ‘linear’}, optional

Imaginary-index interpolation policy.

Returns:
IndexTable

Validated table sorted by increasing angular frequency.

Raises:
ModeError

If coordinates or samples violate the table requirements.

loss_interpolation: Literal['log', 'linear'] = 'log'#
neff(omega)[source]#

Return the interpolated complex effective index.

Parameters:
omegaarray_like

Angular frequencies in rad/s, shape (n_omega,), inside the table.

Returns:
numpy.ndarray

Complex index, shape (n_omega,).

neff_values: Complex[ndarray, 'n_neff_nodes']#
omega: Float[ndarray, 'n_nodes']#
refractivity(omega)[source]#

Return refractivity and its exact interpolant derivative.

Parameters:
omegaarray_like

Positive finite angular frequencies in rad/s, shape (n_omega,).

Returns:
tuple of numpy.ndarray

Complex n - 1 and dn/domega in s/rad, each shape (n_omega,).

Raises:
ModeError

If frequencies are invalid or outside the table’s support.

property wavelength_range: tuple[float, float][source]#

Return the inclusive wavelength range in metres.

Returns:
tuple of float

Shortest and longest wavelength, m.

solprop.modes.tabulated.MIN_TABLE_POINTS = 4#

Fewest samples required by the house cubic interpolant.

class solprop.modes.tabulated.TabulatedHollowMode(radius, gas=None, pressure=0.0, *, kind='HE', n=1, m=1, phi=0.0, model='full', loss=True, cladding=None, temperature=None, susceptibility=None, mixture=None, table, reference_wavelength=None)[source]#

Bases: _TableMode

Add a gas fill to an evacuated table using fixed transverse wavenumber.

n_eff**2 = n_v**2 + chi_g is exact for the full Marcatili model. It neglects the fill’s change of wall contrast in a general fibre (about -0.25 % in the resonance wavelengths at 10 bar of argon). Inherited gas, pressure and mixture paths supply both linear and nonlinear responses. Radius is constant; cladding and the reduced model are refused.

Attributes:
tableIndexTable

Evacuated complex effective index and optional area for this geometry.

reference_wavelengthfloat or None, optional

Wavelength in m at which the table’s area is used for propagation. Required exactly when the table contains an area column.

class solprop.modes.tabulated.TabulatedMode(radius, gas=None, pressure=0.0, *, kind='HE', n=1, m=1, phi=0.0, model='full', loss=True, cladding=None, temperature=None, susceptibility=None, mixture=None, table, reference_wavelength=None)[source]#

Bases: _TableMode

Use a filled table’s whole linear response with Marcatili transverse fields.

Gas or mixture declarations supply nonlinear responses only, and must have constant paths. A table computed at 10 bar paired with 20 bar nonlinear responses is a modelling error the code cannot detect. Loss policies and the real-index floor are inherited from MarcatiliMode.

Attributes:
tableIndexTable

Whole complex effective index and optional area at one fill and geometry.

reference_wavelengthfloat or None, optional

Wavelength in m selecting the propagation area, required exactly when the table has an area column.

absorption_by_species(omega, z=0.0)[source]#

Return zero species attribution for a table’s indivisible total loss.

Parameters:
omeganumpy.ndarray

Positive finite angular frequencies in rad/s, shape (n_omega,).

zfloat, optional

Position in m; ignored, the fill is fixed.

Returns:
numpy.ndarray

Zeros in 1/m, shape (n_species, n_omega); one row for a legacy gas.

sampled_terms(omega)[source]#

Sample nothing: the filled table is the whole linear response.

Parameters:
omeganumpy.ndarray

Positive angular frequencies in rad/s, shape (n_omega,).

Returns:
MarcatiliTerms

Zero gas and cladding terms, one susceptibility row per population.

Raises:
ModeError

If a frequency is not positive and finite or lies outside the table.

solprop.modes.tabulated.sample_index_table(mode, omega, *, z=0.0, include_area=True)[source]#

Sample a mode into a dense index snapshot with analytic Hermite slopes.

Parameters:
modeMode

Source mode with an index and its declared frequency derivative.

omegaarray_like

At least four distinct positive finite frequencies in rad/s, in either order.

zfloat, optional

Finite snapshot position in m within the source’s declared paths.

include_areabool, optional

Include area in m². Step-index profiles are evaluated at each frequency; other modes retain their declared frozen-profile area at z.

Returns:
IndexTable

Sorted, immutable index samples and a Hermite interpolant using the supplied derivative. No extrapolation or E/H reconstruction is implied. The object is a private IndexTable subclass, so it also carries derivative_values (the source slopes in s/rad) and source_identity (the mode’s type, repr, snapshot position, frequency domain and area model); every other attribute and method is the public table’s.

The table is built with loss_interpolation="linear", not the table default "log": a lossless source has an imaginary index of exactly zero and no logarithm, and the logarithmic policy refuses a non-positive one outright.

Raises:
ModeError

If frequencies, derivatives, position or required source data are invalid.