# Boltzmann Energy and Velocity Distribution Simulation
# (c) 2012 Kevan Hashemi, Brandeis University.
# This is a LWDAQ Toolmaker Script. It is written in TclTk
# but uses routines for printing, plotting, and drawing on
# the screen that are provided by the LWDAQ libraries. We
# offer it as an example of a Toolmaker script that does not
# require any data acquisition from instruments, and yet does
# some plotting with LWDAQ images. To run the program, paste
# the entire thing into a blank Toolmaker window, or load the
# script with the Toolmaker's Load button. You will see
# a red line showing the theoretical Boltzmann energy distribution
# for molecules colliding in gas, and an orange line giving their
# velocity distribution. For the red line, the horizontal axis
# is energy, and the vertical is frequency. For the orange line,
# the horizontal axis is velocity, and the vertical is frequency.
# The green line shows the actual distribution of energies and the
# blue line shows the actual distribution of velocities. These start
# with a uniform energy distribution, and evolve to match the
# Boltzmann distribution as the simulation runs. The simulation simply
# collides randomly-selected particles and re-distributes their
# energy randomly. The Run button gets the simulation going, and
# the Stop button pauses it. If you want the program to run faster,
# increase num_collisions, which sets the number of particle
# collisions between plots of the graphs.
# In the Toolmaker's window frame we make a label and we
# create a Tk photo and a LWDAQ image to go with it.
set boltzmann_run Initialize
image create photo graph
lwdaq_image_create -width 400 -height 200 -name graph
label $f.image -image graph
pack $f.image -side top
# Create the Run and Stop buttons.
button $f.run -text Run -command {set boltzmann_run Run}
button $f.stop -text Stop -command {set boltzmann_run Stop}
pack $f.run $f.stop -side top
# This routine updates the screen.
LWDAQ_update
# We define the parameters used by our Boltzmann energy
# distribution simulation. We are going to make a list of
# N particles, each of which we will represent by its energy
# in a list. We will collide randomly-selected particles and
# redistribute their energy between them. This is the sort of
# distribution of energy one sees between atoms in a solid,
# or between modes of vibration in a molecule, or between the
# hypothetical electromagnetic oscillations in a black body
# cavity. We are going to plot the distribution of particles
# with respect to energy by making a histogram of particle
# energy, and for that we use dE as a bin width.
set N 10000
set dE 0.02
set E_ave 1.0
set E_bins [expr 3*$E_ave/$dE]
set E_nmax [expr 1.5*$N*$dE/$E_ave]
set num_collisions 1000
# Define the list of particles.
set particles ""
for {set i 0} {$i <= $N} {incr i} {
lappend particles [expr rand()*$E_ave*2.0]
}
# Print some information. We use the LWDAQ print routine to write
# to the text window in colored letters.
LWDAQ_print $t "RED: Boltzmann energy distribution." red
LWDAQ_print $t "ORANGE: Boltzmann velocity distribution." orange
LWDAQ_print $t "GREEN: Actual energy distribution." green
LWDAQ_print $t "BLUE: Actual velocity distribution." blue
# Here is the program loop that keeps colliding particles and plotting
# their energy and velocity distribution on the screen. When the execution
# window is closed by the user, the $f frame will no longer exist, and the
# loop will quit.
while {[winfo exists $f]} {
# We take notice of background tasks and user input.
LWDAQ_update
# if the global command variable is not Stop, then skip the execution
# code with the "continue" command.
global boltzmann_run
if {$boltzmann_run == "Stop"} {continue}
# Plot the simple exponential Boltzmann energy distribution
# as a histogram.
set histogram ""
for {set i 0} {$i < $E_bins} {incr i} {
lappend histogram "$i [format %.1f \
[expr $N*$dE*(1/$E_ave)*exp(-$i*$dE/$E_ave)]]"
}
lwdaq_graph $histogram graph -fill 1 -color 0 \
-y_min 0 -y_max $E_nmax \
-x_min 0 -x_max $E_bins
# Plot the velocity magnitude distribution we derive from
# Boltzmann energy distribution.
set histogram ""
for {set i 0} {$i < $E_bins} {incr i} {
set E [expr $i*$dE]
lappend histogram "$i [format %.1f \
[expr $N*$dE/$E_ave*$E*exp(-$E*$E/(2.0*$E_ave))]]"
}
lwdaq_graph $histogram graph -fill 0 -color 3 \
-y_min 0 -y_max $E_nmax \
-x_min 0 -x_max $E_bins
# Plot our current energy distribution as a histogram
# of frequency with energy bins of width dE.
set histogram ""
for {set i 0} {$i < $E_bins} {incr i} {
lappend histogram "$i 0"
}
foreach E $particles {
set i [expr round($E/$dE-0.5)]
if {$i < [llength $histogram]} {
lset histogram $i 1 [expr [lindex $histogram $i 1] + 1]
}
}
lwdaq_graph $histogram graph -fill 0 -color 1 \
-y_min 0 -y_max $E_nmax \
-x_min 0 -x_max $E_bins
# Plot our current velocity distribution as a histogram.
set histogram ""
for {set i 0} {$i < $E_bins} {incr i} {
lappend histogram "$i 0"
}
foreach E $particles {
set i [expr round(sqrt($E*2.0)/$dE-0.5)]
if {$i < [llength $histogram]} {
lset histogram $i 1 [expr [lindex $histogram $i 1] + 1]
}
}
lwdaq_graph $histogram graph -fill 0 -color 2 \
-y_min 0 -y_max $E_nmax \
-x_min 0 -x_max $E_bins
# Draw our graphs on the screen and update displays. The updated
# graph image will appear when we next call the LWDAQ update
# command.
lwdaq_draw graph graph -zoom 2
# If this is our initialization pass through the loop, then stop.
if {$boltzmann_run == "Initialize"} {
set boltzmann_run "Stop"
continue
}
# Perform collisions. We choose two particles at random and
# collide them, sharing their energy between them in a uniform
# random proportion.
for {set c 0} {$c < $num_collisions} {incr c} {
set i [expr round(rand()*$N)]
set j [expr round(rand()*$N)]
set E [expr [lindex $particles $i] + [lindex $particles $j]]
set Ei [expr rand()*$E]
set Ej [expr $E - $Ei]
lset particles $i $Ei
lset particles $j $Ej
}
}