Back when I was teaching Java programming, I wrote a demo program that involved balls moving around and colliding with each other in a box. It was designed as a game, inspired by “Maxwell’s demon“; the box was divided into two parts by a barrier, and the barrier had a gate that the player could open or close, the objective being to try to get all the balls into one compartment. The balls would bounce around, and the idea was to operate the gate so as to let balls through in one direction but block them from getting back out. Needless to say, it did not turn out to be the next Angry Birds. It was written as a Java applet, and, as I have grumbled about elsewhere, the fine folks at Oracle have essentially killed applets dead, breaking zillions of web apps in the process, so I can’t post  a working version, at least not in that form. However, I have coded up a modified version, converted to javascript and running in a web page, here. This version is not a game, it’s a simulation of particles of gas in a box, for the purpose of trying to get a feel for some basic principles of thermodynamics.

The motivation for this simulation (apart from a continuing effort to get more comfortable writing javascript apps) relates to another “hobby” of mine, which is trying to fill some gaps in my grasp of basic physics. Meaning, in this case, the Maxwell-Boltzmann distribution, which (to oversimplify a bit) gives the breakdown of speeds of individual particles in a gas. To understand how this works, suppose you measured the speed of each of 1000 cars on the freeway. Then you could count how many are going between 45 and 50 kph, how many between 50 and 55 kph, and so on, and you could plot the results as a histogram. That’s what a Maxwell-Boltzmann distribution gives you — it’s for molecules of gas bouncing around in a box instead of cars on the freeway, but it’s exactly the same idea.

Here is a screen shot; click here to see it in action.


In textbooks, the Maxwell-Boltzmann distribution is typically derived based on a few assumptions about the state of the system at equilibrium. (The best-explained derivation that I’ve found is in Chapter 6.7 of a quite excellent free e-book, Heat and Thermodynamics,  written by Prof. J. B. Tatum, a retired physics professor from University of Victoria (who has also written several excellent sets of notes on several other physics subjects, available here).

The argument goes like this (I’ll summarize it using the same notation that Tatum does, in which u, v, and w are the x, y, and z components of the velocity, respectively, and c is the speed, i.e. the (scalar) magnitude of the velocity vector):

First, consider (say) the x-components (u) of all the particle velocities; clearly the sum of the velocities of the particles going leftward must equal the sum of the velocities of those going rightward, otherwise there would be a net flow in one direction or the other, which wouldn’t be equilibrium. (We’re assuming all of the particles have the same mass.) That means that the distribution of u has to be symmetric, which means it must be a function of an even power of the x-velocity, such as f(u2).

Second, the choice of the axes is arbitrary, so the distributions of the y and z velocities must be the same as for the x velocities. That implies that the overall distribution of speeds is a function of the product of the three components, i.e. F(c2) = f(u2) f(v2) f(w2). But c is just the magnitude of the velocity vector, which is the square root of the sum of the squares of the components, so c2 = u2 + v2 + w2, so:

F(u2 + v2 + w2) = f(u2) f(v2) f(w2)

That means that f(u2) must be a function that maps a product to a sum, which implies an exponential, so what you get is a gaussian (i.e. a symmetric bell curve):

f(u2) = A e-u2/c2m

where A and cm are constants to be determined.

That’s for each of the three components of the velocity. The Maxwell-Boltzmann distribution is a distribution of the speeds, which are the magnitudes of the velocity vectors, taking into account all three components. The speed is a scalar; it can be zero, but it can’t be negative, so the distribution can’t extend leftward past zero. The distribution of speeds is not a symmetric bell curve, it’s skewed with a longer tail to the right. The actual distribution is:


This follows mathematically once you assume that each of the three components is a gaussian. Tatum gives the derivation; I won’t summarize it here because it isn’t necessary for the point I’m trying to make, which is that once you make the assumptions that (1) equilibrium exists and (2) the three axes are indistinguishable, the general form of the Maxwell-Boltzmann distribution follows, without needing to know anything at all about how the particles are actually interacting or what their energies are or what kind of collisions are occurring or anything else about what they’re doing.

That leads to an interesting conjecture (well, I thought it was interesting): Suppose you start with a “gas” in which all of the particles are moving at exactly the same speed. They collide with each other in elastic collisions, so that both momentum and energy are conserved. Initially, since they’re all going the same speed, the speed distribution is a single vertical line. But what happens after they’ve bounced around for a while? In theory, some would have to get faster, and some slower, because at equilibrium they should conform to a Maxwell-Boltzmann distribution.

And in fact, that is exactly what my simulation shows. If you click the “sample” button before clicking “start”, a list will appear of the speeds of all the particles, and they’re all the same. Click start, wait for them to bounce around for a while, and then click sample, and the speeds will all be different. The total kinetic energy will remain constant.

It’s a simple matter to plug the list of speeds into Mathematica and plot the distribution as a histogram; the following plot is an example of doing that with 500 particles in the simulation. I’ve superimposed a distribution in Maxwell-Boltzmann form, and you can see that it matches the actual data fairly well. (Not perfectly, but this simulation is 2D, not 3D, and 500 particles isn’t really enough; still, the fit isn’t bad.)


The javascript code for the simulation is here. The Mathematica notebook with the above data is here. The simulation is a standard time-step animation, the only somewhat tricky aspect is getting the collisions right so that balls bounce off each other at the right speed and direction based on the speeds and directions of the colliding pair. That requires enforcing conservation of both momentum and energy at each collision — see the collidewith function in the Ball class. Particularly for large numbers of balls, there is an inherent bias because the order in which the balls are checked for collisions is fixed, so if three balls collide exactly at the same time step, the trajectories would depend on which pair is evaluated first. It doesn’t seem to affect the results much if at all, and the purpose of the sim is to get a feel for what happens rather than to nail down exact values, so I haven’t tried to correct for that bias.

Regarding the javascript coding, I am once again struck with the clunkiness and inelegance of the language. For example, to replace the ending comma with a closing brace in the string variable containing the list of speeds requires the following abomination:

diststr = diststr.substr(0, diststr.length – 1) + “}”;

In Python, that would be:

diststr[-1] = “}”

Also, in javascript, classes and class objects are more of an afterthought; you can do them, sort of, but it isn’t pretty. In writing this sim I borrowed heavily from my earlier Java applet. Java is designed for true object-oriented programming, which lends itself much better to this kind of sim.

For this project I downloaded the trial version of the WebStorm javascript IDE. The debugger works well, it has code completion and a lot of other editing features, and I found it mostly pretty intuitive — very similar to the Komodo IDE. The non-trial version is $49, and I’ll probably spring for it — it’s a big improvement over switching back and forth between a text editor, chrome, and the chrome javascript console.


Leave a Reply

Your email address will not be published. Required fields are marked *