"Noting that A=$\\pi r^2$, we get an estimate for the value of π given by,\n",
"Noting that $A=\\pi r^2$, we get an estimate for the value of π given by,\n",
"\n",
"\n",
"$$ π≈4 \\frac{N_i}{N} $$\n",
"$$ π≈4 \\frac{N_i}{N} $$\n",
"\n",
"\n",
...
...
%% Cell type:markdown id:51574bca tags:
%% Cell type:markdown id:51574bca tags:
## Checkpoint 6
## Checkpoint 6
### Aim
### Aim
To write a Python program to calculate the volume of molecules made up of overlapping spherical atoms; it is also an example in using OOP to simpify the task. Don't get frightened, for this checkpoint you will be given part of the code to help you progress (***this also simulates pretty well how multi-person software development works***).
To write a Python program to calculate the volume of molecules made up of overlapping spherical atoms; it is also an example in using OOP to simpify the task. Don't get frightened, for this checkpoint you will be given part of the code to help you progress (***this also simulates pretty well how multi-person software development works***).
## Monte Carlo estimate of π
## Monte Carlo estimate of π
Consider a circle of radius r within a square of side $2r \times 2r$ as shown in the figure below.
Consider a circle of radius r within a square of side $2r \times 2r$ as shown in the figure below.
If we randomly pick N points evenly distributed within the square and $N_{i}$ of them are inside the circle, then an estimate of the area of the circle A is given by the fraction falling inside the circle multiplied by the area of the square, so
If we randomly pick N points evenly distributed within the square and $N_{i}$ of them are inside the circle, then an estimate of the area of the circle A is given by the fraction falling inside the circle multiplied by the area of the square, so
$$ A=4r^ 2 \frac{N_i}{N} $$
$$ A=4r^ 2 \frac{N_i}{N} $$
Noting that A=$\pi r^2$, we get an estimate for the value of π given by,
Noting that $A=\pi r^2$, we get an estimate for the value of π given by,
$$ π≈4 \frac{N_i}{N} $$
$$ π≈4 \frac{N_i}{N} $$
So provided the selection of points is evenly distributed over the whole square, than as N becomes large you will get a good estimate for $\pi$. This is the basis of Monte Carlo integration and can be used to estimate the internal area of any closed object.
So provided the selection of points is evenly distributed over the whole square, than as N becomes large you will get a good estimate for $\pi$. This is the basis of Monte Carlo integration and can be used to estimate the internal area of any closed object.
See an example Python code that uses the random.uniform() function to form random points:
See an example Python code that uses the random.uniform() function to form random points:
- Code example to calculate $\pi$ [here](../CodeExamples/PiExample.ipynb)
- Code example to calculate $\pi$ [here](../CodeExamples/PiExample.ipynb)
Take a look at this and experiment, you will find that for N>200,000 you get a reasonable estimate for $\pi$, and that as N gets larger the estimate gets better.
Take a look at this and experiment, you will find that for N>200,000 you get a reasonable estimate for $\pi$, and that as N gets larger the estimate gets better.
This is clearly a "very bad" way to calcuate π, but is very useful for finding the area of overlapping objects in two-dimensions as shown in the figure below; which is otherwise analytically tricky.
This is clearly a "very bad" way to calcuate π, but is very useful for finding the area of overlapping objects in two-dimensions as shown in the figure below; which is otherwise analytically tricky.
Here the method is to form a bounding box of dimensions Vb=a×b×c that totally encloses the object. If N points are in the bounding box and N$_i$ are inside the object, then the volume of the object is simply given by
Here the method is to form a bounding box of dimensions Vb=a×b×c that totally encloses the object. If N points are in the bounding box and N$_i$ are inside the object, then the volume of the object is simply given by
$$ V_0=V_b \frac{N_i}{N} $$
$$ V_0=V_b \frac{N_i}{N} $$
This technique is used in computer simulations of molecules to calculate the volume of molecules that are made up of overlapping spherical atoms.
This technique is used in computer simulations of molecules to calculate the volume of molecules that are made up of overlapping spherical atoms.
#### Code Structure
#### Code Structure
This is rather tricky program but it can be vastly simplied by use of OOP; the suggested structure is
This is rather tricky program but it can be vastly simplied by use of OOP; the suggested structure is
1. Form an Atom class by extending the Vector3d class given by Vector3d Class
1. Form an Atom class by extending the Vector3d class given by Vector3d Class
2. The Atom class should add an extra internal variable radius and have a boolean method isInside(v) which takes argument v being a Vector3d and returns True if v is inside the atom. (Note the distance(v) method of Vector3d is useful here.)
2. The Atom class should add an extra internal variable radius and have a boolean method isInside(v) which takes argument v being a Vector3d and returns True if v is inside the atom. (Note the distance(v) method of Vector3d is useful here.)
3. Form a Molecule class that has a list of objects of type Atom and a boolean method isInside(v), which takes argument v being a Vector3d and returns True if v is inside the molecule.
3. Form a Molecule class that has a list of objects of type Atom and a boolean method isInside(v), which takes argument v being a Vector3d and returns True if v is inside the molecule.
- You also need to consider how to read in the location of the atoms; this is similar to Checkpoint 4.
- You also need to consider how to read in the location of the atoms; this is similar to Checkpoint 4.
4. Form a BoundingBox class where the constructor takes a populated Molecule and finds and stores internally the minima / maxima of the box round the molecule (you need 6 floats). This class should have two methods:
4. Form a BoundingBox class where the constructor takes a populated Molecule and finds and stores internally the minima / maxima of the box round the molecule (you need 6 floats). This class should have two methods:
- volume() that gets the volume of the box.
- volume() that gets the volume of the box.
- getRandomPoint() which should return a random Vector3d that is randomly distributed inside the box.
- getRandomPoint() which should return a random Vector3d that is randomly distributed inside the box.
(This is the most “messy” bit of the code to write.)
(This is the most “messy” bit of the code to write.)
If you have this structure, then what your main program has to do is:
If you have this structure, then what your main program has to do is:
- Ask for the file containing the Atom data and read this into a Molecule.
- Ask for the file containing the Atom data and read this into a Molecule.
- Construct a BoundingBox from the Molecule
- Construct a BoundingBox from the Molecule
- Go round a while loop,
- Go round a while loop,
- Getting a random Vector3d from the BoundingBox
- Getting a random Vector3d from the BoundingBox
- Testing if it isInside() the Molecule and incrementing a counter if it is.
- Testing if it isInside() the Molecule and incrementing a counter if it is.
- Finally calculating the estimate for the Molecule volume and printing it out.
- Finally calculating the estimate for the Molecule volume and printing it out.
It is also useful to monitor the progress of the estimate as was done in the example code for estimation of π to check how the integration is going.
It is also useful to monitor the progress of the estimate as was done in the example code for estimation of π to check how the integration is going.
#### Format of Data
#### Format of Data
There are two data files suppied (in the current directory, so they can be read in and executed directly upon here), these being :
There are two data files suppied (in the current directory, so they can be read in and executed directly upon here), these being :
-[oxygen.data](oxygen.data) : single oxygen atom
-[oxygen.data](oxygen.data) : single oxygen atom
-[water.data](water.data) : water molecule
-[water.data](water.data) : water molecule
each consists of a comma delimited CSV file with one atom per line in the format,
each consists of a comma delimited CSV file with one atom per line in the format,
Name , r , x , y , z
Name , r , x , y , z
with comment lines delimited by # being the same format as coded in [Parsing Input](../CourseNotes/ParsingInput.ipynb) and used in [Checkpoint 4](Checkpoint4.ipynb).
with comment lines delimited by # being the same format as coded in [Parsing Input](../CourseNotes/ParsingInput.ipynb) and used in [Checkpoint 4](Checkpoint4.ipynb).
#### Computing Task
#### Computing Task
Write a Python program based on the above structure to:
Write a Python program based on the above structure to:
1. Read in the data file defining the atom locations.
1. Read in the data file defining the atom locations.
2. Prompt the user for the number of points to run in the calculation.
2. Prompt the user for the number of points to run in the calculation.
3. Calculate the volume of the molecule using Monte Carlo integration and output the final value.
3. Calculate the volume of the molecule using Monte Carlo integration and output the final value.
4. Optionally plot a graph of the convergence of the algorithm, being the estimate against number of points. The graph should have 100 data points at regular intervals, see Pi example for how to to this easily.
4. Optionally plot a graph of the convergence of the algorithm, being the estimate against number of points. The graph should have 100 data points at regular intervals, see Pi example for how to to this easily.
5. Test your code with a single oxygen atom and with water. ***For a pass, only the atom is strictly necessary to run.***
5. Test your code with a single oxygen atom and with water. ***For a pass, only the atom is strictly necessary to run.***
> #### Note
> #### Note
> The volume of a single oxygen atom of radius 1.4 Å is 11.494 Å$^3$. The volume of water is $\approx$ 15.5 Å$^3$. Use these values to check your results before calling a demonstrator.
> The volume of a single oxygen atom of radius 1.4 Å is 11.494 Å$^3$. The volume of water is $\approx$ 15.5 Å$^3$. Use these values to check your results before calling a demonstrator.
6. Have another careful read of [final weekly task](../WeeklyTasks/Week6.ipynb).
6. Have another careful read of [final weekly task](../WeeklyTasks/Week6.ipynb).
%% Cell type:code id:9376506d tags:
%% Cell type:code id:9376506d tags:
``` python
``` python
""""
""""
A more developed Vector class for simple 3d vectors
A more developed Vector class for simple 3d vectors
"""
"""
importmath
importmath
importrandom
importrandom
classVector3d(object):
classVector3d(object):
"""
"""
Simple vector 3d class
Simple vector 3d class
"""
"""
def__init__(self,x,y,z):
def__init__(self,x,y,z):
"""
"""
Constructor to form a vector
Constructor to form a vector
"""
"""
self.x=float(x)
self.x=float(x)
self.y=float(y)
self.y=float(y)
self.z=float(z)
self.z=float(z)
def__str__(self):
def__str__(self):
"""
"""
Method to format a vector as a string (implments str())
Method to format a vector as a string (implments str())