A high-performance Molecular Dynamics (MD) engine written in C++ and CUDA. It uses a hybrid architecture where bond/angle forces are calculated on the CPU (OpenMP) and non-bonded interactions (Lennard-Jones + Coulomb) are accelerated on the GPU.
mdsim.mp4
Using OVITO for the visualization.
- GPU (CUDA): Handles the computationally expensive non-bonded pair interactions (Lennard-Jones + Coulombic). This is the dominant cost ($O(N \times \text{neighbors})$).
-
CPU (OpenMP): Handles bonded interactions (harmonic bonds, harmonic angles) and integration.
- Threads: Dynamic scheduling with
#pragma omp parallel for. - Synchronization: Forces are computed independently on CPU/GPU and summed into a shared force array before the integration step.
- Threads: Dynamic scheduling with
I used a spatial hashing algorithm on the GPU to avoid the
-
Binning: The simulation box is divided into cubic cells of side length
$d \ge r_{cut} + \text{skin}$ . Each atom is hashed to a 1D cell index$k = x_{grid} + y_{grid} \cdot D + z_{grid} \cdot D^2$ . - Sorting: Atoms are sorted by cell ID using CUB Radix Sort.
- Indexing: A lookup table (cell_start, cell_end) is generated to map cell IDs to start/end indices in the sorted atom array.
-
Adjacency Build: For every atom, the kernel searches only the 27 adjacent cells (3x3x3 block). Neighbors within
$r < r_{cut} + \text{skin}$ are stored in a fixed-width adjacency list per atom.
The engine simulates the following molecular systems:
- Water (H₂O): Includes proper bonding and angle parameters for water molecules
- Argon (Ar): Monatomic noble gas simulations
- Methane (CH₄): Multi-atom hydrocarbon simulations with bonding
The engine uses Langevin Dynamics instead of standard Newtonian physics (
Calculated between all pairs of atoms (excluding bonded neighbors) that fall within the cutoff radius (
The engine utilizes the BAOAB splitting method to integrate the Langevin equations of motion.
The accuracy of the simulation was confirmed by computing the Radial Distribution Function (RDF) and comparing against reference data.
Parameters: 1000 molecules, 31.0 Å box length, 0.5 fs time step, 50.0 fs simulation time
| Configuration | Best Time |
|---|---|
| Single-core (baseline) | 13.94 seconds |
| OpenMP parallelization | 2.46 seconds |
Improvement: 82% faster.
Parameters: 1000 molecules, 31.0 Å box length, 0.5 fs time step, 5000.0 fs simulation time
| Configuration | Best Time |
|---|---|
| OpenMP CPU | 245.12 seconds |
| CUDA GPU | 70.26 seconds |
Improvement: 3.5x faster.
Here are some resources I used to learn and help write the code.
- Used this as a starting point: Molecular Dynamics Simulation Introduction
- Textbook: Computer Simulations of Liquids - Allen & Tildesley
- C++: LearnCpp.com
- Good video on CUDA basics: CUDA Programming Tutorial
- Move bond/angle force computing onto GPU for improved performance
- Implement NPT (isothermal-isobaric) ensemble for pressure control