Solvers and settings¶
Global state¶
CAMFR keeps its settings in one global state: the wavelength, the number of
modes, the polarisation, the solvers, PML and walls. The set_* functions
change it for everything that follows in the process. Some settings (PML,
walls) are read when a waveguide is created, others (wavelength, N,
solvers) when it is calculated. So set PML and walls before defining the
structures they apply to.
Waveguides and stacks cache their results and recalculate only when a relevant
setting changed. Interface matrices are kept in a global cache: call
free_tmps() between independent calculations, or at the end of
an inner loop, to release them.
Number of modes and convergence¶
set_N(n) sets the number of modes in each waveguide’s expansion. Results
converge as N grows; check it by repeating a calculation with a larger N.
The field example of the tutorial gives
|
|R|² |
|T|² |
|---|---|---|
20 |
0.3588 |
0.1144 |
40 |
0.3557 |
0.1151 |
60 |
0.3557 |
0.1153 |
Computation time grows roughly as N³ (matrix operations), so symmetry that
halves the structure (below) also halves N, a factor of about eight.
Boundaries: walls and PML¶
Slabs are enclosed by walls at x = 0 and x = width, electric by default.
Change them for the slabs defined afterwards with
set_lower_wall() / set_upper_wall()
(slab_E_wall, slab_H_wall, slab_no_wall), or per slab with
Slab.set_lower_wall / set_upper_wall. Sections have
set_left_wall() / set_right_wall()
(E_wall, H_wall), and their top and bottom walls are those of their slabs.
Symmetry. A structure symmetric about a plane can be cut in half with a
wall on that plane. For TE, a magnetic wall (slab_H_wall) keeps the even
modes (including the fundamental) and an electric wall the odd ones; for TM it
is the other way round. Only the modes of that symmetry are then found, and no
PML is needed on the symmetry plane.
PML. Closed walls reflect everything that leaves the waveguide, and the
modes of a closed box can sit exactly at cutoff (CAMFR warns “mode close to
cutoff”). Open structures therefore need perfectly matched layers:
set_lower_PML(p) gives the first layer of each subsequent slab an imaginary
thickness p*1j; p is negative (absorbing), typically -0.01 to -0.1.
Likewise set_upper_PML (last layer), set_left_PML / set_right_PML
(Sections) and set_circ_PML (the cladding of Circ). The PML must be thick
enough, and the cladding it sits on far enough from the core, not to disturb
the guided modes; vary both to check.
Mode solvers for Slab and Circ¶
set_solver() chooses how the modes of Slab and Circ
waveguides are found:
track(default)Finds the modes of the corresponding lossless structure, then tracks them as the losses and the PML are switched on. Fast and reliable for dielectric waveguides.
seriesEstimates the modes from a plane-wave (Fourier) expansion, then refines each with the exact dispersion relation. Suits lossy and metallic structures. The number of plane waves is
N × set_mode_surplus(default 1.2).ADRFinds the modes as the zeros of the dispersion relation inside a contour in the complex plane (argument principle), independent of the lossless structure.
ASR,stretched_ASRSeries expansion with adaptive spatial resolution (optionally with stretched coordinates);
set_eta_ASRsets the stretching. Implemented for TM only: for TE they fall back totrack.
The mode search can be tuned with set_precision() (guided
modes) and set_precision_rad() (radiation modes): a finer scan
misses fewer modes. set_degenerate(),
set_chunk_tracing() and set_orthogonal() help
with degenerate or badly separated modes.
Metallic structures¶
In metal-clad structures light is often guided in the low-index regions,
for example air gaps between metal layers. The default slab solver looks for
modes guided by high-index cores and can miss these. Call
set_low_index_core() (True) for such structures (or use the
series solver); see
issue #2.
The Section solver¶
A Section (2D cross-section) is solved in two stages:
Estimation: a plane-wave expansion with
M1terms gives estimates of the effective indices. This stage takes most of the time.Refinement: each estimate is refined with a dispersion relation built from
M2modes of each slab.
Section(expression, M1, M2) sets both; the defaults are N × mode_surplus
and N. set_section_solver() selects the estimation algorithm:
L (default, Li’s Fourier factorisation), L_anis (anisotropic materials),
NT, OS, ASR_2D and ASR_2D_stretched.
set_mode_correction() chooses which estimates are refined
(full refines all modes).
Speed. If the effective indices are roughly known (from an earlier run, a
slab approximation or another solver), give them with
section.set_estimate(n_eff), one per wanted mode: the estimation stage is
skipped, which is often 40 times faster for the same result.
set_calc_field_profiles(False) skips the field profiles when only the
effective indices are needed.
Stability of stacks¶
Scattering matrices are computed with the S-matrix scheme, which is stable for
thick structures. Near-singular interfaces can be handled with
set_stability() (extra equilibration or SVD), and
set_unstable_exp_threshold() controls when growing
exponentials are dropped.
Known problems¶
Open solver issues are tracked on GitHub with the
solver label,
among them:
metal/air splitters with unphysical reflection (#1),
slab_no_walland transparent boundary conditions failing in the slab solver (#5),Circwith theADRsolver and a PML hanging (#4).