Troubleshooting¶
Splashdown procedures. Every pilot ditches occasionally — what matters is how fast you're back in the air. Find your error below; each entry quotes the exact message (or symptom), explains the cause, and gives the fix.
Stack construction¶
ValueError: need at least a cover and a substrate layer
Every flight needs a sky and a ground:
ValueError: the cover/substrate layer must be uniform and semi-infinite (height=inf)
The first and last layers are the incidence and transmission half-spaces —
add_uniform_layer(np.inf, ...), no patterns, no finite thickness.
ValueError: interior layers must have finite thickness
Only the two outer layers may be np.inf. Give everything in between a
real thickness in meters.
ValueError: topology references N materials but only M provided
Your integer map contains an index with no matching entry. The materials
list must be at least topology.max() + 1 long (index 0 →
materials[0]).
ValueError: patterned layer requires a 'materials' list
add_layer(height, topology, materials) — the third argument isn't
optional.
Source¶
ValueError: first set_source call requires 'wavelength'
The first call must name a wavelength; afterwards it's retained and you can update fields one at a time.
ValueError: polarization must be one of ('linear', 'RCP', 'LCP')
Exactly those strings. A specific linear orientation is
polarization="linear" + linear_pol_angle=....
ValueError: call set_source(...) before simulating
No light, no flight. Define the source first.
Energy balance & convergence¶
RuntimeWarning: Energy balance R+T=... exceeds 1.01
For a lossless structure: unconverged — raise n_orders or use
simulate(auto_converge="once"). If a material is supposed to be
lossy, check its k sign (Ikarus expects \(k>0\) for absorption; gain-sign
data manufactures free energy).
RuntimeWarning: Energy balance R+T=... is far above 1
You flew too close to the sun: at very high n_orders the eigenmode
algebra loses conditioning for high-contrast structures. Counterintuitive
fix: reduce n_orders (or raise resolution). The goal is the
smallest converged order count, not the largest survivable one.
ValueError: Cell resolution too coarse for the requested harmonic orders
The convolution matrix needs ≥ 4*n_orders + 1 real-space samples per
axis. Raise resolution or lower n_orders. (The RCWA façade auto-raises
sampling, so you'll usually meet this only when calling
convolution_matrix directly.)
numpy.linalg.LinAlgError: ... singular matrix
Usually an order parked exactly on a Rayleigh–Wood anomaly (the light
line) in a perfectly lossless structure. Ikarus regularizes these with a
vanishing imaginary loss; if it still bites, nudge wavelength/angle/period
off the exact anomaly or add a whisper of material loss. The
auto-convergence loop catches LinAlgError and stops the sweep gracefully.
Optional dependencies¶
ImportError: inverse.optimize needs pymoo
pip install "ikarus-rcwa[inverse]"
ImportError: HDF5 I/O requires the 'h5py' package
pip install "ikarus-rcwa[io]"
ModuleNotFoundError: No module named 'matplotlib'
pip install "ikarus-rcwa[viz]"
Results & fields¶
KeyError: order (p, q) not in truncated set
order_index(p, q) asked for a harmonic outside \(-M..+M\). Increase
n_orders or request an order inside the kept set.
Exit angles are NaN
Not an error — NaN marks an evanescent order (a ghost lane carrying
no far-field power). Mask with np.isfinite(...) before plotting.
Field maps look empty or uniform
Three usual suspects: no solve ran yet (call simulate() first); you
reconstructed at a depth inside the cover/substrate instead of the
patterned layer (check the z convention: 0 = cover/first-layer interface,
increasing downward); or nx/ny is too coarse to show the detail.
Performance¶
Sweeps/optimization crawl on a many-core machine
BLAS thread oversubscription — the classic. Pin one thread before importing NumPy:
import os
for v in ("OMP_NUM_THREADS", "OPENBLAS_NUM_THREADS",
"MKL_NUM_THREADS", "VECLIB_MAXIMUM_THREADS"):
os.environ.setdefault(v, "1")
import numpy as np
One big solve is slow
The eigensolve is \(\mathcal{O}(P^3)\). Confirm n_orders isn't
over-dialed (run the
convergence ritual),
keep 1-D problems 1-D, and for genuinely large \(M\) let BLAS use its
threads.
Still in the water?¶
Open an issue with a minimal reproducer:
github.com/CAVITYtechnologies/ikarus/issues.
Include the structure definition, n_orders, resolution, the source, and the
full warning or traceback — rescue is much faster with coordinates.