Advertise DC resistance only; frame f>0 as a skin-only estimate
Build PCM package / build (push) Successful in 10s

Skin resistance is a small fraction of real AC impedance (proximity
and inductance dominate), so AC must not appear in the descriptions.
README headline, PCM/plugin metadata, pyproject, dialog note, CLI
help and the summary label now all say: skin-only lower bound on the
resistance rise, not an AC impedance simulation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
janik
2026-07-22 16:34:21 +07:00
parent d7c3089031
commit b806d31a9a
7 changed files with 29 additions and 21 deletions
+17 -11
View File
@@ -1,15 +1,17 @@
# Fill Resistance — KiCad 10 plugin
Computes the **DC or AC resistance of copper zone fills and traces**
Computes the **DC resistance of copper zone fills and traces**
between two contacts, **single- or multi-layer**: the chosen net's fills
(teardrops included) and tracks on the selected copper layers are
solved as coupled finite-difference sheets linked by the net's **via
and through-hole-pad barrels** (18 µm plating, configurable). At a user-set **frequency** the exact 1D foil/barrel
skin-effect correction is applied (AC results are a rigorous lower
bound; see *Model & limits*). Shows per-layer rasterized maps,
potential, current density, and **power density**, and reports **per-via
currents** (via ampacity!) and total dissipation at a **selectable test
current**. PNGs + a text summary are saved per run.
and through-hole-pad barrels** (18 µm plating, configurable). Shows
per-layer rasterized maps, potential, current density, and **power
density**, and reports **per-via currents** (via ampacity!) and total
dissipation at a **selectable test current**. PNGs + a text summary are
saved per run. An optional **skin-effect correction** (exact 1D
foil/barrel solution at a user-set frequency) estimates the resistive
skin rise only — it is **not** an AC impedance simulation (no proximity
effect, no inductance; see *Model & limits*).
![Current density on a two-layer demo net](docs/img/demo-current.png)
*Real output on a synthetic two-layer net: current from a soldered
@@ -236,10 +238,14 @@ SWIG API. Requires KiCad **10.0.1+**.
isolated foil), and the analogous correction for the 18 µm barrel wall.
Enter one frequency per run (e.g. a switching harmonic, with its RMS
amplitude as the test current); suffixes `k`/`M` are accepted.
**Caveat:** only through-thickness crowding is modeled. Lateral
(proximity-effect) redistribution needs a magneto-quasistatic solver
and is not captured — since the resistance-driven distribution is the
minimum-dissipation one, AC results are a rigorous **lower bound**.
**Caveat:** this is **not an AC impedance simulation** — skin
resistance is only a small part of real AC behavior. Only
through-thickness crowding is modeled: lateral (proximity-effect)
redistribution needs a magneto-quasistatic solver and is not
captured — since the resistance-driven distribution is the
minimum-dissipation one, the f > 0 resistance is a rigorous **lower
bound** — and inductance, usually the dominant term of a real AC
impedance, is absent entirely.
Rule of thumb for 70 µm foil: skin is negligible below ~300 kHz
(δ = 173 µm at 142 kHz), ~+11 % at 1 MHz. At f > 0 the |J| maps are
referenced to the skin-reduced conduction-equivalent thickness
+4 -4
View File
@@ -137,10 +137,10 @@ class _Dialog(QDialog):
lay = QVBoxLayout(self)
lay.addLayout(form)
note = QLabel("Multiple layers are coupled through the net's "
"via/through-pad barrels. At f > 0 the foil-thickness "
"skin effect is applied per layer; lateral (proximity) "
"redistribution is not modeled, so AC results are a "
"lower bound.")
"via/through-pad barrels. f > 0 applies only the "
"foil-thickness skin effect (a lower bound on the "
"resistance rise) - not an AC impedance simulation: "
"proximity and inductance are not modeled.")
note.setWordWrap(True)
note.setStyleSheet("color: gray; font-size: 10px;")
lay.addWidget(note)
+2 -1
View File
@@ -59,7 +59,8 @@ def write_summary(outdir: Path, problem: Problem, stack: RasterStack,
+ (f"{result.freq_hz:g} Hz (skin depth {result.skin_depth_um:.0f} um)"
if result.freq_hz > 0 else "DC")),
f"RESISTANCE: {result.R_ohm * 1000:.6g} mOhm"
+ (" (AC LOWER BOUND: lateral/proximity redistribution not modeled)"
+ (" (SKIN-ONLY LOWER BOUND: no proximity/inductance - "
"not AC impedance)"
if result.freq_hz > 0 else ""),
f"VOLTAGE DROP: {result.R_ohm * result.i_test * 1000:.4g} mV "
f"@ {result.i_test:g} A",
+2 -1
View File
@@ -26,7 +26,8 @@ def main(argv=None) -> int:
help="test current [A] (default: config TEST_CURRENT_A)")
ap.add_argument("--freq", type=parse_frequency, default=0.0,
help="frequency, e.g. 142k or 1.5M (default: DC). "
"AC results are a lower bound (skin per foil only)")
"Skin resistance only, a lower bound - not AC "
"impedance (no proximity, no inductance)")
ap.add_argument("--cell-um", type=float, default=None,
help="force grid cell size [um]")
ap.add_argument("--layers", type=str, default=None,
+2 -2
View File
@@ -1,8 +1,8 @@
{
"$schema": "https://go.kicad.org/pcm/schemas/v2",
"name": "Fill Resistance",
"description": "DC/AC resistance of copper zone fills and traces between two contacts, single- or multi-layer with via coupling; current and power density maps.",
"description_full": "Computes the DC or AC resistance of copper zone fills and traces between two contacts (marker rectangles on User.1/User.2 and/or selected pads/vias), single- or multi-layer: the chosen net's fills and tracks are solved as coupled finite-difference sheets linked by the net's via and through-hole-pad barrels. Selected vias/THT pads inject at the drill-wall barrel, and every populated THT hole carries its full solder joint (component lead, solder fill, one-sided pad coat and protruding-lead cone) with exact pad shapes and do-not-populate flags read from KiCad, conducting in-plane as its solder plug and lead on every layer it spans. Every net pad's exact copper shape is stamped on the layers it sits on, SMD as well as through-hole, and oblong (slotted) holes are modelled as their true stadium shape rather than an approximating circle. Traces narrower than the grid become exact 1D resistor chains, and an adaptive multi-resolution grid (fine at features, coarse plane interiors, deferred-corrected) keeps large boards fast.\n\nShows per-layer rasterized maps, potential, current density and power density, reports per-via currents (via ampacity) and total dissipation at a selectable test current. At a user-set frequency the exact 1D foil/barrel skin-effect correction is applied (AC results are a rigorous lower bound). PNGs, a text summary and a re-solvable geometry dump are saved per run.\n\nNote: the first load builds the plugin's Python environment (numpy, scipy, pyamg, matplotlib, PySide6) and can take several minutes.",
"description": "DC resistance of copper zone fills and traces between two contacts, single- or multi-layer with via coupling; current and power density maps.",
"description_full": "Computes the DC resistance of copper zone fills and traces between two contacts (marker rectangles on User.1/User.2 and/or selected pads/vias), single- or multi-layer: the chosen net's fills and tracks are solved as coupled finite-difference sheets linked by the net's via and through-hole-pad barrels. Selected vias/THT pads inject at the drill-wall barrel, and every populated THT hole carries its full solder joint (component lead, solder fill, one-sided pad coat and protruding-lead cone) with exact pad shapes and do-not-populate flags read from KiCad, conducting in-plane as its solder plug and lead on every layer it spans. Every net pad's exact copper shape is stamped on the layers it sits on, SMD as well as through-hole, and oblong (slotted) holes are modelled as their true stadium shape rather than an approximating circle. Traces narrower than the grid become exact 1D resistor chains, and an adaptive multi-resolution grid (fine at features, coarse plane interiors, deferred-corrected) keeps large boards fast.\n\nShows per-layer rasterized maps, potential, current density and power density, reports per-via currents (via ampacity) and total dissipation at a selectable test current. An optional skin-effect correction (exact 1D foil/barrel solution at a user-set frequency) estimates the resistive skin rise only - proximity redistribution and inductance are not modeled, so this is not an AC impedance simulation. PNGs, a text summary and a re-solvable geometry dump are saved per run.\n\nNote: the first load builds the plugin's Python environment (numpy, scipy, pyamg, matplotlib, PySide6) and can take several minutes.",
"identifier": "th.co.b4l.fill-resistance",
"type": "plugin",
"author": {
+1 -1
View File
@@ -2,7 +2,7 @@
"$schema": "https://go.kicad.org/api/schemas/v1",
"identifier": "th.co.b4l.fill-resistance",
"name": "Fill Resistance",
"description": "DC/AC resistance of copper zone fills and traces between two contacts (marker rectangles or pads), single- or multi-layer with via coupling",
"description": "DC resistance of copper zone fills and traces between two contacts (marker rectangles or pads), single- or multi-layer with via coupling",
"runtime": {
"type": "python"
},
+1 -1
View File
@@ -4,7 +4,7 @@
[project]
name = "fill-resistance"
version = "1.2.1"
description = "DC/AC resistance of copper zone fills and traces between two contacts (KiCad 10 plugin)"
description = "DC resistance of copper zone fills and traces between two contacts (KiCad 10 plugin)"
license = "GPL-3.0-or-later"
requires-python = ">=3.11"
dependencies = [