Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix docs and consistency checks in calculator getters #168

Merged
merged 3 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,11 @@
<a href="https://github.com/grimme-lab/dxtb/actions/workflows/ubuntu.yaml">
<img src="https://github.com/grimme-lab/dxtb/actions/workflows/ubuntu.yaml/badge.svg" alt="Test Status Ubuntu"/>
</a>
<a href="https://github.com/grimme-lab/dxtb/actions/workflows/macos.yaml">
<img src="https://github.com/grimme-lab/dxtb/actions/workflows/macos.yaml/badge.svg" alt="Test Status macOS"/>
</a>
<a href="https://github.com/tgrimme-lab/dxtb/actions/workflows/macos-x86.yaml">
<img src="https://github.com/tgrimme-lab/dxtb/actions/workflows/macos-x86.yaml/badge.svg" alt="Test Status macOS (x86)"/>
<img src="https://github.com/grimme-lab/dxtb/actions/workflows/macos-x86.yaml/badge.svg" alt="Test Status macOS (x86)"/>
</a>
<a href="https://github.com/tgrimme-lab/dxtb/actions/workflows/macos-arm.yaml">
<img src="https://github.com/tgrimme-lab/dxtb/actions/workflows/macos-arm.yaml/badge.svg" alt="Test Status macOS (ARM)"/>
<img src="https://github.com/grimme-lab/dxtb/actions/workflows/macos-arm.yaml/badge.svg" alt="Test Status macOS (ARM)"/>
</a>
<a href="https://github.com/grimme-lab/dxtb/actions/workflows/windows.yaml">
<img src="https://github.com/grimme-lab/dxtb/actions/workflows/windows.yaml/badge.svg" alt="Test Status Windows"/>
Expand Down Expand Up @@ -124,6 +121,8 @@ forces = calc.get_forces(pos)
assert torch.equal(forces, -g)
```

All quantities are in atomic units.

For more examples and details, check out [the documentation](https://dxtb.readthedocs.io).

## Compatibility
Expand All @@ -142,13 +141,13 @@ For more examples and details, check out [the documentation](https://dxtb.readth
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.

**Restriction for macOS and Windows:**

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

**Restriction for macOS and Windows:**
The libcint interface is **not** available for macOS and Windows.
Correspondingly, the integral evaluation can be considerably slower.
Moreover, higher-order multipole integrals (dipole, quadrupole, ...) are not implemented.

While macOS support may be considered in the future, native Windows support is not possible, because the underlying [libcint](https://github.com/sunqm/libcint) library does not work under Windows.


Expand Down
2 changes: 2 additions & 0 deletions docs/source/01_quickstart/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Getting Started
The main object of *dxtb* is the :class:`~dxtb.Calculator` class, which is used
to perform calculations on a given system.

Note that all quantities are in atomic units.

Creating a Calculator
---------------------

Expand Down
6 changes: 4 additions & 2 deletions docs/source/01_quickstart/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ If you want to install the package without pip, start by cloning the repository.
DEST=/opt/software
git clone https://github.com/grimme-lab/dxtb $DEST/dxtb

Next, add <path to dxtb>/dxtb/src to your `$PYTHONPATH` environment variable.
For the command line interface, add <path to dxtb>/dxtb/bin to your `$PATH` environment variable.
Next, add ``<path to dxtb>/dxtb/src`` to your ``$PYTHONPATH`` environment variable.
For the command line interface, add ``<path to dxtb>/dxtb/bin`` to your ``$PATH`` environment variable.

.. code-block:: shell

Expand All @@ -97,9 +97,11 @@ The following dependencies are required
- `tad-multicharge <https://github.com/tad-mctc/tad-multicharge>`__
- `tad-dftd3 <https://github.com/dftd3/tad-dftd3>`__
- `tad-dftd4 <https://github.com/dftd4/tad-dftd4>`__
- `tad-libcint <https://github.com/tad-mctc/tad-libcint>`__
- `torch <https://pytorch.org/>`__

For tests, we also require

- `pytest <https://docs.pytest.org/>`__
- `pyscf <https://pyscf.org/>`__
- `tox <https://docs.pytest.org/>`__
4 changes: 2 additions & 2 deletions docs/source/03_for_developers/errors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ RuntimeError: clone is not supported by NestedIntSymNode
--------------------------------------------------------

This is a bug in PyTorch 2.3.0 and 2.3.1 (see
`PyTorch #128607 <<https://github.com/pytorch/pytorch/issues/128607>`__).
To avoid this error, manually import `torch._dynamo` in the code. For example:
`PyTorch #128607 <https://github.com/pytorch/pytorch/issues/128607>`__).
To avoid this error, manually import ``torch._dynamo`` in the code. For example:

.. code-block:: python

Expand Down
16 changes: 10 additions & 6 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,18 @@ If you use *dxtb* in your research, please cite the following paper:

.. code-block:: bibtex

@article{dxtb,
@article{dxtb.2024,
title = {dxtb -- An Efficient and Fully Differentiable Framework for Extended Tight-Binding},
author = {Friede, Marvin and Hölzer, Christian and Ehlert, Sebastian and Grimme, Stefan},
journal = {J. Chem. Phys.},
volume = {},
number = {},
pages = {},
author = {Friede, Marvin and H{\"o}lzer, Christian and Ehlert, Sebastian and Grimme, Stefan},
journal = {The Journal of Chemical Physics},
volume = {161},
number = {6},
pages = {062501},
year = {2024},
month = {08},
issn = {0021-9606},
doi = {10.1063/5.0216715},
url = {https://doi.org/10.1063/5.0216715},
}


Expand Down
File renamed without changes.
86 changes: 86 additions & 0 deletions examples/batch-2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# This file is part of dxtb.
#
# SPDX-Identifier: Apache-2.0
# Copyright (C) 2024 Grimme Group
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
"""
Obtaining the interaction energy of a dimer from a batched calculation.
"""
import tad_mctc as mctc
import torch

import dxtb

torch.set_printoptions(precision=10)


# 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],
],
dtype=torch.double,
),
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],
],
dtype=torch.double,
),
)
)

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


# instantiate calculator and calculate GFN1 energy in Hartree
calc = dxtb.calculators.GFN1Calculator(numbers, dtype=torch.double)
energy = calc.get_energy(positions, charge)


print(energy)
# tensor([-23.2835232516, -11.6302093800], dtype=torch.float64)

e = energy[0] - 2 * energy[1]
# tensor(-0.0231044917, dtype=torch.float64)

print(e * mctc.units.AU2KCALMOL)
# tensor(-14.4982874136, dtype=torch.float64)
36 changes: 35 additions & 1 deletion src/dxtb/_src/calculators/types/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class and implement the :meth:`calculate` method and the corresponding methods
from abc import abstractmethod

import torch
from tad_mctc.exceptions import DtypeError
from tad_mctc.exceptions import DeviceError, DtypeError

from dxtb import IndexHelper, OutputHandler
from dxtb import integrals as ints
Expand Down Expand Up @@ -730,6 +730,40 @@ def get_property(
if allow_calculation is False and name not in self.cache:
return None

# Before calculating, let's do some device and dtype checks.
if self.device != positions.device:
raise DeviceError(
f"Device mismatch: Calculator is on '{self.device}', but "
f"positions are on '{positions.device}'."
)
if self.dtype != positions.dtype:
raise DtypeError(
f"Dtype mismatch: Calculator is of type '{self.dtype}', but "
f"positions are of type '{positions.dtype}'."
)
if isinstance(chrg, Tensor):
if self.dtype != chrg.dtype:
raise DtypeError(
f"Dtype mismatch: Calculator is of type '{self.dtype}', "
f"but charge is of type '{chrg.dtype}'."
)
if self.device != chrg.device:
raise DeviceError(
f"Device mismatch: Calculator is on '{self.device}', but "
f"charge is on '{chrg.device}'."
)
if isinstance(spin, Tensor):
if self.dtype != spin.dtype:
raise DtypeError(
f"Dtype mismatch: Calculator is of type '{self.dtype}', "
f"but spin is of type '{spin.dtype}'."
)
if self.device != spin.device:
raise DeviceError(
f"Device mismatch: Calculator is on '{self.device}', but "
f"spin is on '{spin.device}'."
)

# All the cache checks are handled deep within `calculate`. No need to
# do it here as well.
self.calculate([name], positions, chrg=chrg, spin=spin, **kwargs)
Expand Down
80 changes: 80 additions & 0 deletions test/test_calculator/test_dd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# This file is part of dxtb.
#
# SPDX-Identifier: Apache-2.0
# Copyright (C) 2024 Grimme Group
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
"""
Test Calculator dtype and device consistency.
"""

from __future__ import annotations

import pytest
import torch
from tad_mctc.exceptions import DeviceError, DtypeError

from dxtb import GFN1_XTB as par
from dxtb import Calculator
from dxtb._src.typing import MockTensor, Tensor


def test_fail_dtype() -> None:
numbers = torch.tensor([3, 1])
positions = torch.tensor([[0.0, 0.0, 0.0], [0.0, 0.0, 1.0]])
charge = torch.tensor(0.0)
spin = torch.tensor(0.0)

calc = Calculator(numbers, par, opts={"verbosity": 0})

# same dtype works
e = calc.get_energy(positions, charge, spin)
assert isinstance(e, Tensor)

with pytest.raises(DtypeError):
calc.get_energy(positions.type(torch.double), charge, spin)

with pytest.raises(DtypeError):
calc.get_energy(positions, charge.type(torch.double), spin)

with pytest.raises(DtypeError):
calc.get_energy(positions, charge, spin.type(torch.double))


def test_fail_device() -> None:
numbers = torch.tensor([3, 1])

_positions = torch.tensor([[0.0, 0.0, 0.0], [0.0, 0.0, 1.0]])
_charge = torch.tensor(0.0)
_spin = torch.tensor(0.0)

calc = Calculator(numbers, par, opts={"verbosity": 0}, dtype=torch.float)

# same device works
e = calc.get_energy(_positions, _charge, _spin)
assert isinstance(e, Tensor)

with pytest.raises(DeviceError):
positions = MockTensor(_positions)
positions.device = torch.device("cuda")
calc.get_energy(positions, _charge, _spin)

with pytest.raises(DeviceError):
charge = MockTensor(_charge)
charge.device = torch.device("cuda")
calc.get_energy(_positions, charge, _spin)

with pytest.raises(DeviceError):
spin = MockTensor(_spin)
spin.device = torch.device("cuda")
calc.get_energy(_positions, _charge, spin)
2 changes: 1 addition & 1 deletion test/test_calculator/test_general.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def test_fail() -> None:
numbers = torch.tensor([6, 1, 1, 1, 1], dtype=torch.double)

with pytest.raises(DtypeError):
Calculator(numbers, par, opts={"vebosity": 0})
Calculator(numbers, par, opts={"verbosity": 0})

# because of the exception, the timer for the setup is never stopped
timer.reset()
Expand Down
Loading