Ideal Gas
WHAT IS IT?
This model is intended to perform as an ideal gas.
HOW TO USE IT
Starting assumptions: The turtles are molecules of a gas with identical masses. The molecules start in random positions in the gas, with velocities given by a normal distribution dependent on the square root of the temperature with a standard deviation of 1/2 the central value. Although this is an approximation of the actual Maxwell-Boltzman distribution, the two are very close. There should be a large number of molecules to model the behavior adequately.
Molecular interactions: Molecules travel in a straight line unless they hit a wall or each other. When two molecules hit, there is an elastic collision. The molecules trade velocities and headings according to a vector calculation using conservation of momentum and conservation of kinetic energy. When molecules hit a wall, they rebound with the angle of incidence equal to the angle of reflection. This is also an elastic collision; the molecules will not lose any energy in collisions with the wall. The red colored particles have the greatest velocity, followed by the blue and the green.
Pressure calculation: Presure is calculated by adding the momenta transferred to the wall during a time interval and dividing by the area of the wall.
To observe gas law behavior: Draw a container with a rectangular shape. Input temperature and number of molecules. Record values for volume and pressure. Change the volume by drawing a new container.
THINGS TO NOTICE
Notice that as you increase the number of particles the pressure tends to fluctuate more. Why does this happen ? Does this happen in real gases ?
EXPLORATIONS
This model would be a great start to modeling other physical phenomena that requires elastic collisions between turtles. The calculations are quite involved, so be sure to copy all the routines before trying to use them.
STARLOGO FEATURES
Plotting the pressure happens asynchronously in an 'every' block. We could also have put in a step counter and plotted the pressure every n number of steps.
Turtle procedures
turtles-own [vel]
globals [force]
to go ;Only move if path is clear, else turn and wait.
ifelse (pc-towards 0 vel / max-vel) != black
[analyze-bounce]
[fd (vel / max-vel)
grab one-of-turtles-here [collision who partner]
]
end
to analyze-bounce ;Check the four neighbors for walls.
let [:up (pc-at 0 1) != black
:rt (pc-at 1 0) != black
:dn (pc-at 0 -1) != black
:lt (pc-at -1 0) != black
]
if (:up) and ((between heading -1 90) or (between heading 270 360))
[do-bounce 0 180 stop]
if (:rt) and (between heading 0 180)
[do-bounce 90 360 stop]
if (:dn) and (between heading 90 270)
[do-bounce 180 180 stop]
if (:lt) and (between heading 180 360)
[do-bounce 270 360 stop]
end
to do-bounce :iw :rp ;Calculate the force of the collision and the new heading.
;:iw is the angle of the vector heading into the wall.
;:rp is the "plane of reflection", either 180 or 360
setforce force + 2 * mass * (vel * sin ((:iw + 90) - heading)) ^ 2
setheading (:rp - heading) mod 360
end
to between :h :min :max ;Determines whether a heading is strictly between two limits.
output (:h > :min) and (:h < :max)
end
to collision :m1 :m2 ;Calculates the interaction between two colliding turtles and updates.
let [:v1 (vel-of :m1) :h1 (heading-of :m1)
:v2 (vel-of :m2) :h2 (heading-of :m2)
:glance asin ((random 199) - 99) / 100
:i1 (vector-sum-heading (-1 * :v1) (:h1) (:v2) (:h2)) + :glance
:i2 (:i1 + 180) mod 360
:t1 ((:i1 - 180) - :h1) ;mod 360
:t2 ((:i2 - 180) - :h2) ;mod 360
:impulse (cos :t1) * :v1 + (cos :t2) * :v2
]
ask-turtle :m1 [
set vel vector-sum-speed :v1 :h1 :impulse :i1
set heading vector-sum-heading :v1 :h1 :impulse :i1
if (vel > max-vel) [set max-vel vel]
speed-color
]
ask-turtle :m2 [
set vel vector-sum-speed :v2 :h2 :impulse :i2
set heading vector-sum-heading :v2 :h2 :impulse :i2
if (vel > max-vel) [set max-vel vel]
speed-color
]
end
to vector-sum-heading :v1 :h1 :v2 :h2
let [:vx1 :v1 * sin (:h1)
:vy1 :v1 * cos (:h1)
:vx2 :v2 * sin (:h2)
:vy2 :v2 * cos (:h2)]
output (atan (:vx1 + :vx2) (:vy1 + :vy2))
end
to vector-sum-speed :v1 :h1 :v2 :h2
let [:vx1 :v1 * sin (:h1)
:vy1 :v1 * cos (:h1)
:vx2 :v2 * sin (:h2)
:vy2 :v2 * cos (:h2)]
output sqrt ((:vx1 + :vx2) ^ 2 + (:vy1 + :vy2) ^ 2)
end
to speed-color
if (vel / max-vel <= .25) [set color green]
if (vel / max-vel > .25) and (vel / max-vel <= .75) [set color blue]
if (vel / max-vel > .75) [set color red]
end
Observer procedures
globals [pressure pressure-list area max-vel]
to setup
clear-graphics
clear-plot
clear-turtles
set pressure 0
set pressure-list [0 0 0 0 0 0 0 0 0 0]
set force 0
let [:meanvel sqrt((2 * 1.38 * 1000 * 6.02 * temperature) / mass) ; sqrt(2kT/m)
:sd (:meanvel / 2) ]
create-and-do number [
setshape bubble-shape
setvel (random-gaussian :sd) + :meanvel
seth (random 360)
]
set max-vel max-of-turtles [vel]
ask-turtles [ speed-color ]
ask-patches [
if (((abs xcor) = box-width) and ((abs ycor) <= box-width)) or
(((abs ycor) = box-width) and ((abs xcor) <= box-width))
[setpc yellow]
]
setarea (count-pc yellow)
place-randomly
end
to place-randomly
ask-turtles [
setx (xcor - (box-width - 1)) + random 2 * (box-width - 1)
sety (ycor - (box-width - 1)) + random 2 * (box-width - 1)
]
end
to plot-pressure
every 1
[
set pressure-list fput force / (1000 * area) butlast pressure-list
set pressure average-of-list pressure-list
set force 0
plot pressure / 1000 ; convert to kilo Pascals
]
end
