Architecture and Source Map

This page is the shortest path from the public API to the underlying analytical kernels.

Layered structure

The repository is organized in layers.

Public API layer

This layer handles:

  • object construction,

  • compatibility-oriented getB/getH/getJ/getM behavior,

  • source/sensor formatting,

  • path and orientation semantics,

  • pixel aggregation,

  • squeeze and broadcasting behavior.

Field engine layer (fields/)

Object base layer

This layer handles:

  • shared object state,

  • path mutation semantics,

  • orientation storage and caching,

  • validation of constructor and motion inputs,

  • lightweight style compatibility.

Geometry and kernel layer

  • src/magpylib_jax/core/geometry.py — frame transforms, cartesian↔cylindrical, pose broadcasting.

  • src/magpylib_jax/core/kernels/ — the analytic field kernels, one module per source family (dipole, circle, cuboid, cylinder, sphere, polyline, triangle, tetrahedron, trimesh, cylinder_segment, current_sheet, current_strip), plus elliptic (Bulirsch cel), _raycast (mesh inside-tests), and _safe/_common helpers.

This is where the actual field formulas live. Each kernel is a pure function of origin-local observer coordinates and is differentiable in JAX.

Source wrappers

Current-driven sources:

Magnet sources:

Miscellaneous sources:

How getB flows through the code

A typical high-level getB call follows this path:

  1. Validate inputs and normalize source/sensor descriptors.

  2. Prepare source tensors and sensor tensors, reusing caches where possible.

  3. Group homogeneous source families for efficient batched evaluation.

  4. Call the matching analytical kernel.

  5. Rotate the resulting field back to the global frame.

  6. Apply sensor aggregation and Magpylib-compatible squeeze behavior.

The orchestration lives in the fields/ package: api.py routes the call, prepare.py builds the batched tensors, and engine.py runs the vectorized JIT kernel. Force and torque follow the same field path through fields/force.py, adding a jax.jacfwd of the field for the magnet gradient term.

Where to profile