Professional Documents
Culture Documents
Charles J. Weiss
The software used in these simulations is free, open source software which runs on Mac,
Windows, and Linux systems. The Anaconda installer provided by Continuum Analytics has been used
by the author as a quick and convenient way of installing all of the software and libraries required.
While the following instructions are current as of this writing, be aware that the steps or details may
since change.
Installation
1. Download the appropriate graphical Anaconda installer for your system from
https://www.continuum.io/downloads. Multiple versions of Python are available. Be sure to
select the most recent version of Python 3.1
2. Click on the downloaded file and follow the installation instructions that appear.
Getting Started
1. Click on the Anaconda-Navigator icon (green circle) on your computer to start Anaconda.
3. Jupyter should launch in your default web browser and a terminal window will also appear. If
the browser does not launch with Jupyter, you may need to copy and paste the local host
address from the terminal window into the address bar of your web browser. The address looks
something like the following:
http://localhost:8888/?token=asdt4d93kck2kk195ieme34ifk3ifi3jfm53g
1 Python 2 is also available, but this is technically legacy and should only be used if you know that you need this version.
S2
4. From the Jupyter window (in the web browser), navigate the file system and select a Jupyter
notebook to open it. Note: double clicking a Jupyter notebook from your computer’s file
browser will not open the file; it must be opened from within Jupyter.
5. There are two types of cells in a Jupyter notebook, code cells and markdown cells. Code cells
contain live code while markdown cells contain explanatory text, images, and equations to
provide instructions, background information on the code, and/or discussion of the results.
To run a cell, select Cell → Run Cells from the menu at the top of the screen or click the Run
Cell button (looks like a play button).
S3
Alternatively, the user can create a new Jupyter notebook by selecting New → Python 3 from the
menu at the top right of the browser.
S4
Chain-Growth Polymerization
student instructions
Instructions
In groups of two students, open the Jupyter notebook provided or a new notebook and perform
the following tasks.
1. Stochastically simulate the chain-growth process using a random value generator with a
probability argument (e.g., Poisson distribution) to dictate termination. You are welcome to
develop your own method or use the one illustrated below. It is recommended that you use ten
thousand steps/cycles in your simulation and a hundred thousand polymer chains.
First Cycle
chains 0 0 0 0 0 0 0 0 growth
chains 1 1 1 1 1 1 1 1
poly_growth 1 1 1 1 1 1 1 1
termination
poly_growth 1 1 1 1 1 1 1 1 poly_growth 1 1 1 0 1 1 1 1
Second Cycle
chains 1 1 1 1 1 1 1 1 growth
chains 2 2 2 1 2 2 2 2
poly_growth 1 1 1 0 1 1 1 1
termination
poly_growth 1 1 1 0 1 1 1 1 poly_growth 0 1 1 0 1 1 1 1
Third Cycle
chains 2 2 2 2 2 2 2 2 growth
chains 2 3 3 2 3 3 3 3
poly_growth 0 1 1 0 1 1 1 1
termination
poly_growth 0 1 1 0 1 1 1 1 poly_growth 0 1 1 0 0 1 1 1
S5
2. Generate a histogram plot showing the distribution of polymer chain lengths.
3. It is common in polymer chemistry to plot the molecular weight distribution in terms of weight
fraction (W) which is the fraction of the total polymer weight that each chain length contributes
to the over weight of polymer. This can be calculated by dividing the total weight of polymer
chains of a given length by the total weight of polymer.
4. Compare the results of the stochastic simulation against the theoretical model 2 shown below.
During each step of the polymerization, there is a given probability, p, that a polymer will add a
new monomer instead of terminating described by the below equation where ν p is the rate of
polymerization and νt is the rate of termination.3 This probability can be used to calculate the
weight fraction (W) for each molecular weight (M). To be consistent, the following plot is
plotted in terms of number of monomers (X) where M 0 is the monomer molecular weight.
2 X−1
W =(1−p) Xp
vp
where X =M / M 0 and p=
v p + vt
2 (a) Flory, P. J. Molecular Size Distribution in Linear Condensation Polymers . J. Am. Chem. Soc. 1936, 58 (10), 1877–
1885. (b) Flory, P. J. Molecular Size Distribution in Ethylene Oxide Polymers J. Am. Chem. Soc. 1940, 62 (6), 1561–
1565.
3 Horta, A.; Pastoriza, M., A. The Molecular Weight Distribution of Polymer Samples J. Chem. Educ. 2007, 84 (7), 1217-
1221.
S6
Code from Jupyter Notebooks
The code from the Jupyter notebooks is included below for convenience for anyone who wants
to review or use the code outside of the Jupyter environment. The following code includes the imports
(i.e., activation of modules/libraries), simulations, and plotting the results of the simulations.
DNA Simulation
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.set(font_scale=2, style='white')
2D Brownian Motion
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.set(font_scale=2, style='white')
steps = 10000
S7
for step in t:
# random move x direction
position[step, 0] = position[step - 1, 0] + np.random.randint(-1, 2)
# random move x direction
position[step, 1] = position[step - 1, 1] + np.random.randint(-1, 2)
3D Brownian Motion
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.set(font_scale=2, style='white')
from mpl_toolkits.mplot3d import Axes3D
steps = 10000
# only need to do 49 steps being that we already know that we start at (0, 0)
for step in t:
position[t, 0] = position[t - 1, 0] + np.random.randint(-1, 2)
position[t, 1] = position[t - 1, 1] + np.random.randint(-1, 2)
position[t, 2] = position[t - 1, 2] + np.random.randint(-1, 2)
fig = plt.figure(figsize=(8,8))
ax1 = fig.add_subplot(1,1,1, projection='3d')
ax1.plot(position[:,0], position[:,1],position[:,2], '-')
ax1.plot([0],[0],[0], 'o', color='k')
ax1.set_xlabel('Position(x), au', labelpad=15)
ax1.set_ylabel('Position(y), au', labelpad=15)
ax1.set_zlabel('Position(z), au', labelpad=17)
ax1.w_xaxis.set_pane_color((0, 0, 0, 0))
ax1.w_yaxis.set_pane_color((0, 0, 0, 0))
ax1.w_zaxis.set_pane_color((0, 0, 0, 0))
plt.tight_layout()
S8
Diffusion
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import scipy.stats
import seaborn as sns
%matplotlib inline
sns.set(font_scale=2, style='white')
for frame in t:
# add random value to locations
loc += 2 * (np.random.rand(particles) – 0.5)
for step in t:
rand_index = np.random.randint(size) # randomly selects position
molecules[rand_index] = 0 # assigns value to zero
conc[step] = np.sum(molecules) # records number of ones
S9
plt.plot(t, conc/size) # plotted per 1000 molecules in the simulation
plt.xlabel('Iterations')
plt.ylabel('[A]/[A]o')
for step in t:
# generate indices using random number generators
index_B = np.random.randint(0, high=size)
index_C = np.random.randint(0, high=size)
# A -> B reaction
if molecules[index_B] == 0:
molecules[index_B] = 1
# A -> C reaction
if molecules[index_C] == 0 and np.random.randint(0,2) == 1:
molecules[index_C] = 2
S10
Chain-Growth Polymerization
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(font_scale=2, style='white')
for steps in t:
chains += poly_growth # grows the polymers
poly_growth *= np.random.binomial(1, p, size=N) # terminates chains
total_weight = np.sum(chains)
S11
Monte Carlo Calculation of Pi
Image a circle (radius = r) is inscribed inside a square of side length 2r. The area of a circle is
described by Acircle = πr2 whereas the area of the unit square is Asquare = 2r × 2r. We can calculate the ratio
of the areas of the circle and square as π/4.
A circle π r 2 π r 2 π
= = =
A square (2r )2 4 r2 4
The ratio of the two areas can be estimated by generating random points in both the circle and square,
totaling these points up, and dividing the two. This ratio can then be used to calculate a value of π. The
following code performs this simulation.
import numpy as np
def estimate_pi(samples):
'''(integer) -> pi, coordinates
pi = 4 * (np.size(in_circle)/samples)
return (pi, coords)
estimate_pi(1000)
S12