Magnetic fields are not the simplest beasties to tame. When any precision is required in the estimated field characteristics of an electromagnet, coil designers turn to their computers and start running simulations.
Computing the magnetic field generated by an electric current flowing through an infinitely narrow wire in a vacuum (or air) is an exceptionally simple task, requiring the use of the Biot-Savart equation:
\[\mathbf{B}(\mathbf{r}) = \frac{\mu_0}{4 \pi} \int_C i \frac{d\mathbf{l} \times \mathbf{r}}{|\mathbf{r}|^3}\]Without too much headache, any three-dimensional curve may be approximated by line segments, and the magnetic field at any point may be computed using a few vector operations! :)
For every line segment, the angles between the wire ends ($\mathbf{A}$ and $\mathbf{B}$) and the computation point ($\mathbf{r}$) are calculated:
\[\cos \theta_{1,k} = \frac{\mathbf{B}_k - \mathbf{A}_k} {\left| \mathbf{B}_k - \mathbf{A}_k \right|} \cdot \frac{\mathbf{r} - \mathbf{A}_k} {\left| \mathbf{r} - \mathbf{A}_k \right|}\] \[\cos \theta_{2,k} = \frac{\mathbf{B}_k - \mathbf{A}_k} {\left| \mathbf{B}_k - \mathbf{A}_k \right|} \cdot \frac{\mathbf{r} - \mathbf{B}_k} {\left| \mathbf{r} - \mathbf{B}_k \right|}\]Then the magnetic field unit vector is calculated:
\[\hat{\mathbf{f}}_k = \frac{\mathbf{B}_k - \mathbf{A}_k} {\left| \mathbf{B}_k - \mathbf{A}_k \right|} \times \frac{\mathbf{v}_k}{\left| \mathbf{v}_k \right|}\]where…
\[\mathbf{v}_k = \left( \mathbf{r} - \mathbf{A}_k \right) - \left[ \left( \mathbf{r} - \mathbf{A}_k \right) \cdot \frac{\mathbf{B}_k - \mathbf{A}_k} {\left| \mathbf{B}_k - \mathbf{A}_k \right|} \right] \frac{\mathbf{B}_k - \mathbf{A}_k} {\left| \mathbf{B}_k - \mathbf{A}_k \right|}\]The final magnetic field at $\mathbf{r}$ is then as follows:
\[\mathbf{f}(\mathbf{r}) = \frac{\mu_0}{4\pi} \sum_{k=1}^K \left[ \frac{i_k}{\left | \mathbf{v}_k \right |} \left( \cos \theta_{1,k} - \cos \theta_{2,k} \right) \hat{\mathbf{f}}_k \right]\]Where $\mathbf{A}$ and $\mathbf{B}$ are the starting and ending points of each line segment, $\mathbf{r}$ is the point at which the field is to be computed, and $\mathbf{v}$ is the perpendicular vector from $\mathbf{r}$ to the segment $\mathbf{AB}$.
Whew! Now wasn’t that simple?
I’ve always found magnetic fields to give the most beautiful images, so here are a few computed results for your enjoyment. :)
The GPUfield program runs as an interpreter that parses a very simple set of commands. Wires are added using moveto and lineto statements, or through higher-level commands like arc, solenoid, maxwell or golay. Once the wires are in place, the magnetic field may be computed along a surface using the grid command, or along an arbitrary linear trajectory using the traj command.
GPUfield runs all field computations on the graphics card using the CUDA C API. Calculations that would’ve taken ten hours on a single CPU core can be reduced to a few seconds using CUDA, thanks to the embarrassingly parallel nature of the task.
Enough of my rambling… If you want to check out the source code, the latest version is available on GitHub: