Use the force¶
Topic: atomistic models, pair potentials, conservative forces
- Task:
Implement the method that calculates forces on all atoms.
Run the program and compare your forces against values the program calculates by numerically differentiating the potential energy. If your function works, all values should be a close match. If there are any notable discrepancies, there is a bug.
Change the \(\Delta\) parameter and study how it affects numeric accuracy. Does the numeric result approach your analytic solution?
Make the program create random configurations and check that you always get matching results.
Template: forces.py
Data: atoms.txt
forces.py¶
- class forces.Atom(position, velocity, mass=1.0)[source]¶
A point like object.
An atom has a position (a 3-vector), a velocity (3-vector) and a mass (a scalar).
- Parameters:
position (array) – coordinates \([x, y, z]\)
velocity (array) – velocity components \([v_x, v_y, v_z]\)
mass (float) – mass \(m\)
- forces.calculate_forces(atoms, parameters)[source]¶
Calculates the total force applied on each atom.
The forces are returned as a numpy array where each row contains the force on an atom and the columns contain the x, y and z components.
[ [ fx0, fy0, fz0 ], [ fx1, fy1, fz1 ], [ fx2, fy2, fz2 ], ... ]
Note
This function is incomplete!
- Parameters:
atoms (list) – a list of
forces.Atom
objectsparameters (list) – a list of physical parameters
- Returns:
forces
- Return type:
array
- forces.calculate_potential_energy(atoms, parameters)[source]¶
Calculates the total potential energy of the system.
The potential energy is calculated using the Lennard-Jones model
\[U = \sum_{i \ne j} 4 \epsilon \left( \frac{ \sigma^{12} }{ r^{12}_{ij} } - \frac{ \sigma^6 }{ r^6_{ij} } \right).\]- Parameters:
atoms (list) – a list of
forces.Atom
objectsparameters (list) – a list of physical parameters
- Returns:
potential energy
- Return type:
array
- forces.create_random_configuration(n=10)[source]¶
Randomly creates a set of
Atom
objects.The atoms are placed uniformly in a \([-3, 3] \times [-3, 3] \times [-3, 3]\) box. They are also given random velocities and masses.
- Parameters:
n (int) – number of atoms
- Returns:
the atoms
- Return type:
list
- forces.distance_squared(atom1, atom2)[source]¶
Calculates the squared distance between two atoms,
\[r^2_{ij} = (x_i-x_j)^2 + (y_i-y_j)^2 + (z_i-z_j)^2.\]- Parameters:
atom1 (forces.Atom) – the first atom
atom2 (forces.Atom) – the second atom
- Returns:
the squared distance \(r^2_{ij}\)
- Return type:
float
- forces.draw_particles_and_forces(atoms, forces_A, forces_B=None)[source]¶
Draws the particles and forces as dots and arrows in the xy plane.
The function accepts two sets of forces and draws them both so that the forces can be compared to each other.
- Parameters:
atoms (list) – a list of
forces.Atom
objectsforces_A (array) – forces on all atoms
forces_B (array) – forces on all atoms
- forces.energy_gradient(atoms, alpha, delta, parameters)[source]¶
Calculates a numeric approximation for the gradient of the potential energy with respect to the position of one atom.
The potential energy of the system is defined via
calculate_potential_energy()
, and it is a function of the coordinates of all atoms,\[U = U(x_0, y_0, z_0, x_1, y_1, z_1, \ldots).\]The force of a conservative interaction is given by the gradient of the potential energy. More precisely, the force on atom \(\alpha\) is the gradient with respect to the coordinates of that particular atom,
\[\vec{F}_\alpha = - \nabla_\alpha U = \frac{ \partial U }{\partial x_{\alpha} } \hat{i} + \frac{ \partial U }{\partial y_{\alpha} } \hat{j} + \frac{ \partial U }{\partial z_{\alpha} } \hat{k}.\]This function calculates this vector numerically. Each partial derivative is calculated using the symmetric finite difference result
\[\frac{ \partial U }{\partial x } = \frac{ U(x+\Delta) - U(x-\Delta) }{2 \Delta}.\]In practice, the function shifts atom \(\alpha\) and calls
calculate_potential_energy()
to obtain the needed energies.- Parameters:
atoms (list) – a list of
forces.Atom
objectsalpha (int) – index of the atom with respect to which the gradient is calculated
delta (float) – the shift \(\Delta\) used for calculating finite differences
- Returns:
force components \([ F_{x,\alpha}, F_{y,\alpha}, F_{z,\alpha} ]\)
- Return type:
array
- forces.main(delta=0.001, random_atoms=0)[source]¶
The main program.
Reads the particle data from the file
atoms.txt
or creates a random configuration and calculates the forces acting on all particles both directly withcalculate_forces()
and by numerically differentiating the potential energy withenergy_gradient()
. The method reports these results as well as the error\[\Delta \vec{F} = \vec{F}_\text{analytic} - \vec{F}_\text{numeric},\]its absolute value \(|\Delta \vec{F}|\) and the error relative to the magnitude of the force, \(|\Delta \vec{F}| / |\vec{F}_\text{numeric}|\).
If the force calculation is correct, the results should be approximately the same and the error should be close to zero. Due to numeric inaccuracy, one expects a difference which approaches zero as \(\Delta\) goes to zero.
- Parameters:
delta (float) – the shift \(\Delta\) used for calculating finite differences
random_atoms (int) – If zero, configuration is read form file. If positive, a random system with that many atoms is created.
- forces.read_atoms_from_file(filename)[source]¶
Reads the properties of atoms from a file.
Each line should define a single
forces.Atom
listing its position in cartesian coordinates, velocity components and mass, separated by whitespace:x0 y0 z0 vx0 vy0 vz0 m0 x1 y1 z1 vx1 vy1 vz1 m1 x2 y2 z2 vx2 vy2 vz2 m2 x3 y3 z3 vx3 vy3 vz3 m3 ...
- Parameters:
filename (str) – name of the file to read
- Returns:
list of
forces.Atom
objects- Return type:
list
- forces.vector(atom1, atom2)[source]¶
The vector pointing from one atom, \(i\), to another, \(j\),
\[\vec{r}_{i \to j} = \vec{r}_j - \vec{r}_i\]- Parameters:
atom1 (forces.Atom) – the first atom
atom2 (forces.Atom) – the second atom
- Returns:
components of \(\vec{r}_{i \to j}\), \([x_{i \to j}, y_{i \to j}, z_{i \to j}]\)
- Return type:
array