Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

PROBLEM SET 11

Submit your answers as a single pdf-file with the following name: set11 Lastname1 Lastname2.pdf.
Always comment on your results. Make sure that your code is clear, readable and that comments
clarify your lines of code. For instructions on how to compile your answers into a readable pdf: see
Canvas. In the description of the problems you find additional instructions on submitting python code:
• Include your Python code in your results document as well.
Make sure you copy and paste your code into the document (see Canvas for instructions on how
top this efficiently and readable.).
• Submit the .py-file.
In this case you need to submit your python script along with the pdf file.

This week we want to simulate an ideal gas. You will make use of matplotlib’s animation functions to
visualize the simulation.

Figure 1: Screenshot of the ideal gas simulation.


Note that for all quantities mentioned in this exercise we do not specify the units (e.g.
the radius of the molecules equals 3). This is done for convenience only. If you want to
calculate real physical quantities from this simulation (e.g. a pressure) than it is obviously
required to use proper units and values for the parameters. This requires however a lot of
scaling to properly show the simulation in a plot. In this exercise you are not asked to do
this (but if you like......).

115
1 Setting up the animation
Include your Python code in your results document as well.
Submit the .py-file.

Setting up the script. Create a new script called ideal gas simulation version 1.py. The version
number refers to the assignment.

Initializing variables. We will simulate N molecules moving in a 2D box of size box size = 100.
Each molecule will be represented by a position r (a vector of composed of the x and y coordinate) and
a velocity vector v. We take the radii and masses of all molecules equal: radius (a scalar) and mass (a
scalar). Add code to your script that defines the position and velocity of the molecules. Define the mass
and radius separately. Use the following data structure: Define a 2D numpy array r, in which there are
N number of rows and 2 columns. The first row gives the vector r of the first molecule x-coordinate, the
second row gives the second position vector, etc. In a similar fashion define a 2D numpy array v that
defines the velocity for each molecule. Finally define two scalars mass and radius that store the mass
and radius. Fill the arrays with the following initial data:
We start with defining just three molecules (N = 3). Take as a starting position ”[0, 0]”, ”[10, 10]”, ”[-5,
5]”. Take as a starting velocity ”[1, 2]”, ”[-1, 2]” and ”[0.5, -1.5]”. For the radius you can take a value
of 3 and set the mass to 1. Check your variable-explorer if the variables are properly initialized!

Setting up the figure. For drawing the molecules we will make use of Matplotlib’s plt.plot()
command and using the o marker to draw the ”molecules”. Create the figure and plot the molecules.
Remember to store the references to the figure and plot objects just like in the example in the reader.
Adapt the axis limits such that it represents the size of the box. In order to make sure the x-axis and
y-axis are also drawn with equal lengths (so it looks like a square on your screen) you can include the
following code in your script: fig.gca().set_aspect('equal', 'box')

Setting the marker size. As you probably noticed, the size of the marker does not correspond to
the real size (value of radius) of the molecule in axis-units. The reason is that if you set the marker
size to e.g. 3 (e.g. using the keyword argument plt.plot( , , ms=3) the size is specified in points. In
matplotlib there are 72 points per inch. To actually calculate the required markersize is illustrated in
the code snippet below:

Editor
# get required markersize to draw marker in axis units .
# fig is the reference to the figure .
# box_size is the axis range in axis units
ms = 2 * radius * fig . gca () . get_windo w_exte nt () . height / box_size *
72./ fig . dpi

# next update the markersize of the plot .


# line is the reference to the plot .
line . set_markersize ( ms )

When running your script you should now see the three ”molecules” as three dots in your plot, with the
size corresponding to the radius as specified.

116
2 Moving/Animating the molecules
Setting up the script. To keep track of modifications during software development it is common to
work with versions3 (if you mess up, you still have the previous script). Make a copy of the script you
made in Exercise 1 and name it ideal gas simulation version 2.py.

Implement the animation. You will now setup the animation part. For this we make use of the mat-
plotlib FuncAnimation() function. Use the example in the reader as a reference. Write the animate()
function. Add a line of code that calls the FuncAnimation() function and run the script.

Implement the Euler method. In the previous exercise the animate function does not yet update
the positions of the molecules, so they do not move. Adapt this function such that in each call the
position of the molecules are updated. Use a time step dt=0.05 to start with.
Your molecules should now move when you run the script. However they are not contained in the box.
You will implement this in the next step.

3 Keeping the molecules in the box.


You will now see that the molecules are leaving the plot window. That is a bit of a pity, so let’s try
to keep the objects inside the box. A very simple way of avoiding objects leaving the box is to flip the
velocity component of the molecule that is leaving the box. For example, when the circle is leaving the
box on the right it has a positive x-velocity. To prevent it from leaving the box you have to flip the
velocity to negative x-velocity as soon as it touches the wall of the box.

Setting up the script. Make a copy of the script you made in Exercise 3 and name it:
ideal gas simulation version 3.py.

Keeping the molecules in the box. For this question you have to prevent the molecules from
leaving the box. Make a function called wall collisions(r, v, radius, box size) which returns
the updated velocities of the molecules to make sure that they can never leave the box. Hint: You have
two parts to this function, determining which objects are about to leave the box, and the actual flipping
of the relevant velocity component.

Increasing the number of molecules in the box. So far you used N=3 (three molecules). Adapt
the script for initialization of the positions and velocities of N molecules using random generators (pick
some sensible range for the position and velocity). Make sure all the molecules are located within the
box and they are initialized according to Exercise 1b. You can ignore overlapping molecules, as we will
fix this in Exercise 4. Test it with e.g. N = 25

Speeding it up. You may have noticed that increasing the molecules will slowdown the simulation.
Increasing the time step in the Euler method can speed it up, but may also result in inaccurate results.
As plotting the molecules takes up a lot of time it is also a good idea not to plot the molecules every
Euler step. Adapt your script such that in every call to animate multiple Euler steps are performed.

3 Actually most professional software developers work with version control software such as git to keep track of changes.

117
4 Adding molecule collisions
Setting up the script. Make a copy of the script you made in Exercise 3 and name it
ideal gas simulation version 4.py.

Resolve collision between molecules. Resolve collisions between objects using the elastic collision
equations below. Implement this in a function resolve collisions(r, v) that updates and returns
the velocities of all molecules caused by collisions.


You have to check all possible pairs of molecules, but not double (since comparing molecule
1 and molecule 2 is the same as molecule 2 and molecule 1)! First determine if the two
objects are supposed to collide, which has two criteria: They must be touching, and they
must be moving towards each other (see info below).

The equations to compute the velocities after a collision should look familiar:
 
”In an angle-free representation, the velocities v1 and v2 after collision are computed using the centers
r1 and r2 and velocities v1 and v2 at the time of contact as” (adapted from Wikipedia) 4

 2m2 (v1 − v2 ) · (r1 − r2 )


v1 = v1 − (r1 − r2 )
m1 + m2 |r1 − r2 |2
 2m1 (v2 − v1 ) · (r2 − r1 )
v2 = v2 − (r2 − r1 )
m1 + m2 |r2 − r1 |2

In these equations, the double enclosing vertical bars |a| are used to indicate the norm (or length) of the
vector. Since the masses of our molecules are all identical, the fractions with the masses are equal to 1
in the above equations. These two equations will give the new velocity vectors due to an elastic collision
between two molecules.
Furthermore, if two objects are moving towards each other the following relation is true:

(r2 − r1 ) · (v1 − v2 ) > 0 (2)


Optional: You probably notice that increasing the number of molecules can slow
down your simulation considerably. You can speed up the code significantly by mak-
ing use of a so-called jit (just-in-time) compiler. To use this, first import the re-
quires module from numba import jit . Next you include the following line just be-
fore the function definition resolve collisions(): @jit(nopython=True) . The function
resolve collisions() will now be compiled the first time it is evoked and all subsequent
calls to this function will now run much faster (can speed up things 2 orders of magnitude
in some cases).

4 The position vectors 


r correspond to the rows in your variable r.

118
Bonus: Suggestions for experiments
If you successfully finished Exercises 1 through 4 you can perform some experiments. These are not
obligatory!

• Diffusion Even without particle-particle interactions you should see the effects of diffusion. You
could try to see how two species of objects ”mix” over time if they are initially separated. Setup
a system where you have 40 small blue (radius 1) particles on the left randomly distributed with
the same speed (but random direction), and 40 similar red particles on the right. Determine after
how many seconds the system appears to be mixed (qualitatively). If you have time left you can
try to calculate how well they are mixed (i.e. count how many red are on the left and on the right
etc.). Do the calculations in Python and not by eye!

• Ideal gas law The simulation without particle interaction behaves like an ideal gas. You can
count how many times the particles bounce against a wall, which is similar to the pressure term in
P V = nRT (actually you should count the amount of change in momentum Δp on the wall, which
depends on the incoming angle, but on average you can assume this to be a constant, allowing
counting bounces instead). You could try to vary the other parameters of the ideal gas law and see
the effect on the pressure (e.g. double the amount of particles and see how the ’pressure’ increases).

• Maxwell-Boltzmann With particle-particle interaction enabled you have a system where particles
can exchange energy with each other (without loss). If you introduce a large population of particles
with the same velocity you would expect the distribution of velocities to change over time to match
a Boltzmann profile. See https://en.wikipedia.org/wiki/Maxwell-Boltzmann_distribution.
Try if you can find such a distribution.

119

You might also like