Skip to content

fix(palace): restore airbox in notebooks so absorbing BC is not on metal - #200

Merged
vvahidd merged 1 commit into
mainfrom
fix/palace-missing-airbox
Jul 25, 2026
Merged

fix(palace): restore airbox in notebooks so absorbing BC is not on metal#200
vvahidd merged 1 commit into
mainfrom
fix/palace-missing-airbox

Conversation

@vvahidd

@vvahidd vvahidd commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Why

palace_microstrip was producing S-parameters far too lossy and reflective for a simple microstrip — S21 = -32.6 dB and S11 = -7.8 dB at 100 GHz, so |S11|² + |S21|² = 0.17 and 83% of the power was being absorbed. This was initially attributed to a Palace 0.17.0 upgrade, but the mesh is built client-side, so a solver upgrade can't remove a material region — and a missing material region is what it turned out to be.

Cause

get_stack(air_above=...) has been deprecated and silently ignored since the airbox refactor (f17f9ca); it only emits a warning, which is easy to miss in a notebook. Several notebooks still passed it and never called set_airbox(), and MeshConfig.airbox_margin defaults to 0.0, so no air region was created at all.

The mesh box then collapses to the design footprint and Palace's 2nd-order absorbing boundary is applied directly to the outer dielectric faces (sio2__None / sin__None) rather than to an airbox. For the microstrip that put the absorbing wall 1.9 µm above the trace (TopMetal2 top z=14.03, box top z=15.93) and flush against the ground-plane edge at y=±27 µm. In the quasi-TEM near field that behaves as a resistive sheet. The missing air also raises ε_eff, pulling Z0 below the 50 Ω ports.

Rebuilding the notebook reproduces the bad run's physical groups exactly (same 11 groups, same numbering); adding set_airbox() restores the air volume and moves the absorbing BC onto air__None.

Changes

  • Add set_airbox(margin_x=50, margin_y=50, z_above=100, z_below=100) — matching the values already used by the working CPW/inductor notebooks — and drop the dead air_above from palace_microstrip, palace_branch_line_coupler, palace_cpw_via, palace_width_sweep, and _palace_cpw. palace_cpw_lumped already called set_airbox(), so only its dead argument is removed.
  • mesh() now logs a warning when an absorbing boundary exists but no volume is air-like, so this fails loudly instead of yielding plausible-looking but badly wrong S-parameters.

Decisions

  • The guard warns from mesh() only — not write_config() / validate_mesh() / run() — so it fires once, before any cloud submit.
  • Used logger.warning rather than warnings.warn to match the local idiom in mesh() (the adjacent >75k-node advisory and the existing set_stack(air_above=...) deprecation).
  • An earlier version recorded outer-face names in groups.py to check which material each absorbing face touched. Simplified to checking groups["volumes"] for an air-like region, which needs no new plumbing. Slightly weaker: a stack with an internal air gap but no airbox would not be flagged.
  • Un-deprecating get_stack(air_above=...) was considered and rejected in favour of migrating callers to the current API.

Note

Notebook outputs are not regenerated and still show the old values; the affected notebooks need a re-run to refresh them.

`get_stack(air_above=...)` has been deprecated and silently ignored since the
airbox refactor (f17f9ca), but several notebooks still relied on it and never
called `set_airbox()`. With no air region the mesh box collapses to the design
footprint, so Palace's 2nd-order absorbing boundary is applied straight to the
outer dielectric faces (`sio2__None` / `sin__None`) instead of an airbox.

For palace_microstrip that put the absorbing wall 1.9 um above the trace and
flush against the ground-plane edge. In the quasi-TEM near field it behaves as
a resistive sheet: S21 = -32.6 dB and S11 = -7.8 dB at 100 GHz, with
|S11|^2 + |S21|^2 = 0.17, i.e. 83% of the power absorbed by the walls. The
missing air also raises eps_eff, pulling Z0 below the 50 ohm ports.

Add `set_airbox()` to the affected notebooks and drop the dead `air_above`
argument. Also warn from `mesh()` when an absorbing boundary exists but no
volume is air-like, so this fails loudly instead of producing plausible-looking
but badly wrong S-parameters.

Notebook outputs are not regenerated here and still show the old values.
@github-actions github-actions Bot added the bug Something isn't working label Jul 25, 2026
@vvahidd
vvahidd merged commit 604870d into main Jul 25, 2026
13 checks passed
@vvahidd
vvahidd deleted the fix/palace-missing-airbox branch July 25, 2026 05:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant