main
History Download
John Lauer adom-fields 0.7.17: the open PRs merged onto 0.7.16. Plated pad barrels and drill voids with wall coupling (5, 9), expl… df40420

Thermal fields in solids beyond the PCB

adom-fields thermal3d --spec assembly.json --out solved

This independent mode solves steady 3D conduction through axis-aligned solid volumes, including heatsink fins, interface layers and package contact surfaces. It does not reuse PCB layer geometry or automatically assign materials to GLB meshes. Existing board analyze, serve and ui commands are unchanged. This mode is not yet integrated with the board viewer/SSE commands.

Example (millimetres, watts, degrees Celsius):

{
  "name": "uniformly heated slab",
  "ambientC": 20,
  "pitchMm": 1,
  "assumptions": ["Only the top face exchanges heat with air"],
  "bodies": [{
    "name": "slab",
    "boxesMm": [[0,0,0,10,10,10]],
    "conductivityWMk": 10,
    "convectionWM2k": [0,0,0,0,0,100],
    "watts": 1,
    "provenance": "Analytical test fixture, not a product rating"
  }],
  "contacts": []
}

A body's boxes form a union; different bodies may touch but cannot overlap. Every touching pair of different bodies requires one contact declaration, e.g. {"bodies":["case","isolator"],"resistanceM2kW":0.00002,"provenance":"Measured interface at specified pressure"}. Zero resistance explicitly means ideal contact. A declared contact with no shared face is rejected. Contact resistance is area-normalized, not K/W; a uniform patch has R=R''/area.

convectionWM2k orders faces -X,+X,-Y,+Y,-Z,+Z. It applies only to exposed faces; zero insulates. Air is not meshed. Each source's watts are distributed uniformly over its union volume. To model a localized die, create its explicit body/contact rather than heating an entire heatsink. A lumped junction-to-case estimate may be added separately to a suitable package case boundary; never count the same resistance twice.

The grid includes every box boundary and subdivides intervals to at most pitchMm, preserving thin layers instead of rounding them away. Neighbour conductance includes both half-cell material resistances and any interface resistance. Boundary convection includes half-cell conduction. The solver rejects unsupported fields, negative/nonfinite inputs, overlaps, missing contacts, insulated islands, excessive grids and failed convergence/energy balance. Limit: two million Cartesian grid cells, including empty cells.

thermal3d.json contains the input and its SHA-256, cell bounds and temperatures, signed heat transfer and flux on conductive faces, exposed-face heat rejection, body extrema, PCG residual and energy balance. Temperature is cell-centred, not an exact surface measurement. Check mesh convergence near thin contacts and local sources. Float colours are for visualization; numerical extrema remain in JSON.

Export a Z-up, metre-unit GLB with named bodies and solved cell colours:

python3 tools/thermal3d_glb.py solved/thermal3d.json solved/thermal3d.glb --color-min 20 --color-max 100

Use the canonical Adom 3D viewer with Z-up enabled. All scenarios must use the same colour limits for comparison. Mesh faces at material interfaces are retained so hiding a heatsink reveals the underlying contact layer. Export is piecewise constant per cell, with no invented smooth temperature gradient. Above/below colour limits saturates; include the numeric maximum and range in the viewer. No automatic GLB material/thermal-property inference, arbitrary triangle mesh import, fan animation, CFD, radiation, phase change, transient capacity, or heat-pipe transport is implemented. Prescribed moving-air h is not measured installed fan performance. Thermal ceilings from these assumptions are conditional estimates, never qualified device ratings.