Skip to main content

Torch Autodiff for DFT-D4

Compatibility: Python Versions PyTorch Versions
Availability: Release PyPI Conda Version Apache-2.0
Status: Test Status Ubuntu Test Status macOS (ARM) Test Status Windows Build Status Documentation Status pre-commit.ci Status Coverage

Implementation of the DFT-D4 dispersion model in PyTorch. This module allows to process a single structure or a batch of structures for the calculation of atom-resolved dispersion energies.

If you use this software, please cite the following publication:

  • M. Friede, C. Hölzer, S. Ehlert, S. Grimme, J. Chem. Phys., 2024, 161, 062501. DOI: 10.1063/5.0216715

For details on the D4 dispersion model, see:

  • E. Caldeweyher, C. Bannwarth and S. Grimme, J. Chem. Phys., 2017, 147, 034112. DOI: 10.1063/1.4993215
  • E. Caldeweyher, S. Ehlert, A. Hansen, H. Neugebauer, S. Spicher, C. Bannwarth and S. Grimme, J. Chem. Phys., 2019, 150, 154122. DOI: 10.1063/1.5090222
  • E. Caldeweyher, J.-M. Mewes, S. Ehlert and S. Grimme, Phys. Chem. Chem. Phys., 2020, 22, 8499-8512. DOI: 10.1039/D0CP00502A

For alternative implementations, also check out:

  • dftd4: Implementation of the DFT-D4 dispersion model in Fortran with Python bindings.
  • cpp-d4: Implementation of the DFT-D4 dispersion model in C++.

Installation

pip PyPI Version PyPI Downloads

tad-dftd4 can easily be installed with pip.

pip install tad-dftd4

conda Conda Version Conda Downloads

tad-dftd4 is also available from conda.

conda install tad-dftd4

From source

This project is hosted on GitHub at dftd4/tad-dftd4. Obtain the source by cloning the repository with

git clone https://github.com/dftd4/tad-dftd4
cd tad-dftd4

We recommend using a conda environment to install the package. You can setup the environment manager using a mambaforge installer. Install the required dependencies from the conda-forge channel.

mamba env create -n torch -f environment.yaml
mamba activate torch

Install this project with pip in the environment

pip install .

The following dependencies are required

Compatibility

PyTorch \ Python 3.8 3.9 3.10 3.11 3.12 3.13 3.14
1.11.0 ✅ ✅ ❌ ❌ ❌ ❌ ❌
1.12.1 ✅ ✅ ✅ ❌ ❌ ❌ ❌
1.13.1 ✅ ✅ ✅ ✅ ❌ ❌ ❌
2.0.1 ✅ ✅ ✅ ✅ ❌ ❌ ❌
2.1.2 ✅ ✅ ✅ ✅ ❌ ❌ ❌
2.2.2 ✅ ✅ ✅ ✅ ✅ ❌ ❌
2.3.1 ✅ ✅ ✅ ✅ ✅ ❌ ❌
2.4.1 ✅ ✅ ✅ ✅ ✅ ❌ ❌
2.5.1 ❌ ✅ ✅ ✅ ✅ ❌ ❌
2.6.0 ❌ ✅ ✅ ✅ ✅ ✅ ❌
2.7.1 ❌ ✅ ✅ ✅ ✅ ✅ ❌
2.8.0 ❌ ✅ ✅ ✅ ✅ ✅ ❌
2.9.1 ❌ ❌ ✅ ✅ ✅ ✅ ✅
2.10.0 ❌ ❌ ✅ ✅ ✅ ✅ ✅

Note that only the latest bug fix version is listed, but all preceding bug fix minor versions are supported. For example, although only version 2.2.2 is listed, version 2.2.0 and 2.2.1 are also supported.

On macOS and Windows, PyTorch<2.0.0 does only support Python<3.11.

Development

For development, additionally install the following tools in your environment.

mamba install black covdefaults mypy pre-commit pylint pytest pytest-cov pytest-xdist tox
pip install pytest-random-order

With pip, add the option -e for installing in development mode, and add [dev] for the development dependencies

pip install -e .[dev]

The pre-commit hooks are initialized by running the following command in the root of the repository.

pre-commit install

For testing all Python environments, simply run tox.

tox

Note that this randomizes the order of tests but skips "large" tests. To modify this behavior, tox has to skip the optional posargs.

tox -- test

Examples

All examples can also be found in the examples directory.

The following example shows how to calculate the DFT-D4 dispersion energy for a single structure.

import torch
import tad_dftd4 as d4
import tad_mctc as mctc

numbers = mctc.convert.symbol_to_number(symbols="C C C C N C S H H H H H".split())

# coordinates in Bohr
positions = torch.tensor(
    [
        [-2.56745685564671, -0.02509985979910, 0.00000000000000],
        [-1.39177582455797, +2.27696188880014, 0.00000000000000],
        [+1.27784995624894, +2.45107479759386, 0.00000000000000],
        [+2.62801937615793, +0.25927727028120, 0.00000000000000],
        [+1.41097033661123, -1.99890996077412, 0.00000000000000],
        [-1.17186102298849, -2.34220576284180, 0.00000000000000],
        [-2.39505990368378, -5.22635838332362, 0.00000000000000],
        [+2.41961980455457, -3.62158019253045, 0.00000000000000],
        [-2.51744374846065, +3.98181713686746, 0.00000000000000],
        [+2.24269048384775, +4.24389473203647, 0.00000000000000],
        [+4.66488984573956, +0.17907568006409, 0.00000000000000],
        [-4.60044244782237, -0.17794734637413, 0.00000000000000],
    ]
)

# total charge of the system
charge = torch.tensor(0.0)

# TPSSh-D4-ATM parameters
param = {
    "s6": positions.new_tensor(1.0),
    "s8": positions.new_tensor(1.85897750),
    "s9": positions.new_tensor(1.0),
    "a1": positions.new_tensor(0.44286966),
    "a2": positions.new_tensor(4.60230534),
}

# parameters can also be obtained using the functional name:
# param = d4.get_params("tpssh")

energy = d4.dftd4(numbers, positions, charge, param)
torch.set_printoptions(precision=10)
print(energy)
# tensor([-0.0020841344, -0.0018971195, -0.0018107513, -0.0018305695,
#         -0.0021737693, -0.0019484236, -0.0022788253, -0.0004080658,
#         -0.0004261866, -0.0004199839, -0.0004280768, -0.0005108935])

The next example shows the calculation of dispersion energies for a batch of structures.

import torch
import tad_dftd4 as d4
import tad_mctc as mctc

# S22 system 4: formamide dimer
numbers = mctc.batch.pack((
    mctc.convert.symbol_to_number("C C N N H H H H H H O O".split()),
    mctc.convert.symbol_to_number("C O N H H H".split()),
))

# coordinates in Bohr
positions = mctc.batch.pack((
    torch.tensor([
        [-3.81469488143921, +0.09993441402912, 0.00000000000000],
        [+3.81469488143921, -0.09993441402912, 0.00000000000000],
        [-2.66030049324036, -2.15898251533508, 0.00000000000000],
        [+2.66030049324036, +2.15898251533508, 0.00000000000000],
        [-0.73178529739380, -2.28237795829773, 0.00000000000000],
        [-5.89039325714111, -0.02589114569128, 0.00000000000000],
        [-3.71254944801331, -3.73605775833130, 0.00000000000000],
        [+3.71254944801331, +3.73605775833130, 0.00000000000000],
        [+0.73178529739380, +2.28237795829773, 0.00000000000000],
        [+5.89039325714111, +0.02589114569128, 0.00000000000000],
        [-2.74426102638245, +2.16115570068359, 0.00000000000000],
        [+2.74426102638245, -2.16115570068359, 0.00000000000000],
    ]),
    torch.tensor([
        [-0.55569743203406, +1.09030425468557, 0.00000000000000],
        [+0.51473634678469, +3.15152550263611, 0.00000000000000],
        [+0.59869690244446, -1.16861263789477, 0.00000000000000],
        [-0.45355203669134, -2.74568780438064, 0.00000000000000],
        [+2.52721209544999, -1.29200800956867, 0.00000000000000],
        [-2.63139587595376, +0.96447869452240, 0.00000000000000],
    ]),
))

# total charge of both system
charge = torch.tensor([0.0, 0.0])

# TPSSh-D4-ATM parameters
param = {
    "s6": positions.new_tensor(1.0),
    "s8": positions.new_tensor(1.85897750),
    "s9": positions.new_tensor(1.0),
    "a1": positions.new_tensor(0.44286966),
    "a2": positions.new_tensor(4.60230534),
}

# calculate dispersion energy in Hartree
energy = torch.sum(d4.dftd4(numbers, positions, charge, param), -1)
torch.set_printoptions(precision=10)
print(energy)
# tensor([-0.0088341432, -0.0027013607])
print(energy[0] - 2*energy[1])
# tensor(-0.0034314217)

The last example shows how to use the D4SModel.

import torch
import tad_dftd4 as d4
import tad_mctc as mctc

numbers = mctc.convert.symbol_to_number(symbols="C C C C N C S H H H H H".split())

# coordinates in Bohr
positions = torch.tensor(
    [
        [-2.56745685564671, -0.02509985979910, 0.00000000000000],
        [-1.39177582455797, +2.27696188880014, 0.00000000000000],
        [+1.27784995624894, +2.45107479759386, 0.00000000000000],
        [+2.62801937615793, +0.25927727028120, 0.00000000000000],
        [+1.41097033661123, -1.99890996077412, 0.00000000000000],
        [-1.17186102298849, -2.34220576284180, 0.00000000000000],
        [-2.39505990368378, -5.22635838332362, 0.00000000000000],
        [+2.41961980455457, -3.62158019253045, 0.00000000000000],
        [-2.51744374846065, +3.98181713686746, 0.00000000000000],
        [+2.24269048384775, +4.24389473203647, 0.00000000000000],
        [+4.66488984573956, +0.17907568006409, 0.00000000000000],
        [-4.60044244782237, -0.17794734637413, 0.00000000000000],
    ]
)

# total charge of the system
charge = torch.tensor(0.0)

# Create the D4S model
model = d4.model.D4SModel(numbers, **dd)

param = d4.get_params("tpssh")
energy = d4.dftd4(numbers, positions, charge, param, model=model)

torch.set_printoptions(precision=10)
print(energy)
# tensor([-0.0020843975, -0.0019013016, -0.0018165035, -0.0018363572,
#         -0.0021877293, -0.0019495023, -0.0022923108, -0.0004326892,
#         -0.0004439871, -0.0004362087, -0.0004454589, -0.0005344027])

Limitations

The current implementation only works molecular structures. Periodic boundary conditions are not implemented.

The code is fully vectorized for maximum efficiency. Therefore, all quantities are stored as full tensors, which makes calculations rather memory intensive. Especially, the ATM term can become limiting as it requires a 3D tensor of dimension (n_atoms, n_atoms, n_atoms).

Contributing

This is a volunteer open source projects and contributions are always welcome. Please, take a moment to read the contributing guidelines.

License

This project is licensed under the Apache License, Version 2.0 (the "License"); you may not use this project's files except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Metadata

Release files for tad-dftd4 0.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tad-dftd4 0.8.0
File Size Uploaded Provenance Actions
tad_dftd4-0.8.0.tar.gz 137.9 kB With provenance Details for tad_dftd4-0.8.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for tad-dftd4 0.8.0
File Interpreter ABI Platform Actions
tad_dftd4-0.8.0-py3-none-any.whl Python 3 none any Details for tad_dftd4-0.8.0-py3-none-any.whl

Total release size: 300.3 kB

Release files / tad_dftd4-0.8.0.tar.gz

Download URL tad_dftd4-0.8.0.tar.gz
Size 137.9 kB
Tags Source
SHA-256 checksum
How to use checksums
aa364038d4ffa396a5e01f906bc865e9c2a2c69ed2fab0c510c176af9912babc
BLAKE2b-256 checksum
How to use checksums
236a57e5e4a84c5c94ff5e766e7d25bd1d4ceacd5b6396633c98b961924a939e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 24, 2026.

Transparency log

Release files / tad_dftd4-0.8.0-py3-none-any.whl

Download URL tad_dftd4-0.8.0-py3-none-any.whl
Size 162.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c8170ec9431aa8f4d81704389822678448afedbdcc300f19d24d249254ea562e
BLAKE2b-256 checksum
How to use checksums
dab0fd65be9bb8c7364d2fada553fc29ab9ed27ac52bd5a95c3500f60ae89418
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 24, 2026.

Transparency log

Security for tad-dftd4 0.8.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for tad_dftd4-0.8.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page