Presenting padne: a tool for DC power delivery network analysis

Hi!

For the last few months, I have been casually programming a DC power delivery network simulator that works with KiCad projects. This is mostly a fun side project intending as a finite element method practice, but I have used it in my day job for some high current PCB design.

What it does: Simulates DC voltage drops on your PCB using the finite element method. Basically, it shows you where voltage drop occurs on your PCB power distribution traces and planes.

How it works: You add text directives describing your sources and sinks into your schematic, such as !padne VOLTAGE v=3.3V p=U1.1 n=U1.4 to describe a voltage source of 3.3V between pins 1 and 4 of U1, then run a command and get an interactive GUI where you can zoom around your board to explore the voltage/current distribution.

It lives on Github here: https://github.com/atx/padne , maybe it is going to be useful or interesting to someone else too. For now, it is very much a work in progress tool, but I am feeling good enough about it to start showing it to others.

12 Likes

@atx that seems very nice.

Do you have a sample board to show a demo result?

damn! this looks interesting.

Oh I think I could make use of this!

Often, after completing the power rail routing, I sort of imagine water flowing from source to load, and try to spot any bottlenecks. But I’d much rather rely on a visualisation rather than my intuition, particular when it comes to managing the risk of change.

Might it be useful for that?

When you say “work in progress”, are you thinking the algorithm might be incorrect, or more that the user experience is immature at the moment? Or certain current paths (vias?) are not modelled well?

A quick peek shows a “test” directory in his repository with over 30 KiCad projects.

This looks sort of promising / intriguing, but it’s a subject I’m not knowledgeable enough to have a real opinion of. but still..

How does this compare to other FEM solutions (elmer, OpenEMS)

I did a quick look around with: kicad thermal fem at DuckDuckGo

I think FreeCAD is one of the most popular programs to visualize the data, in a youtube video of FOSS FEM from Robert Feranec, I saw paraview being used.

This course seems worth following if you have a practical application for this subject:
https://www.udemy.com/course/kicad-fem-with-free-software-tools/

Also found this topic on gitlab, but it has not seen much progress in the last 6 years.

You write:

And that is of course good for you, and i’m sure you know more about this then I do, so I ask: Have you done some research into what already is available in the FOSS market? What program (or combination of programs) has the most potential to grow into an (integrated?) FEM tool for KiCad?

EDIT: I have somehow managed to trigger the antispam by sending this post, it said something like “you are not allowed to post links to this address” and then disabled the thread. I have removed all links from the post just to be sure it does not happen again.

@Heath_Raftery so, in terms of the “FEM” part, I think that is correct. There is hopefully nothing really to go wrong there. Poisson’s equation is among the simplest of applications of FEM.

But, the devil is in the boundary conditions: I am honestly not quite sure if both the pad connection model and the via model is accurate enough. In particular, the via model effectively works by “stitching” the edges of the via opening with resistors across layers. But, this is probably mostly accurate for “large and short” vias. Most vias in practice are “small and tall” (it is common to have a 0.3mm drill through a 1.6mm PCB right…), so there is probably quite a bit of current density happening “on the wall” below the opening. What I mean is that I believe the current method could underestimate the conductance “across” a via (imagine a thin trace pierced by a via).

Ultimately the only way to figure how much this matters is making some test boards and experimentally verifying the simulations, developing a more complex via model along the way. Something for the future. Or getting an Altium PDN license, but I do not think using commerical tools to generate test data is a good idea, legally and ethically.

@paulvdh one of the main observations I made is that the vast majority of work developing these tools is ferrying data around, with the actual simulation part being relatively “easy”. In fact, padne basically does the FEM part in about 40 lines in solver.py starting on line 166: (obviously this is in part due to the limited scope of padne being only a DC solver, “full” field solvers are significantly more complex). The remaining few thousand lines of code mostly take care that the KiCad project gets converted into a reasonable mesh (by pushing everything through pygerber and into CGALs mesher), sources get connected to the expected places, the system matrix gets delivered into scipy for sparse solving and then this gets collected together into something that can be displayed to an user.

As for something that could have larger scope: I have some hope that awslabs/palace could become an interesting backend (wouldn’t have guessed that Amazon of all corporations would be the one to deliver an open source EM solver but here we go). It ingests JSONs with the boundary conditions and geometry and then spits out a solution. Could be convenient for simulating distributed element filters etc.

But, really, the computational backend does not matter that much I think. Doing the user interface integration is the lion’s share of the work unfortunately.

2 Likes

Very interesting.

Well I’m embarrassed to say I spent hours trying to install on macOS and ultimately hit a wall. I thought I was making progress performing the usual, seemingly endless dependency resolution jumps. After going back and forward many times with different Python installs, and finally bypassing pipx (way easier to iterate by cloning and pip installing instead) I finally got the thing built.

Alas, kigadgets needs to run KiCad’s python. On macOS, KiCad’s python is still 3.9. I loosened the dependencies to accommodate, but no dice - padne itself uses the match functionality, introduced in 3.10.

So your work looks very interesting, but a bit outside my reach at the moment.

1 Like

Ah hm. Unfortunately I do not have a Mac at hand so I never tested on the platform. As far as I can tell from the kigadgets page, there is no really easy way of importing pcbnew.py on Mac from a non-bundled Python… I need to think about the best way to solve this.

Backstory: Since the pcbnew module is not available via PyPI and is distributed as an inseparable part of the KiCad install itself, it cannot just be pulled in as a standard Python dependency (for example, for pipx to install it in its own isolated environment automatically). So, I try to solve it two ways: by using kigadgets to find wherever the system KiCad libraries live or by bundling everything into a single binary using pyinstaller for the Linux standalone binary.

Hopefully this will cease to be a problem once the new IPC API takes over and becomes a bit more featureful…

I apologize for that, one or two months ago there was a wave of spam with 10 or more new accounts per day created for spam purposes, and spammers adding links after the initial post. As a result anti-spam measures have made stronger on this forum, but I’m almost certain that all (potential) spam messages get reviewed by real human beings, and then either being released, or blocked, and account deleted.

2 Likes

The back end has lots and lots of options. Most were probably never touched or even reviewed as they change sometimes between software upgrades.

You sent this via email? I think I was somewhat familiar with this option at some point but forgot it existed. If it does. :wink: Probably a whole separate set of rules applies. I wondered why the system showed as having unlisted and then relisted it. I’ve never seen that before.

I tried on Ubuntu 25.10 for ARM running in UTM (QEMU). Alas, no go.

$ padne -d solve JP2.kicad_pro pdn.padne
2025-10-20 14:46:17,005 - padne.cli - DEBUG - Parsed arguments: Namespace(debug=True, command='solve', kicad_pro_file=PosixPath('JP2.kicad_pro'), output_file=PosixPath('pdn.padne'), mesh_angle=20.0, mesh_size=0.6, variable_density_min_distance=0.5, variable_density_max_distance=3.0, variable_size_maximum_factor=3.0, distance_map_quantization=1.0)
2025-10-20 14:46:17,005 - padne.cli - INFO - Loading KiCad project: JP2.kicad_pro
2025-10-20 14:46:17,005 - padne.kicad - INFO - Plotting layers to gerbers
14:46:17: Font 'Arial' not found; substituting 'Liberation Sans Bold'.
2025-10-20 14:46:23,164 - padne.kicad - INFO - Processing vias and through hole pads
2025-10-20 14:46:23,563 - padne.kicad - INFO - Creating networks from specifications
2025-10-20 14:46:23,567 - padne.cli - INFO - Solving problem...
2025-10-20 14:46:23,567 - padne.solver - INFO - Constructing connectivity graph and finding connected layers
2025-10-20 14:46:24,824 - padne.solver - INFO - Meshing the connected components
Segmentation fault (core dumped)

There’s not much to go on here and this project happens is commercial in confidence so no stress. I’ll try again with a simpler project perhaps.

Got further with a simpler project that I own the rights too:

$ padne -d solve BP1.kicad_pro pdn.padne
2025-10-20 14:52:15,203 - padne.cli - DEBUG - Parsed arguments: Namespace(debug=True, command='solve', kicad_pro_file=PosixPath('BP1.kicad_pro'), output_file=PosixPath('pdn.padne'), mesh_angle=20.0, mesh_size=0.6, variable_density_min_distance=0.5, variable_density_max_distance=3.0, variable_size_maximum_factor=3.0, distance_map_quantization=1.0)
2025-10-20 14:52:15,203 - padne.cli - INFO - Loading KiCad project: BP1.kicad_pro
2025-10-20 14:52:15,203 - padne.kicad - INFO - Plotting layers to gerbers
2025-10-20 14:52:17,936 - padne.kicad - WARNING - Clipped geometry for layer F.Cu is empty after applying outline
2025-10-20 14:52:17,936 - padne.kicad - WARNING - Clipped geometry for layer B.Cu is empty after applying outline
2025-10-20 14:52:17,936 - padne.kicad - WARNING - Clipped geometry for layer In1.Cu is empty after applying outline
2025-10-20 14:52:17,936 - padne.kicad - WARNING - Clipped geometry for layer In2.Cu is empty after applying outline
2025-10-20 14:52:18,052 - padne.kicad - INFO - Processing vias and through hole pads
2025-10-20 14:52:18,081 - padne.kicad - WARNING - SMD pad Endpoint(designator='J1', pad='1') connection point at (156.25, 103.765) on layer F.Cu falls outside the layer geometry (likely in a hole). Skipping this connection point.
2025-10-20 14:52:18,081 - padne.kicad - WARNING - SMD pad Endpoint(designator='J1', pad='2') connection point at (156.25, 98.815) on layer F.Cu falls outside the layer geometry (likely in a hole). Skipping this connection point.
2025-10-20 14:52:18,081 - padne.kicad - WARNING - SMD pad Endpoint(designator='J1', pad='3') connection point at (153.71, 103.765) on layer F.Cu falls outside the layer geometry (likely in a hole). Skipping this connection point.
2025-10-20 14:52:18,081 - padne.kicad - WARNING - SMD pad Endpoint(designator='J1', pad='4') connection point at (153.71, 98.815) on layer F.Cu falls outside the layer geometry (likely in a hole). Skipping this connection point.
2025-10-20 14:52:18,081 - padne.kicad - WARNING - SMD pad Endpoint(designator='J1', pad='5') connection point at (151.17, 103.765) on layer F.Cu falls outside the layer geometry (likely in a hole). Skipping this connection point.
2025-10-20 14:52:18,081 - padne.kicad - WARNING - SMD pad Endpoint(designator='J1', pad='6') connection point at (151.17, 98.815) on layer F.Cu falls outside the layer geometry (likely in a hole). Skipping this connection point.
2025-10-20 14:52:18,082 - padne.kicad - WARNING - SMD pad Endpoint(designator='J1', pad='7') connection point at (153.71, 88.2625) on layer F.Cu falls outside the layer geometry (likely in a hole). Skipping this connection point.
2025-10-20 14:52:18,225 - padne.kicad - INFO - Creating networks from specifications
Traceback (most recent call last):
  File "/home/ubuntu/.local/share/pipx/venvs/padne/lib/python3.13/site-packages/padne/cli.py", line 181, in wrapper
    return func(*args, **kwargs)
  File "/home/ubuntu/.local/share/pipx/venvs/padne/lib/python3.13/site-packages/padne/cli.py", line 221, in do_solve
    prob = padne.kicad.load_kicad_project(args.kicad_pro_file)
  File "/home/ubuntu/.local/share/pipx/venvs/padne/lib/python3.13/site-packages/padne/kicad.py", line 1698, in load_kicad_project
    network = lumped_spec.construct(pad_index, layer_dict)
  File "/home/ubuntu/.local/share/pipx/venvs/padne/lib/python3.13/site-packages/padne/kicad.py", line 685, in construct
    main_source_elements = self._construct_source(p_connections[0], n_connections[0])
                                                  ~~~~~~~~~~~~~^^^
IndexError: list index out of range
list index out of range

Let me know if you want to investigate. No dramas if you don’t.

I may know about the segfault, as I was investigating a similar crash last week: it turns out that pygerber sometimes leaves a tiny “notch” in the geometry after rendering it. And CGAL does not like that. I have commited a fix that attempts to clean the geometry a bit more agressively.

As for the second crash: to have working castellated vias etc, I slice every layer geometry by the outline shape (since KiCad renders gerbers even “beyond” the outline). But, in your case, it seems that after this step no geometry is left? This could be a bug on my end about how I extract the outline shape from KiCad :thinking: . You can probably try to, say, remove a single line from the outline shape, which would make it malformed and this step would get completely skipped.

Also, you can try the test projects that live inside tests/kicad in the repository, say, tests/kicad/via_tht_4layer/via_tht_4layer.kicad_pro, those should hopefully just work:tm: :sweat_smile:

@hermit oh no, I sent it via the web interface: right after clicking reply an error message popped up and then I instantly got an email that the entire thread has been disabled.

That worked! So something funky with the couple of projects of mine that I tried.

Hmm dunno. I tend to draw fills larger than the board outline, but that was true of the first project I attempted too, and it didn’t report that error.

I tried on one more project of mine. Big board - 220x200mm. Seemed to be running okay, but eventually killed by OOM. I only have 8GB RAM in this VM.

Anyway, I better move on. I will come back to this when I have some other sample projects to try. The results on the test project are really encouraging. This could be a very useful tool if you get over the hurdle of handling the wide range of designs out there! It has the potential for setting KiCad apart - honestly this sort of insight into PCB behaviour could really change how designers validate their design.

Very interesting project and something I can make use of on a regular basis.

Couple thoughts. Have you considered making this a KiCAD plugin? I wonder if you could submit a feature request to the KiCAD devs for v10 to add voltage and current properties to tracks, vias, pads, zones and other copper (graphical) objects? That way, when the plugin is run it could populate these properties and the user could hop around the board and view the properties without having the leave the KiCAD environment.

Have you considered integration with FreeCAD? I am thinking that for a more detailed view and analysis, jump into FreeCAD and use the FEM workbench. The FEM workbench is actively maintained and provides a framework and tools for the visualization. Perhaps you could use the solver built into FreeCAD as well?

1 Like

@Heath_Raftery Hmm, it’s probably something in the way KiCad computes outlines. I just rely on whatever I get from the API and it may not be correct in some cases I think…

Performance improvements are next on my laundry list. Luckily there is a lot of low hanging fruit that should make everything much faster and more memory efficient in the end, I was not really paying that much attention to performance yet.

@steves It would be great if KiCad had some way for plugins to display some sort of metadata/overlay in pcbnew. Probably a bit too complex of a feature given the current nascent state of the new IPC API layer though. But, it definitely sounds like something that many plugins could leverage. Hopefully we are going to get a rich set of capabilities for making well integrated plugins into the UI at some point though :thinking: