This sits under PARSEC ActiveShield. I built the field and particle simulation stack first, then started wrapping it in a proper browser tool so people can actually run the system without opening Julia files and hand-editing configs.
TL;DR #
I built a GPU accelerated field and particle pipeline that takes coil geometry, computes a full 3D magnetic field map, traces field lines, and simulates charged particle deflection across multiple regimes. Then I turned that into a dark browser-based control surface with particle cards, staged field solves, and interactive 3D output so the workflow feels like an actual tool instead of a pile of scripts.
Right now the web app demo is still running locally. The next step is deploying it onto a remote GPU and CPU node at our company so heavier field solves and particle runs stop being laptop-bound.
Web App #
The new piece here is the UI. Honestly this came out much better than the first throwaway versions.
- Large 3D viewport with orbit controls, grid/axes, and live trajectory playback.
- Per-particle config cards for species, initial position, velocity direction, and relativistic speed.
- Separate
Compute B-FieldandRun Simulationactions so the expensive field solve can be staged and reused. - Inline status feedback during compute plus quick reset/view controls.
- Same physics backend underneath, just surfaced through a much more usable interface.
Approach #
- Parameterized coil geometry (barrel toroid with racetrack coils) and converted each coil into finite wire segments.
- Biot-Savart evaluation on a 3D grid with GPU acceleration and CPU fallback.
- Trilinear interpolation of the field for fast particle stepping.
- Particle pushers: Boris integrator for energy stability and RK4 for cross checks.
- Relativistic correction via gamma in the Lorentz force.
- Deflection metrics computed as hit bore vs deflected for quick comparisons.
- GLMakie and CairoMakie rendering for field lines, structure overlays, and trajectory videos.
Particle Step (Boris) #
function boris_step(pos, vel, q, m, B, dt)
gamma = 1 / sqrt(1 - dot(vel, vel) / C_LIGHT^2)
u = vel * gamma
qp = q * dt / (2m)
t = B * (qp / gamma)
s = (2t) / (1 + dot(t, t))
u_plus = u + cross(u + cross(u, t), s)
gamma_new = sqrt(1 + dot(u_plus, u_plus) / C_LIGHT^2)
v_new = u_plus / gamma_new
return pos + v_new * dt, v_new
endWhy Boris over RK4? The Boris pusher is the standard for charged-particle motion in electromagnetic fields because it is time-centered and volume-preserving. In practice that means it keeps particle energy bounded and avoids secular energy drift, even for long integrations and strong magnetic fields. RK4 is accurate per step, but it is not symplectic for the Lorentz force, so it can slowly inject or remove energy unless the timestep is very small. We used Boris as the production integrator for stability and runtime, and kept RK4 as a cross-check for short runs and regression tests.
Software and Visualization #
- Julia for core physics, geometry, and diagnostics.
- CUDA kernels for grid evaluations and large particle batches.
- PyCall plus magpylib for magnet geometry validation.
- Three.js for the browser UI and interactive 3D scene.
- GLMakie and CairoMakie for high quality field line and trajectory videos.
Media #
In the demo, the UI starts in a clean configuration state: dark 3D scene, axis/grid reference, and stacked particle cards on the right for species, initial position, direction, and relativistic speed. From there the flow is split into two explicit stages. First, the B-field is computed and the app shows that state directly in the interface instead of burying it in terminal logs. Then the particle run is launched against that solved field, and the same viewport updates into trajectory playback without kicking the user into a separate tool or separate page.
NDA Notice #
Detailed system specs and final performance targets may change; this page focuses on the simulation tooling and visualization pipeline.