Skip to content

Commit 13132ae

Browse files
committed
implemented hard sphere potential
1 parent 88a7064 commit 13132ae

File tree

3 files changed

+38
-15
lines changed

3 files changed

+38
-15
lines changed

docs/source/chapters/chapter1.rst

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,33 +66,51 @@ between atoms. Although more complicated options exist, potentials are usually
6666
defined as functions of the distance :math:`r` between two atoms.
6767

6868
Within a dedicated folder, create the first file named *potentials.py*. This
69-
file will contain a function named *LJ_potential* for the Lennard-Jones
70-
potential (LJ). Copy the following into *potentials.py*:
69+
file will contain a function called *potentials*. Two types of potential can
70+
be returned by this function: the Lennard-Jones potential (LJ), and the
71+
hard-sphere potential.
72+
73+
Copy the following lines into *potentials.py*:
7174

7275
.. label:: start_potentials_class
7376

7477
.. code-block:: python
7578
76-
def LJ_potential(epsilon, sigma, r, derivative = False):
77-
if derivative:
78-
return 48*epsilon*((sigma/r)**12-0.5*(sigma/r)**6)/r
79+
def potentials(potential_type, epsilon, sigma, r, derivative=False):
80+
if potential_type == "Lennard-Jones":
81+
if derivative:
82+
return 48 * epsilon * ((sigma / r) ** 12 - 0.5 * (sigma / r) ** 6) / r
83+
else:
84+
return 4 * epsilon * ((sigma / r) ** 12 - (sigma / r) ** 6)
85+
elif potential_type == "Hard-Sphere":
86+
if derivative:
87+
raise ValueError("Derivative is not defined for Hard-Sphere potential.")
88+
else:
89+
return 1000 if r < sigma else 0
7990
else:
80-
return 4*epsilon*((sigma/r)**12-(sigma/r)**6)
91+
raise ValueError(f"Unknown potential type: {potential_type}")
8192
8293
.. label:: end_potentials_class
8394

84-
Depending on the value of the optional argument *derivative*, which can be
85-
either *False* or *True*, the *LJ_potential* function will return the force:
95+
The hard-sphere potential either returns a value of 0 when the distance between
96+
the two particles is larger than the parameter, :math:`r > \sigma`, or 1000 when
97+
:math:`r < \sigma`. The value of *1000* was chosen to be large enough to ensure
98+
that any Monte Carlo move that would lead to the two particles to overlap will
99+
be rejected.
100+
101+
In the case of the LJ potential, depending on the value of the optional
102+
argument *derivative*, which can be either *False* or *True*, the *LJ_potential*
103+
function will return the force:
86104

87105
.. math::
88106
89-
F_\text{LJ} = 48 \dfrac{\epsilon}{r} \left[ \left( \frac{\sigma}{r} \right)^{12}- \frac{1}{2} \left( \frac{\sigma}{r} \right)^6 \right],
107+
F_\text{LJ} = 48 \dfrac{\epsilon}{r} \left[ \left( \frac{\sigma}{r} \right)^{12} - \frac{1}{2} \left( \frac{\sigma}{r} \right)^6 \right],
90108
91109
or the potential energy:
92110

93111
.. math::
94112
95-
U_\text{LJ} = 4 \epsilon \left[ \left( \frac{\sigma}{r} \right)^{12}- \left( \frac{\sigma}{r} \right)^6 \right].
113+
U_\text{LJ} = 4 \epsilon \left[ \left( \frac{\sigma}{r} \right)^{12} - \left( \frac{\sigma}{r} \right)^6 \right].
96114
97115
Create the Classes
98116
------------------
@@ -124,7 +142,7 @@ copy the following lines:
124142

125143
.. code-block:: python
126144
127-
from potentials import LJ_potential
145+
from potentials import potentials
128146
129147
130148
class Utilities:

docs/source/chapters/chapter2.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,14 @@ Modify the *Prepare* class as follows:
9999
epsilon=[0.1], # List - Kcal/mol
100100
sigma=[3], # List - Angstrom
101101
atom_mass=[10], # List - g/mol
102+
potential_type="Lennard-Jones",
102103
*args,
103104
**kwargs):
104105
self.number_atoms = number_atoms
105106
self.epsilon = epsilon
106107
self.sigma = sigma
107108
self.atom_mass = atom_mass
109+
self.potential_type = potential_type
108110
super().__init__(*args, **kwargs)
109111
110112
.. label:: end_Prepare_class
@@ -114,7 +116,10 @@ Here, the four lists *number_atoms* :math:`N`, *epsilon* :math:`\epsilon`,
114116
:math:`10`, :math:`0.1~\text{[Kcal/mol]}`, :math:`3~\text{[Å]}`, and
115117
:math:`10~\text{[g/mol]}`, respectively.
116118

117-
All four parameters are assigned to *self*, allowing other methods to access
119+
The type of potential is also specified, with Lennard-Jones being closen as
120+
the default option.
121+
122+
All the parameters are assigned to *self*, allowing other methods to access
118123
them. The *args* and *kwargs* parameters are used to accept an arbitrary number
119124
of positional and keyword arguments, respectively.
120125

@@ -130,7 +135,7 @@ unit system to the *LJ* unit system:
130135
.. code-block:: python
131136
132137
def calculate_LJunits_prefactors(self):
133-
"""Calculate the Lennard-Jones units prefacors."""
138+
"""Calculate the Lennard-Jones units prefactors."""
134139
# Define the reference distance, energy, and mass
135140
self.reference_distance = self.sigma[0] # Angstrom
136141
self.reference_energy = self.epsilon[0] # kcal/mol

docs/source/chapters/chapter4.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,9 @@ class.
298298
rij = np.linalg.norm(rij_xyz, axis=1)
299299
# Measure potential
300300
if output == "potential":
301-
energy_potential += np.sum(LJ_potential(epsilon_ij, sigma_ij, rij))
301+
energy_potential += np.sum(potentials(self.potential_type, epsilon_ij, sigma_ij, rij))
302302
else:
303-
derivative_potential = LJ_potential(epsilon_ij, sigma_ij, rij, derivative = True)
303+
derivative_potential = potentials(self.potential_type, epsilon_ij, sigma_ij, rij, derivative = True)
304304
if output == "force-vector":
305305
forces[Ni] += np.sum((derivative_potential*rij_xyz.T/rij).T, axis=0)
306306
forces[neighbor_of_i] -= (derivative_potential*rij_xyz.T/rij).T

0 commit comments

Comments
 (0)