meanas/docs/api/waveguides.md

153 lines
7.8 KiB
Markdown
Raw Normal View History

2026-04-18 15:05:35 -07:00
# waveguides
::: meanas.fdfd.waveguide_2d
::: meanas.fdfd.waveguide_3d
::: meanas.fdfd.waveguide_cyl
## Overlap measures and normalization
`waveguide_2d.inner_product(..., measure="physical", conj_h=True)` uses real
Yee widths for physical Poynting power. `measure="stretched"` keeps complex
widths for coordinate reaction. `lorentz_metric` and `lorentz_overlap` default
to the stretched measure. Use the same grid and measure when constructing and
using dual fields. A real overlap grid still defines a consistent constructed
dual basis, even when the eigenproblem uses a separate PML grid.
`normalized_fields_e/h(..., normalization="lorentz")` normalizes unconjugated
self-reaction to one. This fixes phase up to a sign and is distinct from unit
forward power, which remains the default. Zero-power or self-orthogonal modes
raise `ValueError`; open self-orthogonal modes require paired primal/dual
normalization through `ModeBasis`.
## Targeted and reproducible mode solving
For modes near an effective index guess, use `solve_modes_near` with
`target_wavenumbers=[omega * n_guess]`. It targets the electric beta-squared
operator at `(omega * n_guess)**2`; `solve_modes_near_beta` instead targets the
first-order signed-beta operator. Both use the LU shift-invert backend and
support `eigensolver_opts={"v0": starting_vector}`. Factorization cost and
memory depend on the grid, so this is not universally faster than indexed
solving. `solve_modes` keeps its global mode-number semantics and now accepts
`rng` or `v0` for reproducible initialization.
`waveguide_3d.mode_from_2d` accepts a supplied transverse electric eigenvector
and reuses field reconstruction, normalization, numerical-dispersion
correction, Yee staggering, rotation, and full-grid embedding without solving
an eigenproblem.
## Interface and sampled-taper scattering
All scattering matrices use outgoing rows and incoming columns, ordered
`[left, right]`:
```text
[b_left ] [R_left T_right_to_left] [a_left ]
[b_right] = [T_left_to_right R_right] [a_right]
```
`get_s` and `get_abcd` require explicit `dxes`. Mixed Petrov-Galerkin testing is
the default: left electric duals test H continuity, and right magnetic duals
test E continuity. Both incidence directions are solved together with full
projection matrices. Mixed scattering supports unequal mode counts.
`formulation="galerkin"` selects equal-count left testing of both equations.
Neither formulation silently clips transmission. The optional `force_nogain`
and `force_reciprocal` flags are numerical projections, not general physical
tests for arbitrary open or evanescent modal coordinates.
`get_taper_s` replaces finite-difference CMT with half propagation in the left
basis, a midpoint interface, and half propagation in the right basis for each
sampled interval. Redheffer composition avoids growing passive backward
transfer branches. Refine section sampling and modal/PML bases to establish
convergence. The ineffective `rtol`, `atol`, and `max_step` arguments have been
removed. The existing `eme_taper_cmt.py` example filename is retained.
```python
prepared = eme.prepare_taper(sections, dxes)
s_original = eme.evaluate_taper_s(prepared)
s_longer = eme.evaluate_taper_s(prepared, z_coords=prepared.z_coords * 1.2)
s_changed_beta = eme.evaluate_taper_s(
prepared, wavenumber_matrices=beta_matrices,
)
```
`PreparedTaper` owns read-only copies of phase-aligned interface data. Beta
matrix overrides have shape `(section, mode, mode)` in the original supplied
section bases; recorded basis transforms are applied automatically. Explicit
backward branches require backward beta overrides when forward beta is changed.
Evaluation performs no field overlaps or eigensolves. Length sweeps reuse the
sampled model; wavelength sweeps with reused fields are explicitly frozen-basis
approximations. Reprepare when fields, duals, grids, or formulations change.
`cascade_s(left, right, internal_modes=...)` connects spatially ordered S
matrices, including unequal external ports. Public `abcd_to_s` and `s_to_abcd`
use `[f_right, b_right] = ABCD @ [f_left, b_left]` and require equal port counts.
`get_taper_abcd` converts the stable S result; zero transmission or an
unrepresentable transfer matrix raises `LinAlgError`. Prefer S for long lossy
devices. Singular interface and cascade systems also raise contextual errors
rather than silently substituting pseudoinverses.
::: meanas.fdfd.eme
## Orientation bias under modal truncation
Mixed testing is a projected approximation: H continuity is tested on the left
and E continuity on the right. Swapping the ports changes the testing spaces
when the retained modal subspaces are incomplete. This effect survives checks
of reciprocity and unitarity.
A reproducible Maxwell counterexample is a uniform isotropic medium with two
degenerate linear polarizations. Keep one polarization on each port, rotated
so their overlap is `a=0.8`. There is no material interface: true reflection is
zero and transmission into the retained receiver is `a`. The other polarization
carries the remaining transmitted power, `1-a**2=0.36`.
| Calculation | R_left | R_right | T_left_to_right | T_right_to_left |
| --- | ---: | ---: | ---: | ---: |
| Exact full basis, then restrict ports | 0 | 0 | 0.8 | 0.8 |
| Truncated mixed | 0.219512 | -0.219512 | 0.975610 | 0.975610 |
| Swap ports, mixed, then reorder | -0.219512 | 0.219512 | 0.975610 | 0.975610 |
| Truncated left Galerkin | 0 | 0 | 1.25 | 0.8 |
| Euclidean E/H least squares | 0 | 0 | 0.8 | 0.8 |
An independent driven 3D FDFD solve with PML agrees with the exact reference
from either incidence direction: transmission is 0.8 within `1e-12`, with
reflection below `2e-8` in the test fixture. Keeping both polarizations makes
mixed testing match the exact complete scattering matrix and restores
port-relabeling covariance.
For the single retained polarization, mixed testing yields
`r=(1-a**2)/(1+a**2)` and `t=2*a/(1+a**2)`. The spurious reflection is quadratic
in a small angle between adjacent retained polarizations. However, longitudinal
refinement alone is insufficient: rotating a single retained vector through a
uniform degenerate medium makes the sampled chain approach artificial following
of that vector (`|T|` approaches 1), while the physical endpoint overlap remains
0.8. Keeping the complete degenerate block recovers the physical result at every
sampling density tested.
Two tempting corrections are insufficient. Averaging the two port orientations
cancels reflection in this example but leaves transmission at 0.975610. Plain
Euclidean E/H least squares gives the correct uniform-medium result, but is not
a general replacement. A second fixture uses exact degenerate modes of diagonal
positive epsilon/mu tensors, with electric scaling `(1,2)` on the left and
`(1,3)` on the right and a 30-degree polarization rotation on both ports. After
single-mode truncation, least squares has unequal directional transmissions
(approximately 0.850839 and 1.092163) and a maximum singular value of 1.104947.
The complete Fresnel solution is reciprocal and lossless.
The mixed default remains unchanged. Retain complete coupled/degenerate blocks
when the geometry can mix them, check modal-basis convergence as well as section
sampling, and compare against independent full-field results. Neither orientation
averaging nor gain/reciprocity postprocessing recovers omitted-channel physics.
Orientation discrepancy is a useful diagnostic, not a bound on transmission
error. These examples use real power-orthonormal propagating modes; for general
complex modes, the reciprocity constraint involves the modal orthogonality
matrix, as derived by [Svendsen, Haakestad, and Skaar](https://arxiv.org/abs/1301.2458).
Reproduce the analytic, full-basis, candidate-formulation, taper-refinement, and
driven-FDFD checks with:
```sh
OPENBLAS_NUM_THREADS=1 python -m pytest meanas/test/test_eme_orientation.py -q
```