Modeling Magnetic Confinement with JavaScript and D3.js
15 Jan 2016Particle systems are an amazing way to visualize and model important natural phenomena. They give us an experience that provides a different kind of value than simply staring at equations and reading results in an excel document. The value they give us is tangible, and from observing these systems visually, we can understand the subject at hand in an intuitive way.
Just below are a couple videos I added to YouTube showing the results of running a couple different variations of the code we'll get into in this post. If you're not in the mood for a long article, I'd suggest just watching the videos to get an idea of what I mean by a particle system.
Magnetic Confinement Simulation
Big Bang Simulation (medium speed)
Big Bang Simulation (slow motion)
A particle system is a simulation in which elements under observation interact with each other and their surroundings according to explicitly defined physical laws. Think of the planets revolving around the solar system, viruses interacting with and destroying healthy cells.
For each of these we know the exact set of physical laws we will apply to the system. In other words, this type of system is really a simulation. We define a set of equations, build a certain number of particles that adhere to these equations, and set them out into the wild (or the current browser tab). Then we wait and see how the particles interact with each other.
In this post, I want to talk about one specific implementation of a particle system I made with a partner using JavaScript and D3.js, an impressive library for efficiently manipulating DOM elements based different data sets. In this project, we used the fundamental equations of electrodynamics to build a system of protons and electrons.
To achieve this, we created a set of equations in our main JavaScript file to handle vector operations and force calculations in a 2-dimensional space. Below I'll go give a brief description of each step of the process.
Vector Operations
Vectors are useful when you are working with something that has both magnitude and direction. When we are calculating the velocity, force, and acceleration of different particles, we must keep track of not only the magnitude of these quantities but also the directions, so we can determine how these particles will interact with the other particles in the system. We will use the vector helper functions in our physics calculations below.
Force and acceleration functions
All the above equations will be used to calculate the new position of a particle based of its current position, velocity, and the force exerted on it by every other particle in the system. With our main functions in place we can now think about making particles and putting our functions to work.
Particle generating functions being used in the current configuration
Above we have three main functions. The first is a general function for making any type of charged particle we want. The second and third functions are use case specific. In our current implementation, we are simulating the magnetic confinement of charged particles. This might be seen in a particle accelerator, or an experimental nuclear fusion reactor, where you have walls or tubes with an extremely strong charge, exerting a large repulsive force from all directions on a narrow beam of particles in the center of the tube. As a result, the beam of particles is compressed,and often accelerated to tremendous speeds. With this in mind, we see how the makeAWall function can be used to recreate a basic version of one of these repulsive walls. Our injector function, on the other hand, is what creates our particle beam.
Main System Logic/Loop
Above is the heart of what makes the particle system run. We initialize our system by creating two positively charged walls, then inject 100 particles in the space between the walls. The most crucial aspect of this part is what happens inside of the setInterval. Every time the updateParticles (I've omitted the source for that for the sake of brevity) function gets invoked, every particle that is not static (meaning everything but the walls) has a force exerted on it by every other particle in the system (including the walls). In the current implementation, we have 500 total particles. That means for each of the 100 particles made by the injector, we must calculate the influence of the other 499 particles in the system. That means for one iteration of our game loop we must perform roughly 50,000 operations. Moreover, this game loop runs on an interval based off of the variable animSpeed, which in this implementation is 10 milliseconds. That means that every second, this system is performing over 5,000,000 operations.
That in itself is simply amazing. And what is even more amazing is that it runs in the browser... on a laptop. This is something that just a decade ago would have seemed unbelievable. But the fact of the matter is that we can perform meaningful physical simulations with a browser and a software language made for web development.
If you take some time to look at the code, you will probably see how straightforward it would be to modify the code to create a totally different simulation. (Like the big bang example videos at the top). We simply change some of the initial conditions, build a couple of new helper functions, and boom! We get a brand new model.
I hope you've enjoyed reading. Please feel free to contact me with any questions or critiques.