PRACTICAL Implementation of Classical Molecular Dynamics Simulations using Python: (I) Initialization, Boundary conditions, Interaction Potentials, and Thermostat
Classical molecular dynamics is a computational simulation technique used to model structural and dynamical behaviors of particles over time. It is based on the principles of classical mechanics and the Newton's equations of motion to describe the time "evolution" of a system with interacting particles.
In this tutorial, we provide a practical implementation of classical molecular dynamics simulations using Python. This simulation involves the initialization of modelling systems, the selection of boundary conditions, the calculation of interaction potentials (energies and forces) between interacting particles, and their integrations over time so as to animate their dynamical evolution in the modelling system.
Contents of this documents and quicklinks:
A classical molecular dynamics simulation starts with the initialization of positions for particles. For simplicity, we construct a two dimensional modelling system consisting of 16 particles in a simulation box with the box size of 10*10.
Then we generate random positions for these particles using numpy
,
in which the positions
is a list containing numAtoms
items with the X and Y coordinates of each particle being the first and the second one in each item. In order to ensure that everyone can get the same sequence of random numbers when running this script, we set a specific seed value through
, which is particularly useful for debugging and testing purposes, as it allows you to create predictable and repeatable results.
For molecules with complicated structures, it is feasible to read coordination info from an external file instead of generating random positions for molecules.
Data visualization and animation are powerful tools for exploring and presenting data in a visual and dynamic way. For classical molecular dynamics simulations, the animation of simulation trajectories provides a vivid representation of the movement of simulated particles within the modelling system as time evolves.
Matplotlib is a comprehensive and the most widely used library for creating static, animated, and interactive visualizations using Python. Celluloid is a Python library that simplifies the process of creating animations by automatically capturing each configuration in simulation trajectories as Matplotlib plots are generated, eliminating the need to manually manage configuration generation.
Herein, we use matplotlib and celluloid to animate the simulation trajectories of the modelling system with interacting particles.
The code example for the animation part is provided below:
Combining all these code together into a file named ex1-initialization.py, we run this script and obtain the following figure.
In addition to positions, we will generate initial velocities for all particles. This is not necessary as in real modelling systems we can obtain these information via integrating particle positions over time. Herein for simplicity we generate a set of random velocities for all particles.
Here we assume that there is NO interactions between particles, meaning that the motion of all particles at all directions are independent.
We set all particles to run 100 steps with a timestep of 0.5, and we will calibrate these parameters when introducing appropriate interaction potentials.
A simple function is introduced to update positions of particles as time evolves.
Accordingly, a for loop will be provided in the animation part to capture instantaneous positions of all particles at each step.
These code are assembled into a new script ex2-boundary-conditions-1-particle-motion.py to obtained the following animation.
From the above animation, it is shown that all particles gradually fly out of the simulation box. This is not what we expect as we want to track the motion of all particles within the simulation box. As such, we will introduce proper boundary conditions for the modelling system.
Boundary condition specifies the behavior of a modelling system at its boundaries or interfaces with the external environment. Boundary condition is crucial for accurately modeling the behavior of physical systems and ensuring that simulations produce meaningful results.
There are several types of boundary conditions in classical molecular dynamics simulations:
Besides these boundary conditions, there are some others that are widely used to simulate particular modelling systems. A comprehensive discussion of boundary conditions is available HERE.
PBC applies to simulations with a finite box size but can achieve an infinite system via replicating the system box in all directions. With PBC, particles leaving one side of the simulation box re-enter from the opposite side, which is achieved via the following code.
This code is implemented into a new function boundary_conditions
.
By passing periodic
to a variable boundaryCondition
, we run the script ex2-boundary-conditions-2-boundary.py and obtain the follow animation.
In a reflective boundary condition, particles are reflected back into simulation box when they reach boundaries, mimicking the behavior of fluid particles when they hit solid walls. Meanwhile, the velocities of particles at specific directions will be reversed. This condition can be achieved via the code below.
Passing reflective
to the variable boundaryCondition
, we run the script ex2-boundary-conditions-2-boundary.py and obtain the follow animation.
In above code examples, there is no interactions between particles, indicating that all particles have independent diffusion at all directions. In addition, particles can also pass through others during diffusion, and can even have complete overlap with the other particles.
In real modelling simulations, we can include interaction potentials to simulate particles with particular characteristics.
Particle interaction potentials describe the energy and force associated with specific interactions between particles in simulation systems. These potentials are fundamental in determining structural and dynamical quantities of interacting particles in modelling systems.
In this tutorial, we implement the Lennard-Jones potential in the code example, which is defined by the following equation:
where is the distance between interacting particles, is the depth of the potential well usually referred to as the strength of attractive interaction between particles, and is the finite distance at which the inter-particle potential is zero, representing the distance at which the attractive and repulsive forces balance. The Lennard-Jones potential has its minimum at a distance of , where the potential energy has the value .
The code example for the Lennard-Jones energy and force (the derivative of the potential) with reduced units of and are available in the script ex3-potential-1-lj.py and representative plots are shown below.
Before the code implementation, we define parameters representing particle masses, interaction energies, forces, and accelerations acting on all particles.
It should be noted that the Lennard-Jones potential has a singularity when , leading to an infinite force on particles. This singularity can cause numerical instabilities and simulation system crashes when particles get too close to each other. To avoid these issues, we generate particle positions on regular lattices instead of at random positions.
Additional note should be emphasized that when we use PBC in simulations, a particle moves beyond one side of the simulation box, it re-enters into the box from the opposite side as if the simulation box was replicated infinitely in all directions. This concept is often illustrated as "periodic images" or "image cells" to represent periodic replicas of the central simulation box. During the calculation of interaction energies and forces, we should determine the shortest distance between two interacting particles and their periodic images using the minimum image convention, which can be achieved via the code below.
Combining the code mentioned above and the ex3-potential-1-lj.py together into a new function lj_potential
in ex3-potential-2-potential-thermostat.py, we can determine the specific energies and forces acting on all interacting particles.
Once we obtain the Lennard-Jones forces acting on all particles, we can calculate the accelerations on all particles, and therefore to update their velocities via a new function update_velocities
.
In classical molecular dynamics simulations, a thermostat is usually used to control the temperature of simulation system so as to reproduce statistical properties of certain thermodynamic ensembles. The velocity rescaling thermostat is a common method used to control the temperature of simulation systems via rescaling velocities of all particles at regular intervals to achieve a desired temperature. Below is the code to implement this method through a new function thermostat
.
Based on these implementations, we call these newly added functions from the iteration loop in the following code snippets.
In addition, a small timestep will be used in order to keep the simulation system relatively stable.
This is one of the first, of many, tradeoffs of accuracy vs. computational efficiency for classical molecular dynamics simulations. In fact using an extremely small time-step may lead to accurate simulation results, but at a cost of longer computation time or reduced total simulation time which can reduce statistical reliability. A larger time-step may help assist in larger or longer time-scales but at the cost of physical accuracy. It should be emphasized that such a tradeoff between accuracy and computational time is NOT unique to classical molecular dynamics, and can be found in practically every computational modeling technique.
Combining all code examples into the Python script ex3-potential-2-potential-thermostat.py, we run this Python script and get the following animation.
In this tutorial we have provided practical implementation of classical molecular dynamics simulations using Python focusing on
In the next tutorial, we will explore how to use additional simulation techniques to accelerate simulations of modelling systems containing thousands of particles.