Result: agreement within 0.1% for the tested resistor fixtures. Simulated directly at the element, the resistance
agrees within 0.1% in its real part from 0.5 to 6 GHz. The small parallel reactance
comes from the probe box. The result does not depend on the resistor value (30-300 Ω), the cells
along or across the current (1-8), caps, or whether the element is a plain LumpedElement or a
passive LumpedPort. A lossy material block of the same resistance behaves identically.
An apparent frequency-dependent error seen through a test fixture is a de-embedding artifact. It scales with fixture length and is independent of R, the element type and the mesh. An earlier estimate of "+10 % at 2.4 GHz" came from de-embedding a microstrip test line against a differently meshed reference line and was wrong. Nothing needs to be reported upstream as a bug. The script and data here are for anyone who wants to check.
Reproduction
python/examples/lumped_resistor_test.py uses only openEMS, CSXCAD and numpy:
python python/examples/lumped_resistor_test.py --kind lumped --R 100 # upstream openEMS (CPU)
python python/examples/lumped_resistor_test.py --kind port --R 50 --engine gpu # openEMS GPU forkFixture. Two PEC plates (length a, width w) are a gap g apart in z, in free space with MUR boundaries. A 50 Ω lumped port drives the gap at x = 0, and the device under test (DUT) bridges it at x = a. The DUT kinds are:
lumpedandlumped-nocaps:AddLumpedElement(ny=2, caps=True/False, R=R)port: a passiveLumpedPortwithexcite=0material: a block with κ = g / (R w t)
Each case needs three runs: open (no DUT), short (DUT replaced by metal) and the DUT. The DUT impedance follows from open-short de-embedding:
Y'_m = 1/Z_m − 1/Z_open, Y'_s = 1/Z_short − 1/Z_open, Z_dut = 1/Y'_m − 1/Y'_sFor a passive port as the DUT, the script also reports −U/I simulated at the DUT itself. This is the voltage and current of the element's own probes, with no fixture in between. The excitation is a DC-free Gaussian derivative, and the end criterion is −60 dB. All 14 cases of the table below ran in 8 s on the openEMS Metal GPU fork. The CPU engine gives the same numbers, only slower.
Data (Z_dut / R, a = w = g = 1 mm, 4 × 4 cells unless noted)
| Case | 1 GHz | 2.4 GHz | 4 GHz | 6 GHz |
|---|---|---|---|---|
| Passive port, −U/I at the element, R = 100 Ω | 1.000 | 1.000 − 0.007j | 0.999 − 0.017j | |
| Passive port, −U/I at the element, R = 50 Ω | 1.000 | 1.000 − 0.008j | 0.998 − 0.020j | |
| Lumped (caps), fixture de-embedded, R = 30 / 100 / 300 Ω | 0.999 | 0.993 | 0.981 | 0.959 |
| Lumped, 2 × 2 cells | 0.999 | 0.993 | 0.979 | 0.954 |
| Lumped, 8 × 8 cells | 0.999 | 0.994 | 0.982 | 0.961 |
| Lumped, 1 cell along the current | 0.998 | 0.990 | 0.972 | 0.937 |
| Lumped, 8 cells along the current | 0.999 | 0.994 | 0.983 | 0.962 |
| Lumped, 1 cell across | 0.999 | 0.994 | 0.983 | 0.962 |
Lumped, caps=False |
0.999 | 0.993 | 0.981 | 0.959 |
| Passive port as DUT (de-embedded) | 0.999 | 0.993 | 0.981 | 0.959 |
| Lossy material block (κ) | 0.999 | 0.993 − 0.002j | 0.981 − 0.004j | 0.958 − 0.005j |
| Fixture gap 2 mm | 0.998 | 0.990 | 0.972 | 0.937 |
| Fixture plates a = 0.5 mm | 1.000 | 0.997 | 0.992 | 0.983 |
Reading the table.
- The de-embedded value shows a factor 1 − k f² that is the same for every R, every element type (lumped with or without caps, port, lossy material) and every mesh. It changes only with the fixture size: a = 0.5 mm gives 0.983 at 6 GHz, a = 1 mm gives 0.959, and a 2 mm gap gives 0.937. That is the signature of the open-short model's lumped assumption failing on a fixture that is a short transmission line. The resistor has nothing to do with it.
- Simulated at the element, the real part agrees within 0.1% in these fixtures. The imaginary part (−0.7 % of R at 2.4 GHz, −1.7 % at 6 GHz) corresponds to a parallel capacitance of about 5 fF from the probe box.
Consequences for Fairbeam
- No compensation is needed, so
Simulation.lumped_resistor(..., compensate=...)was not added. - Terminated ports are exact terminations. In any case, Fairbeam's S-matrix does not depend on
them: with every port driven it is assembled as
S = B A^-1, which is exact for any termination. Only a partial excitation (b_i/a_j) assumes matched terminations. - The Wilkinson output-match residual (VALIDATION.md, section 8) is therefore not a resistor modeling error. The same layout with a lossy-material resistor body instead of the lumped element gives the same odd-mode impedance: 34.2 + j3 Ω, against 34.1 + j3 Ω.