rfsurrogates: edge_coupled_bpf
Surrogate model of one passive microwave device family: edge-coupled (parallel-coupled) microstrip band-pass filter, Chebyshev N = 3 (0.5 dB ripple), 4 coupled-line sections. It maps the geometry vector p = (w1, w2, g1, g2, l1, l2, eps_r, h) to the complex S11 and S21 on 3-7 GHz (0.02 GHz steps, 201 points), substrate RO4350B (eps_r 3.66, h 0.508 mm, tan d 0.0037), copper as a PEC sheet.
Model: S = S_prior + DeepONet(p, f). S_prior is an analytic coupled-line model (Pozar coupled-line synthesis, Kirschning-Jansen coupled microstrip, Hammerstad open ends, Kobayashi dispersion). The DeepONet correction has 64 basis functions, a frequency warp, reciprocity by construction (one S21 head) and a passivity penalty. Stage A pretrains it on 20,000 prior samples (3 substrates); stage B fine-tunes it on Palace FEM solves. Five seeds per ensemble. A DeepONet trained from scratch on the same data is published next to it.
Code, training, checker and contributor guide: https://github.com/benjhardy/rfsurrogates. Browser demo: https://benjhardy.github.io/filter-surrogate/.
Files
| file | content |
|---|---|
ckpt/stageB_seed0..4.pt |
prior + DeepONet ensemble (the default model) |
ckpt/scratch_seed0..4.pt |
DeepONet from scratch, prior off |
ckpt/stageA_seed0..4.pt |
stage-A pretraining on the prior (start point for new data) |
ckpt/mlp_seed0..4.pt |
plain MLP baseline |
weights.json |
stage-B and scratch ensembles as base64 float32 for the browser page (web/surrogate.js) |
results/preds_*.npz |
held-out predictions behind the tables below |
Load: python tools/fetch.py --family edge_coupled_bpf in the code repo, then python core/inverse.py --f0 5.2 --bw 0.5
or python core/predict.py && python core/eval.py.
Design box and validity
| parameter | unit | low | high |
|---|---|---|---|
| w1 | mm | 0.6184 | 1.1484 |
| w2 | mm | 0.7540 | 1.4003 |
| g1 | mm | 0.1230 | 0.2283 |
| g2 | mm | 0.4127 | 0.7664 |
| l1 | mm | 7.2756 | 9.8435 |
| l2 | mm | 7.2445 | 9.8013 |
| eps_r | 1 | 3.6600 | 3.6600 |
| h | mm | 0.5080 | 0.5080 |
Validity rule: clearance(p) > 0.05 mm with clearance = min(g1 - max(0, (w2 - w1)/2), g2 - max(0, (w1 - w2)/2), g1 - max(0, (W50 - w1)/2)) [mm]. Designs that fail it
are fused (shorted) layouts, not filters. They are not in the training data and the model is not defined there.
Inside the box most designs are detuned filters; 20 of the 26 held-out designs have a split passband.
Data
Data index version 8cae666b9dac (sha256 prefix of data_index/edge_coupled_bpf/manifest.jsonl):
261 training records (80/10/10 split by sample, split seed 0), 10 holdout
records at the finer holdout fidelity, 10 coarse twins of the holdouts. Records: rfsurrogates/samples.
| split | solver | fidelity | records |
|---|---|---|---|
| holdout | palace | medium | 10 |
| train | palace | coarse | 261 |
| twin | palace | coarse | 10 |
Contributors:
- benjhardy: 261 train (coarse), 10 twin (coarse), 10 holdout (medium)
Accuracy on 26 held-out designs (same fidelity as training)
| method | passband |S21| error, dB mean / max | |f0 error| MHz mean / max | |BW error| MHz mean | |S11| linear mean |
|---|---|---|---|---|
| prior only (analytic) | 2.86 / 14.0 | 61.0 / 113 | 114 | 0.050 |
| prior + DeepONet correction (stage B) | 0.52 / 4.0 | 7.9 / 34 | 11 | 0.011 |
| DeepONet from scratch, same data | 0.32 / 1.9 | 4.2 / 13 | 27 | 0.012 |
| plain MLP p -> S | 2.49 / 11.5 | 29.4 / 107 | 76 | 0.037 |
Passband = within 3 dB of the per-sample peak |S21|; f0 = |S21|^2-weighted centroid. Query time on a CPU: 4.5 ms (batch 1) or 0.33 ms (batched), against 663 s for one Palace solve. Ensemble spread vs error: Pearson r = 0.55, mean spread 0.22 dB against mean error 0.52 dB (the spread underestimates the error).
Fidelity: model error next to mesh error
The training data is on the coarse production mesh. On 10 designs solved at the medium holdout mesh as well:
| comparison | N live | passband |S21| dB mean / max | |f0 err| MHz mean / max | |S11| lin | |---|---|---|---|---| | model vs medium | 10 | 0.91 / 3.9 | 38 / 55 | 0.027 | | coarse vs medium | 10 | 1.03 / 3.8 | 35 / 55 | 0.025 | | model vs coarse | 10 | 0.52 / 2.1 | 7 / 26 | 0.010 | | prior vs medium | 10 | 1.25 / 5.0 | 18 / 34 | 0.032 | | prior vs coarse | 10 | 2.86 / 10.1 | 52 / 89 | 0.051 |
The model's error against the medium mesh is about the size of the coarse mesh's own error. At this data size the mesh bias is the larger error term.
Learning curve
| N train | prior only | prior + DeepONet | DeepONet from scratch | plain MLP |
|---|---|---|---|---|
| 10 | 2.86 dB / 61 MHz / 0.050 | 1.83 +- 0.55 dB / 35 MHz / 0.032 (5 seeds) | 9.49 +- 5.46 dB / 185 MHz / 0.204 (5 seeds) | - |
| 25 | 2.86 dB / 61 MHz / 0.050 | 1.16 +- 0.26 dB / 26 MHz / 0.022 (5 seeds) | 2.62 +- 0.44 dB / 54 MHz / 0.078 (5 seeds) | - |
| 50 | 2.86 dB / 61 MHz / 0.050 | 0.82 +- 0.15 dB / 20 MHz / 0.017 (5 seeds) | 1.31 +- 0.36 dB / 24 MHz / 0.038 (5 seeds) | 9.98 +- 0.74 dB / 127 MHz / 0.108 (5 seeds) |
| 100 | 2.86 dB / 61 MHz / 0.050 | 0.62 +- 0.02 dB / 12 MHz / 0.013 (3 seeds) | 0.49 +- 0.04 dB / 9 MHz / 0.019 (3 seeds) | - |
| 150 | 2.86 dB / 61 MHz / 0.050 | 0.60 +- 0.01 dB / 12 MHz / 0.013 (3 seeds) | 0.40 +- 0.01 dB / 8 MHz / 0.015 (3 seeds) | - |
| 209 | 2.86 dB / 61 MHz / 0.050 | 0.54 +- 0.02 dB / 9 MHz / 0.012 (3 seeds) | 0.34 +- 0.00 dB / 5 MHz / 0.013 (3 seeds) | 2.58 +- 0.11 dB / 33 MHz / 0.045 (3 seeds) |
The prior helps below about 50 training samples; from about 100 samples the model trained from scratch is better
in passband |S21|. Both ensembles are published. core/inverse.py and the browser page use the stage-B ensemble;
at the full data size the scratch ensemble has the lower held-out error (accuracy table).
Limits
- Simulated against simulated (Palace FEM). Nothing here was measured.
- One substrate (RO4350B). eps_r and h are inputs but constant in the Palace data. Transfer to another substrate (stage C) is not tested: no second substrate in the Palace data: a stage-C run here would be same-substrate few-shot, not a transfer test.
- Valid inside the box and the validity rule only. Outside the box the model extrapolates without warning.
- Mesh bias of the coarse training data: see the fidelity table.
- Stage-B training stats: 209 train / 26 validation / 26 test samples.
Licence
Weights and code: Apache-2.0. Training records: CC-BY-4.0 (see rfsurrogates/samples).