Having taken physics 113, Thermal Dynamics and Statistical Mechanics, I was interested in modeling one of the concepts that was demonstrated in that class. I chose to model the behavior of the particles of an atmosphere under a gravitational field. This became the project "iBoltz".
Particles in an atmosphere take on an exponential distribution with respect to the increasing vertical. The Boltzmann Factor describes this distribution. The Boltzmann factor describes any situation where a small object is in contact with a large thermal reservoir. The probability P of finding the small object in a particular microstate is proportional to the Boltzmann Factor, e^(-E/kT), where E is the energy of the object, k is the Boltzmann constant and T is the temperature. In the case of the atmosphere, the small object is one of the individual particles and the reservoir is the rest of the atmosphere. In this system of many particles, it can be assumed that for every particle at sea level, there's a particle at height h that has an identical state of motion except for its position. This means that the ratio of the probabilities can be represented as P(h)/P(0)=e^(-mgh/kT), and the ratio of the probabilities gives the ratio of the densities. This shows that the density of the particles in an atmosphere under gravity should take on an exponential distribution.
The goal of iBoltz was to create a program that modeled the behavior of an atmosphere and show that it takes on an exponential distribution in a gravitational field. This was accomplished in several steps. Starting with an illiSkel, the first step was to create a single particle that could move. This was done using an update function (pUpdate()). The next step was to have this particle move in a crude approximation of Brownian motion; this was done by choosing a random value for each of the three directions and having the particle move that much. Next, the single particle became an array of particles. Once the array of 1000 particles was in place, the Gaussian distribution started to form. At this point it was necessary to make it easier analyze the information that was being shown. The vertical axis was broken up into levels and the number of particles in each level was counted and output to the screen. This began to show the Gaussian distribution of the particles, but a more accurate method was required. The number of levels was doubled and a graph was added to display this information. This clearly showed the Gaussian distribution that was forming.
The next and most important step was to figure out a way to add the gravity. With Ben Bernard's help, it was realized that the particles would simply be constantly falling under a gravitational field with respect to x = .5at^2, a kinematic. In this system, where each iteration of the program takes the same amount of time, time is a constant. Since the acceleration due to gravity is also a constant, and assuming that the particles initial velocity is reset every time a new direction for it to move is chosen, the amount that they would fall due to gravity would be a constant. This was implemented simply by subtracting a small amount from the amount chosen for each particle to move in the vertical direction. After the addition of a floor, which the particles could not move below to simulate the ground, the particles took up an exponential distribution.
The last thing that was added was the ability to change the temperature of the system. This was done simply by multiplying the distance the particles would travel every iteration by a constant representing the temperature. This could be increased or decreased by the user to view what changes would occur. This (and the gravity as well) has no specific units, it's just a general temperature tweaked to make the program give an easily discernable output.
Using iBoltz:
Many of the controls of iBoltz are the same as a regular illiSkel. Some controls have been added, these are:
'`'   backwards apostrophe   starts and stops simulation
't'   t key   small t decreases number of iterations before drawing, capital T increases
'x'   x key   small x decreases temperature, capital x increases
'~'   ~ key   sets the number of iterations to 3500
'1'   1 key   sets the number of iterations to 1
'y'   y key   turns on and off gravity (and the floor)
'l'   l key   turns on and off the lattice
'c'   c key   turns on and off graph
'C'   C key   next time you zap, you'll zap to the graph
`/`   slash key   enable the fly/turn modes
'j'   j key   set all the particles to the origin
'k'   k key   set the particles to a random configuration
To get a good example of how this program runs under gravity, set the particles to the origin and use the '~' key to set the number of iterations to 3500. It takes a large number of iterations for the system to take on a very clear exponential pattern. To get a good example of how the program runs without gravity, set the number of iterations to about 100 to 200. It takes far fewer iterations for it to develop a Gaussian distribution, and if too many iterations are allowed to take place, the graph becomes very flat and uninformative as the particles spread out of the range of measurement.
Observations Made:
The program is very sensitive to the amount that the gravity is set to. Increasing it has the effect of increasing the curvature of the exponential curve that appears. The gravity is set to .000025; .00001 was a bit too low and .00005 was a bit too high to see a good exponential curve in the results.
The temperature has very interesting effects on the system. Turning it to 0 has the correct results, as the particles all settle to the bottom. It would be very interesting to see what would happen with a more accurate system of assigning temperatures.
Problems Encountered:
When starting this project, I had very little programming experience. This was my second semester at the University, and the first semester I was taking any kind of programming class. This, of course, caused me to have many problems while working on this project. Luckily, I picked a project that took relatively little programming knowledge, and what I was learning in CS 125 could help me out. That, along with no small amount from Ben Bernard, helped get this project to come together.
There were some basic programming problems that came up. At first, I hadn't pushed and popped between the moving of each individual particle. This caused some problems, but created a rather interesting effect. When trying to change over to using a structure to represent a particle, many problems occurred. I decided it would just be easier to use three different arrays to hold the x, y, and z coordinates of the particles. I'm sure a structure implementation would work fine, but, as this is the first time I've ever programmed in C, I couldn't get it to work.
More important and basic problems also came up. At first, with gravity turned on, there was no floor. This just caused the particles to fall forever and never take up any kind of steady state exponential distribution. The addition of a barrier where the particles could no longer go downwards fixed this problem quite well. The ground of this system is very important the results.
Another flaw in this program is the amount of time it takes to use. When the number of iterations is set very high with 1000 particles in the system, the frame rate goes way down and it takes a while for the system to get to where you want it to go.
On Brownian Motion:
The model of Brownian motion used in the project is very crude. It's good enough to give the desired results, but it could be vastly improved. Brownian motion is based on particle collisions; in this program, the collisions of the particles are completely ignored. I think of this as a display of representative particles in the atmosphere. The direction a particle would go after a collision in a real atmosphere would be determined by the angle at which it collides with the other particle, and the velocity of both particles. In a system with many many particles, this is pretty much random. So, this program just makes this actually random as an approximation. The particles also conveniently move all at the same time. This is convenient in the calculation of how much the fall due to gravity. This is also another flaw of this simulation of Brownian motion. This could be explained as we have chosen a set of particles who, over the course of the runtime of the program, happen to collide with other particles at the same time. In a real atmosphere with numbers of particles on the order of many moles, finding 1000 that collide at almost exactly the same time for a few thousand iterations could be possible.
This is only the way I am explaining this to myself at this point. I am by no means an expert on Brownian motion or statistical mechanics, having only taken a single class on the subject. Much more research would have to be done for me to accurately and scientifically explain all the aspects of this simulation.
Suggestions for Future Improvements:
As I've stated before, the implementation of temperature could use a lot of improvement. In a real system, not all the particles would have the same temperature; instead, they would have a distribution of temperatures (which also take on a Boltzmann distribution). This program could be made to assign temperatures to the particles according to this.
Another thing that could be changed is to have the particles not all change direction at the same time. This would be more realistic as the collisions should happen at random times. This would require an improvement in the way the gravity is implemented, as it can no longer be assumed that it causes a constant value of displacement every iteration.
The main thing that could be improved is the implementation of Brownian motion. It would be very interesting to see what effect this would have on the results.
Sources:
Young, Hugh D. and Roger A. Freedman. University Physics. Addison Wesley, 1996.
Other information provided by the physics department of the University of Illinois.