app
Adom Fields
Public Made by Adomby adom
Adom Fields: where the current and the heat go on your board.
← Commit history
skills/adom-fields/spec.mddeleted−50@@ -1,50 +0,0 @@-# Adom Fields: the spec and the solver, in full--Every spec key and what the solver does with it. The core keys are in SKILL.md; read this for terminals, solids, package cooling, fans, transients, stackups and Fusion boards.--## What a solve writes--```-adom-fields analyze --board <board.kicad_pcb | board.brd from Fusion> --spec <spec.json> --out fields-```--The board must be saved with its zones filled (the filled polygons are the copper). The spec is the AI Flow spec: `loads` (net: amps, maxRiseC, maxDropMv, draws: {part: amps}), `sources` (net: [the parts that feed it]), `hot` (ref: watts, tabNet, maxRiseC: that part's own limit, else hotMaxRiseC), `copperUm`, `hotMaxRiseC`, `thermalVias` (pad, count), optional `stackupMm` (three dielectric thicknesses). About two minutes for a 65 x 75 mm four-layer board at the default 0.2 mm cell; `--pitch 0.1` is four times longer and sharper.--What comes out, in `fields/fields.json` and `fields/tex/`:-- `nets`, ordered by amps then by peak density: peak A/mm² and where, the layers, the copper mm², the Joule loss, the vias.-- `chips`, hottest first: the rise at the tab in still and moving air, and where its watts go within 3 mm (along its layer, down its vias, through the bare dielectric, to the air), with how many vias the spec asked for.-- `issues`: `current-neck` (a loaded net over 60 A/mm², about what IPC-2221 allows at 35 µm for 10 °C), `tab-rise` (over the budget), `thermal-vias` (fewer than the spec asks), each with `at`, `layer`, `net`, `reference` and a `fix`.-- textures per layer: `J-<layer>.png` (all nets), `J-<net>-<layer>.png`, `q-<layer>.png` (heat flow, W/mm), `T-<layer>.png` and `Tm-<layer>.png` (rise, still and moving air), `copper-<layer>.png`, plus `.raw.png` 16-bit values for the readout.--Terminals per net: the wire pads and connectors (MC*, J*, P*) on one side; on the other the spec's hot parts on the net (a FET's tab and its source pins both count), else the Q and U parts, else the parts with real pads, each part's share by its pad area. A net with neither is skipped and says so.--## Honest limits (0.1)--DC only (no skin effect, no switching loss on the copper); per-layer thickness when copperUmByLayer is supplied; the 1.6 mm stack is 0.2 / 1.065 / 0.2 mm unless `stackupMm` says otherwise; convection is a flat coefficient on both faces (10 or 25 W/m²K), optional specified rectangular conducting blocks; no fins, enclosure or radiation; the tab watts come from the spec, not from a switching model. It is a screen that finds the necks and the starved tabs, and shows them; it is not a datasheet number.--## Evidence identity--Each solve records SHA-256 identities of the board and spec in `fields.json.inputIdentity`, plus the solver version. If an input changes while solving, analysis refuses to publish the summary. AI Flow uses these identities to reject stale field screens, and requires every positive load and hot part to be represented. Existing summaries without these identities must be re-solved, not manually stamped. The identities establish which inputs were used; they do not establish the accuracy of assumed terminals, losses, materials or convection.--## Fusion boards (0.6.0+)--A Fusion Electronics board works as `--board <board>.brd` (EAGLE source: `fusion_export_eagle_source`-on the Fusion bridge). Run RATSNEST in Fusion first so the pours are filled: the reader then uses-Fusion's own fill. Put the parts' STEP files, named by MPN, in a folder and pass `--models-dir` so the-chips sit over the fields.--## The solver: holes, terminals, heat models, fans, transients--- **Plated holes** (PR 5, 9): every via and plated through-hole pad barrel joins its copper layers in the electrical and thermal models (25 µm plating, circular or slotted, `platedPads` counted apart from vias). Drill holes are voids on every layer; each barrel's conductance is spread around its plated wall on cells with copper on both faces, and a wall the mesh does not resolve falls back to the nearest such cells, so a plated hole never disconnects a net. `nets[].platedConnections` gives each hole's current and mean barrel density. Blind, buried and micro vias are refused; Fusion boards read their declared `layerSetup`. See docs/plated-wall-coupling.md.-- **Explicit pin currents** (PR 6, 10): `loads.<net>.terminals: [{reference, pad, amps, at?}]`, positive into the copper, negative out, each side summing to `amps`; `at: [x, y]` picks one physical land where a pin number repeats. Wrong-net, missing, duplicate and unbalanced pins are refused; a loaded net the spec names that cannot be solved fails the run instead of publishing a partial report. `terminalAssignments` says explicit or heuristic per net.-- **Peak current density is the modeled maximum** (PR 8), before the display texture's 99.5th-percentile clip and unrounded (`peakJDefinition`).-- **`dcMaxIterations`** (PR 5, default 20000, at most 100000) bounds each net's solve; the target is unchanged.-- **Electro-thermal** (0.9.1, `review.electroThermal`). Copper's resistance rises 0.393 %/°C, so every run reports the first-order extra Joule heat at the solved temperatures, and an `electro-thermal` issue when it is over 10 %. With spec `electroThermal: true`, a second full pass solves the current and heat with each copper cell at its solved temperature. On the ESC: +33 % Joule, peak rise 109 → 119 °C.-- **Heating transient** (0.9.1, `transient`). Spec `transient` {durationS, steps (24), powerScale (1; a stall or surge at 3× is 3), fromSteady}: implicit Euler on the still-air heat system with copper, FR4 and the solid bodies' heat capacities.- - It gives the board peak and each hot part's rise over time, and each part's time constant (`t63S`, to 63 % of its steady rise).- - On the buck: U1 about 2 min, L1 about 3 min.-- **Terminals** (0.8.1): without explicit `loads.<net>.terminals`, the solve picks them. The named `sources` feed the net, and every other connector and part on it is a sink, so a board-to-board connector that a rail feeds counts as a load. Otherwise connectors feed and parts draw. A part listed in `loads.<net>.draws` carries its own amps, the rest share what is left (sinks by pad area, sources evenly), and each part's share splits evenly over its pins. A pin with no copper near it is left out and its share goes to the other pins on its side, so the injection always balances. Every net in fields.json lists `terminalCurrents` (pin, amps, + into the copper) and `terminalBasis`, so a reviewer can check them.-- **Solid bodies off the board** (0.8.0): `solids: {pitchMm, bodies: [{name, boxesMm: [[x0,y0,z0,x1,y1,z1]], conductivityWMk, watts | heatOf: "<hot ref>", hStillWM2k, hMovingWM2k, boardContactM2kW?, provenance}], contacts: [{bodies: [a, b], resistanceM2kW}], boardLinks: [{body, at, layer, resistanceKPerW, pad}], assumptions}`. Boxes are in board mm (x and y as KiCad, z up from the top copper). The bodies are voxelized and solved in the same heat system as the board, so the heat runs from the die through the tab, the pad and the heatsink fins to the air, and down the leads into the copper, in one energy balance. Bodies may touch only through a declared contact (0 means ideal), and they may not overlap. `fields.json` `solids` gives each body's peak rise, heat to air and to board, and peak flux. `solids.json` has every cell's temperature and flux vector, and the viewer paints them in the Heat and Temperature views. Calibrate a sink's h to its vendor rating rather than trusting a textbook h. See docs/solids.md.-- **Fan levels** (0.8.0): `fanLevels: [0, 0.25, 0.5, 0.75, 1]` solves each level fully. h on every exposed face (board, bodies, a packageCooling sink) follows (h_still³ + (h_forced·sⁿ)³)^⅓, where s is the fraction of full speed, s = 1 gives the moving-air h, and n is `fanExponent` (0.5). `fields.json` `airStates` gives each level's h, chip rises and bodies. The viewer's Fan control (Off, 25, 50, 75, 100 %) switches the board and the bodies together, on one colour scale, so the levels compare by eye. `ui view --air fan50` drives it.-- **Package cooling** (PR 11): `packageCooling: [{reference, junctionCaseKPerW, caseSinkKPerW, sinkAmbientStillKPerW, sinkAmbientMovingKPerW, boardLinks, provenance}]` puts a hot part's watts at its junction and lets them split through the supplied case, sink and board links; junction, case and sink rises per air state and an energy balance in `packageCooling`. See docs/package-cooling.md.-- **`adom-fields thermal3d --spec --out`** (PR 12): axis-aligned 3D solids with explicit materials, contacts and convection for an off-board package and finned sink, with a GLB of the surface temperatures. Not CFD. See docs/thermal3d.md.