Empirical dispersion accounts for the fact that Density Functional Theory systematically underestimates Van der Waals interactions. DFT-D and DFT-D2 are very simple. DFT-D3 is a bit more complex.
DFT-D and DFT-D2 both consist of a pairwise -1/r^6 attraction, like a Lennard-Jones attraction, scaled by a parameter C6 and a damping function which prevents the energy from going to -∞ at r=0. The distance parameter r0 is just the sum of the covalent radii of the interacting pair of atoms. The energy parameter C6 is the geometric mean of the two element-wise C6 parameters. Importantly, neither C6 or r0 depend on anything but the pair of elements involved. That makes DFT-D and DFT-D2 very easy to implement.
The following code implements the DFT-D2 energy as used in the wB97X-D functional ("Long-range corrected hybrid density functionals with damped atom–atom dispersion corrections", Chai & Head-Gordon, 2008). DFT-D and variants use other choices of damping function but are otherwise the same. Parameters C6 and covalent radii are available in "Semiempirical GGA-type density functional constructed with a long-range dispersion correction", Grimme, 2006. Currently both of these papers are available as PDFs on Google Scholar. You can get the parameters
def dftd2_wB97XD(r, ai, aj):
r6 = r**6
c6 = sqrt(c6_coefficients[ai] * c6_coefficients[aj])
r0 = covalent_radii[ai] + covalent_radii[aj]
fdamp = 1.0 / (1.0 + 6.0 * (r / r0)**-12.0)
return -fdamp * c6 / r6
Be careful about the units of the parameters - J/mol nm^6 for C6, and Å for the covalent radii. In a real use case, you probably want C6 in kcal/mol Å^6 or Hartree Å^6.
DFT-D3 is conceptually only a little more complex: -C6/r^6 * fdamp6 + C8/r^8 * fdamp8. However, the parameters C6 and C8 depend on the coordination number of each atom, estimated using the distances to other nearby atoms. This makes DFT-D3 more accurate than the earlier versions. A good description can be found at https://www.vasp.at/wiki/index.php/DFT-D3.
There is also an even newer variant, DFT-D4, which continues to add accuracy and complexity by first estimating the atomic partial charges, and then using them to estimate the dispersion parameters. In this way, each atom's dispersion parameters depend on the entire surrounding environment. The paper for the D4 correction is here: https://chemrxiv.org/articles/A_Generally_Applicable_Atomic-Charge_Dependent_London_Dispersion_Correction_Scheme/7430216