Skip to content

components ¤

Modules:

Name Description
base_component

Base class and decorators for defining JAX-compatible circuit components.

electronic

Electronic components.

photonic

Photonic components for optical circuit simulation.

rational

Factory functions for creating Circulax components from rational fitting models.

va_component

Backward-compatibility shim — re-exports va_component from bosdi.circulax.

Functions:

Name Description
OpticalDelayLine

Waveguide modelled as an explicit time-of-flight delay line (real group delay).

TransmissionLine

Matched bidirectional transmission line with exact fixed delay.

delay_line_fdomain

Frequency-domain delay line for AC and harmonic-balance analysis.

OpticalDelayLine ¤

OpticalDelayLine(
    signals: Signals,
    length_um: float = 100.0,
    loss_dB_cm: float = 1.0,
    neff: float = 2.4,
    n_group: float = 4.0,
    wavelength_nm: float = 1310.0,
) -> PhysicsReturn

Waveguide modelled as an explicit time-of-flight delay line (real group delay).

Unlike :func:OpticalWaveguide -- which is a steady-state S-matrix stamp only valid for CW/frequency-domain analysis -- this component enforces the actual transient envelope delay: the output field at p2 is the input field at p1 from tau = length_um * n_group / c seconds ago, attenuated and phase-shifted, via a VCVS-style constraint (same pattern as :func:TunableBeamSplitter). p1 carries no self-stamp and must be driven by a connected source/component, matching that same convention.

See circulax.solvers.assembly for how the delayed local state is computed -- a fixed-size accepted-step history buffer read via jnp.interp, vmapped per-instance since tau may vary across instances of different length. Adaptive and fixed step-size controllers may take steps longer than tau; interpolation against the current Newton trial supplies the required delay Jacobian in that regime.

Parameters:

Name Type Description Default
signals Signals

Current and delayed component-local fields and branch state.

required
length_um float

Waveguide length in micrometres. Defaults to 100.0.

100.0
loss_dB_cm float

Propagation loss in dB/cm. Defaults to 1.0.

1.0
neff float

Effective refractive index, used for the carrier phase shift over the delay. Defaults to 2.4.

2.4
n_group float

Group refractive index; sets the propagation delay via tau = length_um * n_group / c. Defaults to 4.0.

4.0
wavelength_nm float

Operating wavelength in nm. Defaults to 1310.0.

1310.0
Source code in circulax/components/photonic.py
@component(ports=("p1", "p2"), states=("i_p2",))
def OpticalDelayLine(
    signals: Signals,
    length_um: float = 100.0,
    loss_dB_cm: float = 1.0,
    neff: float = 2.4,
    n_group: float = 4.0,
    wavelength_nm: float = 1310.0,
) -> PhysicsReturn:
    """Waveguide modelled as an explicit time-of-flight delay line (real group delay).

    Unlike :func:`OpticalWaveguide` -- which is a steady-state S-matrix stamp
    only valid for CW/frequency-domain analysis -- this component enforces
    the actual transient envelope delay: the output field at ``p2`` is the
    input field at ``p1`` from ``tau = length_um * n_group / c`` seconds ago,
    attenuated and phase-shifted, via a VCVS-style constraint (same pattern as
    :func:`TunableBeamSplitter`). ``p1`` carries no self-stamp and must be
    driven by a connected source/component, matching that same convention.

    See ``circulax.solvers.assembly`` for how the delayed local state is
    computed -- a fixed-size accepted-step history buffer read via
    ``jnp.interp``, vmapped per-instance since ``tau`` may vary across
    instances of different length. Adaptive and fixed step-size controllers
    may take steps longer than ``tau``; interpolation against the current
    Newton trial supplies the required delay Jacobian in that regime.

    Args:
        signals: Current and delayed component-local fields and branch state.
        length_um: Waveguide length in micrometres. Defaults to ``100.0``.
        loss_dB_cm: Propagation loss in dB/cm. Defaults to ``1.0``.
        neff: Effective refractive index, used for the carrier phase shift
            over the delay. Defaults to ``2.4``.
        n_group: Group refractive index; sets the propagation delay via
            ``tau = length_um * n_group / c``. Defaults to ``4.0``.
        wavelength_nm: Operating wavelength in nm. Defaults to ``1310.0``.

    """
    phi = 2.0 * jnp.pi * neff * (length_um / wavelength_nm) * 1000.0
    loss_val = loss_dB_cm * (length_um / 10000.0)
    T_mag = 10.0 ** (-loss_val / 20.0)
    T = T_mag * jnp.exp(-1j * phi)

    c_um_per_s = 2.99792458e14
    delay = (length_um * n_group) / c_um_per_s
    constraint = signals.p2 - T * signals.at_delay(delay).p1

    return {"p1": 0.0, "p2": signals.i_p2, "i_p2": constraint}, {}

TransmissionLine ¤

TransmissionLine(
    signals: Signals, tau: float = 1e-09, z0: float = 50.0, attenuation: float = 1.0
) -> PhysicsReturn

Matched bidirectional transmission line with exact fixed delay.

a1 and a2 are the incident power-wave amplitudes at the two reference planes. The outgoing waves are the delayed incident wave from the opposite end. This stamp stays finite for an exactly lossless line and therefore avoids the singular S -> Y conversion of an ideal through connection.

The same equations are interpreted by DC, transient, AC, and HB.

Source code in circulax/components/electronic.py
@component(
    ports=("p1", "p2"),
    states=("a1", "a2"),
    port_aliases=_PN_ALIASES,
    holomorphic=True,
)
def TransmissionLine(
    signals: Signals,
    tau: float = 1e-9,
    z0: float = 50.0,
    attenuation: float = 1.0,
) -> PhysicsReturn:
    """Matched bidirectional transmission line with exact fixed delay.

    ``a1`` and ``a2`` are the incident power-wave amplitudes at the two
    reference planes. The outgoing waves are the delayed incident wave from
    the opposite end. This stamp stays finite for an exactly lossless line
    and therefore avoids the singular ``S -> Y`` conversion of an ideal
    through connection.

    The same equations are interpreted by DC, transient, AC, and HB.
    """
    past = signals.at_delay(tau)
    b1 = attenuation * past.a2
    b2 = attenuation * past.a1
    i1 = (signals.a1 - b1) / z0
    i2 = (signals.a2 - b2) / z0
    return {
        "p1": i1,
        "p2": i2,
        "a1": signals.p1 - signals.a1 - b1,
        "a2": signals.p2 - signals.a2 - b2,
    }, {}

delay_line_fdomain ¤

delay_line_fdomain(
    f: float, length_um: float = 100.0, loss_dB_cm: float = 1.0, n_group: float = 4.0
) -> ndarray

Frequency-domain delay line for AC and harmonic-balance analysis.

Models a pure transmission-line group delay: S21 = T_mag * exp(-j 2pi f tau) where tau = length_um * n_group / c and T_mag accounts for propagation loss. The S-matrix is converted to a Y-matrix via :func:s_to_y.

This is a frequency-domain-only component (f = modulation / signal frequency, e.g. 1 GHz for an AC sweep). Carrier-phase effects (neff, wavelength_nm) belong in the wavelength-domain :func:OpticalWaveguide and are intentionally excluded here.

This component is AC/HB-only; it cannot be used in transient simulation (fdomain components raise at transient setup time).

Parameters:

Name Type Description Default
f float

Modulation frequency in Hz (supplied by the AC/HB solver).

required
length_um float

Waveguide length in micrometres. Defaults to 100.0.

100.0
loss_dB_cm float

Propagation loss in dB/cm. Defaults to 1.0.

1.0
n_group float

Group refractive index; sets the propagation delay via tau = length_um * n_group / c. Defaults to 4.0.

4.0
Source code in circulax/components/photonic.py
@fdomain_component(ports=("p1", "p2"))
def delay_line_fdomain(
    f: float,
    length_um: float = 100.0,
    loss_dB_cm: float = 1.0,
    n_group: float = 4.0,
) -> jnp.ndarray:
    """Frequency-domain delay line for AC and harmonic-balance analysis.

    Models a pure transmission-line group delay: ``S21 = T_mag * exp(-j 2pi f tau)``
    where ``tau = length_um * n_group / c`` and ``T_mag`` accounts for
    propagation loss.  The S-matrix is converted to a Y-matrix via
    :func:`s_to_y`.

    This is a frequency-domain-only component (``f`` = modulation / signal
    frequency, e.g. 1 GHz for an AC sweep).  Carrier-phase effects
    (``neff``, ``wavelength_nm``) belong in the wavelength-domain
    :func:`OpticalWaveguide` and are intentionally excluded here.

    This component is AC/HB-only; it cannot be used in transient simulation
    (fdomain components raise at transient setup time).

    Args:
        f: Modulation frequency in Hz (supplied by the AC/HB solver).
        length_um: Waveguide length in micrometres. Defaults to ``100.0``.
        loss_dB_cm: Propagation loss in dB/cm. Defaults to ``1.0``.
        n_group: Group refractive index; sets the propagation delay via
            ``tau = length_um * n_group / c``. Defaults to ``4.0``.

    """
    c_um_per_s = 2.99792458e14
    loss_val = loss_dB_cm * (length_um / 10000.0)
    T_mag = 10.0 ** (-loss_val / 20.0)
    tau = (length_um * n_group) / c_um_per_s
    T = T_mag * jnp.exp(-1j * 2.0 * jnp.pi * f * tau)
    S = jnp.array([[0.0, T], [T, 0.0]], dtype=jnp.complex128)
    return s_to_y(S)