solprop.modes.slab#
Model the hollow planar (slab) waveguide: two plates, a gas-filled gap, uniform y.
Two parallel dielectric or metal plates at \(x = \pm a\) guide light in x and
leave it free in y. This module models the guide uniform in y: the field is a plane
wave in y, the mode is the one-wall-pair limit \(b \to \infty\) of the rectangular
guide of solprop.modes.rectangular, and every integral over the cross-section
is an integral over x per metre of y. A run on these modes reports power in W/m
and energy in J/m (transverse_measure = "per_unit_width"); intensities stay W/m².
The model is Laakmann and Steier’s eq. (5) [1] with \(b \to \infty\), which is Miyagi, Hongo and Kawakami’s eq. (19) [2] and Arnold et al.’s eqs. (2)-(3) [3]:
with \(s = \sqrt{\epsilon_{\rm cl} - \epsilon_{\rm co}}\) the filled-core contrast and \(\epsilon_{\rm cl}/\epsilon_{\rm co}\) the TM-like permittivity ratio of a filled core, both shared with the rectangular guide rather than restated. To first order the field attenuation is \(\alpha_p = (1/a)(p\lambda/4a)^2\,\mathrm{Re}\,q\), so the loss goes as \(p^2\) and \(a^{-3}\), and TM/TE is \(\epsilon_{\rm cl}/\epsilon_{\rm co}\) for glass and about \(n^2 + \kappa^2\) for a metal (Miyagi eq. 36). TE has its electric field along y, parallel to the plates – the low-loss polarisation every planar compressor uses; TM has it along x, normal to them.
What a slab uniform in y cannot show. Whole-beam self-focusing, filamentation and
the modulational instability in the free direction set the energy limit of real
planar compressors (Arnold et al. 2009, stable to \(B \approx 15.5\)). A field
uniform in y has no y structure to focus or break up, so none of that appears here.
The manual page is docs/guide/waveguides/planar.md (section “Hollow planar
waveguides”).
References#
K. D. Laakmann and W. H. Steier, Appl. Opt. 15, 1334-1340 (1976), doi:10.1364/AO.15.001334.
M. Miyagi, A. Hongo and S. Kawakami, IEEE J. Quantum Electron. QE-19, 136-145 (1983), doi:10.1109/JQE.1983.1071837.
C. L. Arnold et al., New J. Phys. 12, 073015 (2010), doi:10.1088/1367-2630/12/7/073015.
Module Attributes
Name a slab family: |
Functions
|
Return the share of a Gaussian beam's power each slab mode takes. |
|
Project a unit-peak Gaussian beam in x onto slab modes, with signs. |
|
Return the per-unit-width value at the centre of a Gaussian beam in y. |
|
Return the total of a per-unit-width quantity spread as a Gaussian in y. |
Classes
|
Describe the hybrid planar transverse grid: slab modes in x, samples in y. |
|
Describe one mode of a gas-filled hollow planar waveguide, uniform in y. |
- class solprop.modes.slab.PlanarGrid(modes, radius_y, n_y, *, window_factor=0.1, n_x=None, x_rule='gauss_kronrod')[source]#
Bases:
DisplayedDescribe the hybrid planar transverse grid: slab modes in x, samples in y.
A hollow planar guide resolved in both transverse directions: the field is
E(x, y, t) = sum_p V_p(x) A_p(y, t), the slab modesV_pof one gap in x – sampled on the slab rule – and a periodic y axis with the Cartesian collar, exactlysolprop.grid.FreeGrid’s. The state’s columns are(p, k_y): a modal amplitude per mode and raw y-DFT frequency, flattenedp + n_p*iywith the mode index fastest, as a free grid has x fastest. The geometry integrates over y, so energies are in J and powers in W (transverse_measure = "area"), not per unit width as a slab uniform in y.docs/guide/waveguides/planar.md(“Resolving y”) anddocs/guide/setup/spatial-decompositions.mddescribe it.- Attributes:
- modestuple of SlabMode
The slab channels, in state order: one gap, one polarisation family, a constant gap along z. Each carries the fill.
- radius_yfloat
Requested physical half-width in y, m, finite and positive.
- n_yint
Samples in y, an integer of at least 2.
- window_factorfloat
Added collar width divided by radius_y, in [0, 1): the periodic half-width is
radius_y * (1 + window_factor); zero disables the collar. Default 0.1.- n_xint or None
Slab-rule x nodes asked of
solprop.modes.quadrature.transverse_quadrature();None(the default) takesmax(32, 8 n_p, 6h + 6)withhthe highest order, the modal route’s default for the same set.- x_rule{‘gauss_kronrod’, ‘gauss’}
The x rule’s family:
"gauss_kronrod"(the default, as the modal route) carries its embedded Gauss rule and rounds an even n_x up by one;"gauss"has no embedded rule.- rulesolprop.modes.quadrature.TransverseQuadrature
The slab rule in x.
- xnumpy.ndarray
The x nodes in m, increasing, inside the gap, shape
(n_x,).- x_weightsnumpy.ndarray
Their quadrature weights in m, shape
(n_x,).- y, k_ynumpy.ndarray
The centred y axis in m and its angular frequencies in rad/m in unshifted FFT order, shape
(n_y,).- window_ynumpy.ndarray
The y collar, shape
(n_y,).- synthesisnumpy.ndarray
Mode fields at the x nodes, each normalised to 1 W/m, in V/(m sqrt(W/m)), shape
(n_x, n_p), without any temporal pad scale.- projection, projection_coarsenumpy.ndarray
The dual basis with the weights and
eps0 c / 2folded in, and its embedded coarse-rule counterpart, shape(n_p, n_x).- centrenumpy.ndarray
Each mode’s normalised field at the mid-plane
x = 0, shape(n_p,).
- Raises:
- GridError
If the y axis, the collar or n_x is invalid.
- ModeError
If the set is empty, holds a mode that is not a
SlabMode, repeats a channel, mixes gaps, fills or polarisation families, or has a gap that varies along z: the hybrid transform carries a constant gap only.
- Warns:
- UserWarning
If n_x is below the measured
6h + 6bound of the set’s highest order, naming the count to use.
Examples
>>> from solprop.modes import PlanarGrid, SlabMode >>> modes = [SlabMode(63.5e-6, "Ar", 1.0, order=p) for p in (1, 3)] >>> space = PlanarGrid(modes, 2e-3, 64) >>> space.n_columns, space.n_nodes, space.x.size (128, 2112, 33) >>> space.transverse_measure 'area'
- centre: Float[ndarray, 'n_p']#
- k_y: Float[ndarray, 'n_y']#
- property kperp_sq: Float[ndarray, 'n_columns'][source]#
Return each column’s
k_y**2.- Returns:
- numpy.ndarray
In m^-2, shape
(n_columns,), the mode index fastest.
- property n_columns: int[source]#
Return the number of state columns,
(p, k_y)pairs.- Returns:
- int
n_p * n_y.
- property n_nodes: int[source]#
Return the number of physical nodes,
(x, y)pairs with x fastest.- Returns:
- int
n_x * n_ywithn_x = x.size.
- property on_axis: Complex[ndarray, 'n_columns'][source]#
Return the weights that reconstruct the field at
x = y = 0.- Returns:
- numpy.ndarray
V_p(0) exp(-i k_y y[0]) / n_yin V/(m sqrt(W/m)), complex, shape(n_columns,): the inverse y DFT aty = 0times each mode’s mid-plane field.
- projection: Float[ndarray, 'n_p n_x']#
- projection_coarse: Float[ndarray, 'n_p n_x']#
- rule: TransverseQuadrature#
- property spectral_weights: Float[ndarray, 'n_columns'][source]#
Return the Parseval weight of each state column.
- Returns:
- numpy.ndarray
dy / n_yin m, shape(n_columns,): the energy of a state of modal amplitudes in sqrt(W/m) issum w |A|^2integrated over time.
- synthesis: Float[ndarray, 'n_x n_p']#
- property transverse_measure: Literal['area', 'per_unit_width'][source]#
Return what the grid’s transverse integrals measure.
- Returns:
- str
"area": the grid integrates over y, so energies are J and powers W.
- window_y: Float[ndarray, 'n_y']#
- x: Float[ndarray, 'n_x']#
- x_weights: Float[ndarray, 'n_x']#
- y: Float[ndarray, 'n_y']#
- class solprop.modes.slab.SlabMode(half_gap, gas=None, pressure=0.0, *, order=1, polarisation='te', loss=True, cladding=None, temperature=None, susceptibility=None, mixture=None)[source]#
Bases:
_WallPairFillDescribe one mode of a gas-filled hollow planar waveguide, uniform in y.
The plates are at
x = +-aand y is free. The profile iscos(p pi x / 2a)for oddpandsin(p pi x / 2a)for evenpinside the gap and zero outside; the effective index is Laakmann and Steier’s one-wall-pair form with the filled-core contrast (module docstring). Everything the mode integrates is per metre of y (transverse_measure).- Attributes:
- half_gapfloat or ZProfile
Half the plate separation,
a, in m, positive. A path along z is a scale-invariant taper: the profile is a function ofx / a(z).- gasGas or str or None
Legacy gas declaration; None means vacuum unless a mixture is supplied.
- pressurefloat or ZProfile
Legacy gas pressure in bar, non-negative.
- orderint
Mode order
p >= 1; odd orders are symmetric about the mid-plane, so a centred launch couples only to them.- polarisation{‘te’, ‘tm’}
"te"(the default) has the electric field along y, parallel to the plates, and the low loss;"tm"has it along x, normal to them, and a loss larger by the wall’seps_cl / eps_cofor glass. The two are distinct modes with their own effective index.- lossbool or float or callable
Shared hollow-mode policy: model loss, no loss, a non-negative model scale, or an absolute power attenuation in 1/m.
- claddingGlassIndex or complex or None
Plate index, positive imaginary part for absorption: a glass, a metal of
solprop.physdata.metals, or a constant complex number. None selects fused silica.- temperaturefloat, ZProfile or None
Positive legacy fill temperature in K, or a path of it along z in m, which the density follows.
None(the default) is 293.15 K for a gas and the mixture’s own beside a mixture; a different one beside it is refused.- susceptibilityGasSusceptibility or None
Explicit legacy gas susceptibility;
Nonetakes the built-in gas’s.- mixtureMixture or None
Ordered material populations; excludes competing legacy fill arguments.
- width_xZProfile
The resolved half-gap path in m. It carries the rectangular guide’s name for its x half-width, which this is, so that the geometry-path walkers of
solprop.modes.protocol.GEOMETRY_PATH_NAMESfind its kinks.- densityZProfile
Total number-density path in m^-3.
- cladding_indexGlassIndex or complex
Resolved plate material.
- model{‘full’, ‘reduced’}
Fixed internally to full, selecting the shared evanescent floor.
References
K. D. Laakmann and W. H. Steier, Applied Optics 15, 1334-1340 (1976), doi:10.1364/AO.15.001334, eq. (5) with
b -> infinity; C. L. Arnold et al., New J. Phys. 12, 073015 (2010), eqs. (2)-(3). The filled-core factoreps_cl / (eps_co s)of the TM-like coefficient follows from grazing-incidence Fresnel reflection; it reduces to the publishedeps_cl / sfor an evacuated core.Examples
>>> from solprop.modes import SlabMode >>> mode = SlabMode(63.5e-6, cladding=1.45) >>> mode.channel_label.display_label, mode.principal_component() ('TE1', 'y') >>> f"{mode.aeff() * 1e6:.3f} um effective width" '84.667 um effective width'
- aeff(z=0.0)[source]#
Return the closed-form effective width, per unit width in y.
The mode protocol’s effective area,
(int V^2)^2 / int V^4, taken over x alone because the guide is uniform in y: an effective width, in m, the same4a/3for every order. It is what the mode-averaged normalisation andgamma' = n2 omega / (c A_eff)read, so a mode-averaged run’s powers come out per metre of y without a second name for the same quantity.- Parameters:
- zfloat, optional
Position in m.
- Returns:
- float
4 a / 3in m.
- at_parameters(values)[source]#
Copy the mode with the supplied gap and fill paths frozen.
- Parameters:
- valuescollections.abc.Mapping
A subset of the declared paths, in m, m^-3 or shared pressure in bar.
- Returns:
- SlabMode
A copy retaining unspecified paths and the same wall model.
- Raises:
- ModeError
If a path is unknown or the half-gap is invalid.
- property azimuthal_order: int[source]#
Return the mode order as the rule’s resolution hint.
- Returns:
- int
p. A slab has no azimuthal coordinate; the x rule’s node bound is the measuredsolprop.modes.quadrature.cartesian_nodes()of it.
- property channel_label: ChannelLabel[source]#
Return the slab family and order.
- Returns:
- ChannelLabel
Family
TEorTM, no azimuthal order, the mode orderpin the radial field – the one index the record carries – andTE1,TM3and so on as the display label. The other polarisation is a distinct mode, not a parity partner, soparitystaysNone.
Examples
>>> from solprop.modes import SlabMode >>> SlabMode(50e-6, order=3, polarisation="tm").channel_label.display_label 'TM3'
- cladding: GlassIndex | complex | None = None#
- cladding_index: GlassIndex | complex#
- dimlimits(z=0.0)[source]#
Return the slab cross-section and its integration bounds in x.
- Parameters:
- zfloat, optional
Position in m.
- Returns:
- tuple
("slab", (-a,), (a,)), in m: one coordinate, y being uniform.
- dneff_domega(omega, z=0.0)[source]#
Return the analytic derivative including core and wall material slopes.
- Parameters:
- omeganumpy.ndarray
Positive frequencies in rad/s.
- zfloat, optional
Position in m.
- Returns:
- numpy.ndarray
Complex index derivative in s/rad; only a slope-free loss callable uses the shared numerical loss derivative.
- field(points, z=0.0)[source]#
Return the unnormalised real Cartesian electric-field components.
- Parameters:
- pointsnumpy.ndarray
(x, y)coordinates in m, shape (n_points, 2); y is ignored.- zfloat, optional
Position in m.
- Returns:
- numpy.ndarray
(E_x, E_y), shape (n_points, 2): the profile onE_yfor TE and onE_xfor TM, zero outside the gap.
- Raises:
- ModeError
If the points are non-finite or have an invalid shape.
- neff(omega, z=0.0)[source]#
Return the effective index with positive imaginary part for attenuation.
- Parameters:
- omeganumpy.ndarray
Positive frequencies in rad/s.
- zfloat, optional
Position in m.
- Returns:
- numpy.ndarray
Complex effective index, shape (n_omega,).
- neff_minus_one(omega, z=0.0)[source]#
Return the refractivity directly from the small square-root argument.
- Parameters:
- omeganumpy.ndarray
Positive frequencies in rad/s.
- zfloat, optional
Position in m.
- Returns:
- numpy.ndarray
Complex
n_eff - 1, without subtracting unity from the index.
- normalisation(z=0.0)[source]#
Return the power per unit width carried by the unnormalised profile.
- Parameters:
- zfloat, optional
Position in m.
- Returns:
- float
eps0 c a / 2in W/m for a unit field amplitude: the vacuum admittance timesint V^2 dx = a, halved.
- property orthogonal_polarisation: SlabMode[source]#
Return the same order with the other polarisation.
- Returns:
- SlabMode
TM for a TE mode and TE for a TM one: a distinct mode with its own effective index and its own operator row.
- property parameter_paths: Mapping[str, ZProfile][source]#
Return the gap and material paths carrying longitudinal variation.
- Returns:
- collections.abc.Mapping
The half-gap path plus the shared fill’s density or pressure paths.
- property polarisation_degenerate: bool[source]#
Return whether the two polarisations share one effective index.
- Returns:
- bool
False: TE and TM take different wall coefficients, so they are distinct modes and need a row each, as the rectangular partners do.
- principal_component(z=0.0)[source]#
Return the nonzero Cartesian electric-field component.
- Parameters:
- zfloat, optional
Position in m; the orientation is fixed.
- Returns:
- str
"y"for TE,"x"for TM.
- property radius_is_constant: bool[source]#
Return the transform’s geometry-constant trait for the slab.
- Returns:
- bool
True when the half-gap path is constant; the historical trait name also serves Cartesian and slab modes.
- property scale_invariant: bool[source]#
Return whether one scalar rescaling represents the geometry along z.
- Returns:
- bool
Always True: one gap is the whole geometry, and the profile is a function of
x / a(z), so a taper rescales the matrices bysqrt(a(0) / a(z))(solprop.modes.quadrature.taper_scale()).
- susceptibility: GasSusceptibility | None = None#
- property transverse_measure: Literal['area', 'per_unit_width'][source]#
Return what this mode’s transverse integrals measure.
- Returns:
- str
"per_unit_width": the normalisation is a power per metre of y andaeff()an effective width, so a run’s powers are W/m and its energies J/m (solprop.modes.protocol.TransverseMeasure).
- solprop.modes.slab.SlabPolarisation#
Name a slab family:
"te"has E along y,"tm"has E along x.alias of
Literal[‘te’, ‘tm’]
- solprop.modes.slab.gaussian_coupling(modes, waist, *, offset=0.0, component=None, z=0.0)[source]#
Return the share of a Gaussian beam’s power each slab mode takes.
The beam is
exp(-((x - offset) / waist)^2)in x, uniform in y, with flat phase and one linear polarisation, component. It is projected onto the modes through the slab rule’s dual basis (solprop.modes.quadrature.mode_matrix()), and each share is the modal power over the beam’s whole power, inside the gap and out: what lands on the plates is lost to every mode, so the shares sum to less than one. A centred beam couples to odd orders only, and a mode polarised across the beam takes nothing.- Parameters:
- modessequence of Mode
Slab modes sharing one gap, non-empty.
- waistfloat
The beam’s 1/e field radius in x, m, > 0.
- offsetfloat, optional
The beam centre’s displacement from the mid-plane, m.
- component{‘x’, ‘y’} or None, optional
The beam’s electric-field direction:
"y"launches TE,"x"TM.None(the default) takes the set’s own component, which is refused for a set carrying both, where one beam cannot be both polarisations.- zfloat, optional
Position along the guide the gap is taken at, m.
- Returns:
- numpy.ndarray
Fraction of the beam’s power per unit width in each mode, shape
(n_modes,), in[0, 1]; zero for a mode of the other polarisation.
- Raises:
- ModeError
If the set is empty, is not a slab set, waist is not positive, or component is
Nonefor a set with both TE and TM modes.
Examples
>>> from solprop.modes import SlabMode, gaussian_coupling >>> modes = [SlabMode(1.0, order=p) for p in (1, 2, 3)] >>> [f"{share:.4f}" for share in gaussian_coupling(modes, 0.735)] ['0.9882', '0.0000', '0.0008'] >>> pair = [SlabMode(1.0), SlabMode(1.0, polarisation="tm")] >>> [f"{share:.4f}" for share in gaussian_coupling(pair, 0.735, component="y")] ['0.9882', '0.0000']
- solprop.modes.slab.gaussian_projection(modes, waist, *, offset=0.0, component=None, z=0.0)[source]#
Project a unit-peak Gaussian beam in x onto slab modes, with signs.
The beam is
exp(-((x - offset) / waist)^2)in V/m, uniform in y, polarised along component. Each entry is the modal amplitude in sqrt(W/m) that beam launches into one mode:(eps0 c / 2) int E(x) e_p(x) dxover the gap, withe_pthe mode’s field normalised to 1 W/m, through the slab rule’s dual basis (solprop.modes.quadrature.mode_matrix()) on a fine Gauss rule. Unlikegaussian_coupling()it keeps the sign each order takes, which a launch needs: an offset beam couples to even orders with the sign of the offset.- Parameters:
- modessequence of Mode
Slab modes sharing one gap, non-empty.
- waistfloat
The beam’s 1/e field radius in x, m, > 0.
- offsetfloat, optional
The beam centre’s displacement from the mid-plane, m.
- component{‘x’, ‘y’} or None, optional
The beam’s electric-field direction:
"y"launches TE,"x"TM.None(the default) takes the set’s own component, which is refused for a set carrying both.- zfloat, optional
Position along the guide the gap is taken at, m.
- Returns:
- numpy.ndarray
Modal amplitudes in sqrt(W/m) per V/m of beam peak, shape
(n_modes,); zero for a mode polarised across the beam.
- Raises:
- ModeError
If the set is empty, is not a slab set, waist is not positive, or component is
Nonefor a set with both TE and TM modes.
Examples
>>> from solprop.modes import SlabMode, gaussian_projection >>> modes = [SlabMode(1.0, order=p) for p in (1, 2)] >>> above = gaussian_projection(modes, 0.735, offset=0.1) >>> below = gaussian_projection(modes, 0.735, offset=-0.1) >>> bool(above[1] > 0), bool(below[1] < 0), bool(above[0] == below[0]) (True, True, True)
- solprop.modes.slab.gaussian_to_per_unit_width(value, w_y)[source]#
Return the per-unit-width value at the centre of a Gaussian beam in y.
The inverse of
per_unit_width_to_gaussian(): a total power in W or energy in J carried byexp(-(y / w_y)^2)in field, withw_ythe 1/e field radius, isvalue / (w_y sqrt(pi / 2))per metre of y at its centre – the number to give a run uniform in y.- Parameters:
- valuefloat
Total power in W or energy in J.
- w_yfloat
1/e field radius in y, m, > 0.
- Returns:
- float
Power in W/m or energy in J/m at the centre.
- Raises:
- ModeError
If w_y is not positive and finite.
Examples
>>> from solprop.modes import gaussian_to_per_unit_width >>> f"{gaussian_to_per_unit_width(10e-3, 2e-3):.4f} J/m" '3.9894 J/m'
- solprop.modes.slab.per_unit_width_to_gaussian(value, w_y)[source]#
Return the total of a per-unit-width quantity spread as a Gaussian in y.
A run uniform in y reports power in W/m and energy in J/m: the value at the centre of a beam that is wide in y. For a beam
exp(-(y / w_y)^2)in field –w_ythe 1/e field radius, the 1/e^2 intensity radius – the total isvalue * w_y * sqrt(pi / 2), becauseint exp(-2 y^2 / w_y^2) dyisw_y sqrt(pi / 2). Power and energy convert alike.- Parameters:
- valuefloat
Power in W/m or energy in J/m at the beam centre.
- w_yfloat
1/e field radius in y, m, > 0.
- Returns:
- float
Total power in W or energy in J.
- Raises:
- ModeError
If w_y is not positive and finite.
Examples
>>> from solprop.modes import per_unit_width_to_gaussian >>> f"{per_unit_width_to_gaussian(1.0, 2e-3):.4e}" '2.5066e-03'