LAMMPS from scratch · 25 min

The families of styles

Pair, bond, angle, dihedral, improper, kspace, fix and compute styles each have their own moment in a timestep and their own number in the output. One united-atom butane molecule, built from bond lengths, angles and a dihedral you choose, lets every family speak once: you predict each energy and each geometric value by hand and LAMMPS reports the same. On the way, a hand calculation shows that fix restrain dihedral holds the molecule 180° away from the angle the manual promises.

1 · Understand: who speaks when in one timestep

Page B.3 showed one family (pair) in detail. Every family works the same way: a base class with sockets, many plugs. What differs is when the main loop calls them. The order inside one step of Verlet::run() (src/verlet.cpp:258):

258  modify->initial_integrate(vflag);        // FIX: first half of velocity Verlet (nve, nvt …)
306  force_clear();                           // all forces f = 0
316  force->pair->compute(eflag,vflag);       // PAIR
321  if (force->bond) force->bond->compute(eflag,vflag);          // BOND
322  if (force->angle) force->angle->compute(eflag,vflag);        // ANGLE
323  if (force->dihedral) force->dihedral->compute(eflag,vflag);  // DIHEDRAL
324  if (force->improper) force->improper->compute(eflag,vflag);  // IMPROPER
329  force->kspace->compute(eflag,vflag);     // KSPACE (long-range Coulomb)
347  if (n_post_force_any) modify->post_force(vflag);   // FIX: add or change forces (restrain, addforce, langevin …)
348  modify->final_integrate();               // FIX: second half of velocity Verlet
349  if (n_end_of_step) modify->end_of_step();          // FIX: averages, printing, thermostats …
356  output->write(ntimestep);                // asks COMPUTEs for the numbers it prints
FamilyBase classIts jobThermo keywordIn this browser
pairPairforces between nearby atomsevdwl, ecoullj/cut, morse, buck …
bondBondforce along each listed bondebondharmonic, fene, morse …
angleAngleforce on each listed angleeangleharmonic, cosine, charmm …
dihedralDihedraltwist around the middle bond of 4 atomsedihedopls, harmonic, charmm …
improperImproperkeeps 4 atoms flat or a centre chiraleimpharmonic, cvff, umbrella
kspaceKSpacethe long-range part of Coulombelongnone here (page D.6)
fixFixanything that changes the motion: integrate, thermostat, add forcesf_ID79 styles
computeComputemeasures, never changes anythingc_ID68 styles

A useful rule: forces come from pair, bonded and kspace styles; fixes move atoms and may add forces; computes only read.

2 · Modify: build a butane molecule

Four united atoms, CH₃–CH₂–CH₂–CH₃, with TraPPE-like parameters. The page places the atoms from three bond lengths (1.55, 1.53, 1.56 Å), two angles (110°, 116°) and the dihedral φ you choose, writes the data file (page A.8), and gives it to LAMMPS.

butane.data and the script

3 · Predict by hand, then run

4 · Observe: what each family said

5 · A surprise: where does fix restrain hold the dihedral?

The manual for fix restrain says E = K[1 + cos(nφ − d)] with d = φ₀ + 180°, so that the energy is lowest at φ = φ₀. The code (src/fix_restrain.cpp:135 and src/fix_restrain.cpp:642) uses d = φ₀:

135  target[nrestrain] = DEG2RAD * utils::numeric(FLERR,arg[iarg+7],false,lmp);   // φ₀, no + 180
642  p = p*cos_target[m] + df1*sin_target[m];      // cos(φ − φ₀)
645  p += 1.0;
647  edihed += k * p;                              // E = K[1 + cos(φ − φ₀)]: HIGHEST at φ = φ₀

Section 3 already showed it: the hand value with the code's formula matches f_r; the manual's formula does not. To see what it does to a molecule, minimize with the restraint as the only dihedral term and look where φ ends:

The same lines are in the current development version and in versions back to at least 2018. If you use fix restrain dihedral (for example to scan a torsion profile), check φ after the run, or give φ₀ − 180°.

Your turn

1. Which φ gives E_dihed = 0? Predict from the OPLS formula, then set it.

2. Set φ = 0 (cis) with 1–4 weight 1. Why does E_vdwl explode?

3. Which family would you use to keep atom 1 from moving, and why not a compute?