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

[pull] main from grimme-lab:main #10

Merged
merged 2 commits into from
Feb 16, 2025
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
95 changes: 82 additions & 13 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,52 @@ on:
push:
branches:
- main
- master
tags:
- "v*"
paths-ignore:
- "doc*/**"
- "./*.ya?ml"
- "**/*.md"
- "**/*.rst"

pull_request:
branches:
- main
paths-ignore:
- "doc*/**"
- "./*.ya?ml"
- "**/*.md"
- "**/*.rst"

workflow_dispatch:

jobs:
sdist:
permissions:
contents: read

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Build source distribution (sdist)
run: pipx run build --sdist

- name: Upload source distribution as artifact
uses: actions/upload-artifact@v4
with:
name: ${{ github.event.repository.name }}-sdist
path: dist

wheel:
permissions:
contents: read

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -44,38 +78,68 @@ jobs:
- name: Upload wheel as artifact
uses: actions/upload-artifact@v4
with:
name: dxtb-wheel
path: dist/*.whl
name: ${{ github.event.repository.name }}-wheel
path: dist

install_wheel:
needs: [wheel]

permissions:
contents: read

sdist:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Build source distribution (sdist)
run: pipx run build --sdist

- name: Upload source distribution as artifact
uses: actions/upload-artifact@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: dxtb-sdist
path: dist/*.tar.gz
path: dist
merge-multiple: true

- name: Show downloaded artifacts
run: ls -lcahFR --color=auto dist

- name: Install wheel
run: |
pip install torch --index-url https://download.pytorch.org/whl/cpu
pip install dist/*.whl

- name: Determine package name
run: |
name=$(echo "${REPO_NAME}" | tr '-' '_')
echo "PKG_NAME=$name" >> "$GITHUB_ENV"
echo "PKG_NAME is set to '${name}'."
env:
REPO_NAME: ${{ github.event.repository.name }}

- name: Test import
run: python -c "import ${PKG_NAME}; print(${PKG_NAME}.__version__)"
env:
PKG_NAME: ${{ env.PKG_NAME }}

upload_test_pypi:
needs: [sdist, wheel]

runs-on: ubuntu-latest

environment: release

permissions:
contents: read
id-token: write

if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
steps:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true

- name: Publish to Test PyPI
uses: pypa/gh-action-pypi-publish@release/v1
Expand All @@ -84,17 +148,22 @@ jobs:

upload_pypi:
needs: [sdist, wheel, upload_test_pypi]

runs-on: ubuntu-latest

environment: release

permissions:
contents: read
id-token: write

if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
steps:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: artifact
path: dist
merge-multiple: true

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
5 changes: 3 additions & 2 deletions docs/source/01_quickstart/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ use corresponding getters :meth:`~dxtb.Calculator.get_energy`:

energy = calc.get_energy(positions, charge=0, spin=0)

We recommend using the getters, as they provide the familiar ASE-like interface.
We recommend using the getters, as they provide the familiar
`ASE <https://wiki.fysik.dtu.dk/ase/>`_-like interface.


Gradients
Expand Down Expand Up @@ -195,4 +196,4 @@ counterpart, e.g., :meth:`~dxtb.Calculator.forces_numerical`.
Hence, a subsequent :meth:`~dxtb.Calculator.get_forces` does not
necessitate an additional calculation.

For more details, please see the :ref:`here <indepth_calculators>`.
For more details, please see :ref:`here <indepth_calculators>`.
2 changes: 1 addition & 1 deletion docs/source/05_about/literature.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This is a list of literature that is relevant to the project.
Main Reference
--------------

- M. Friede, C. Hölzer, S. Ehlert, S. Grimme, *J. Chem. Phys.*, **2024**, 161, 062501. ([DOI](https://doi.org/10.1063/5.0216715))
- M. Friede, C. Hölzer, S. Ehlert, S. Grimme, *J. Chem. Phys.*, **2024**, 161, 062501. (`DOI: 10.1063/5.0216715 <https://doi.org/10.1063/5.0216715>`__)

.. code-block:: bibtex

Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ With *dxtb*, we provide a re-implementation of the xTB methods in PyTorch, which

If you use *dxtb* in your research, please cite the following paper:

- M. Friede, C. Hölzer, S. Ehlert, S. Grimme, *dxtb -- An Efficient and Fully Differentiable Framework for Extended Tight-Binding*, *J. Chem. Phys.*, **2024**
- M. Friede, C. Hölzer, S. Ehlert, S. Grimme, *dxtb -- An Efficient and Fully Differentiable Framework for Extended Tight-Binding*, *J. Chem. Phys.*, **2024**, 161, 062501. (`DOI: 10.1063/5.0216715 <https://doi.org/10.1063/5.0216715>`__)

.. admonition:: BibTeX
:class: toggle
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ install_requires =
pydantic>=2.0.0
scipy
tad-dftd3>=0.3.0
tad-dftd4>=0.5.1
tad-dftd4>=0.5.2
tad-mctc>=0.3.2
tad-multicharge
tomli
Expand Down
17 changes: 11 additions & 6 deletions src/dxtb/_src/calculators/types/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,6 @@ def __init__(
opts = dict(opts)
OutputHandler.verbosity = opts.pop("verbosity", 1)

OutputHandler.write_stdout("", v=5)
OutputHandler.write_stdout("", v=5)
OutputHandler.write_stdout("===========", v=4)
OutputHandler.write_stdout("CALCULATION", v=4)
OutputHandler.write_stdout("===========", v=4)
Expand All @@ -523,15 +521,22 @@ def __init__(

# Set integral level based on parametrization. For the tests, we want
# to turn this off. Otherwise, all GFN2-xTB tests will fail without
# `libcint`, even when integrals are not tested (e.g. D4SC). This is
# caused by the integral factories in this very constructor.
# `libcint`, even when integrals are not tested (e.g. D4SC). This
# cannot be avoided becaused this constructor always calls the
# integral factories later.
# If the user sets the level manually, we will still set it to the
# maximum level required for the respective parametrization.
if kwargs.pop("auto_int_level", True):
if par.meta is not None:
if par.meta.name is not None:
if "gfn1" in par.meta.name.casefold():
self.opts.ints.level = labels.INTLEVEL_HCORE
self.opts.ints.level = max(
labels.INTLEVEL_HCORE, self.opts.ints.level
)
elif "gfn2" in par.meta.name.casefold():
self.opts.ints.level = labels.INTLEVEL_QUADRUPOLE
self.opts.ints.level = max(
labels.INTLEVEL_QUADRUPOLE, self.opts.ints.level
)

# create cache
self.cache = CalculatorCache(**dd) if cache is None else cache
Expand Down
19 changes: 14 additions & 5 deletions src/dxtb/_src/calculators/types/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,13 @@ def wrapper(
) -> Tensor:
if efield.LABEL_EFIELD not in self.interactions.labels:
raise RuntimeError(
f"{func.__name__} requires an electric field. Add the "
f"'{efield.LABEL_EFIELD}' interaction to the Calculator."
f"'{func.__name__}' requires an electric field."
f"\nAdd the '{efield.LABEL_EFIELD}' interaction to the "
"Calculator.\n\nExample:\n"
"field = torch.tensor([0.0, 0.0, 0.0], **dd)\n"
"ef = dxtb.components.field.new_efield(field, **dd)\n"
"calc = dxtb.calculators.GFN1Calculator(numbers, "
"interaction=ef, **dd)"
)
return func(self, positions, chrg, spin, *args, **kwargs)

Expand Down Expand Up @@ -134,9 +139,13 @@ def wrapper(
) -> Tensor:
if efieldgrad.LABEL_EFIELD_GRAD not in self.interactions.labels:
raise RuntimeError(
f"{func.__name__} requires an electric field. Add the "
f"'{efieldgrad.LABEL_EFIELD_GRAD}' interaction to the "
"Calculator."
f"'{func.__name__}' requires an electric field gradient."
f"\nAdd the '{efieldgrad.LABEL_EFIELD_GRAD}' interaction to "
"the Calculator.\n\nExample:\n"
"field_grad = torch.zeros((3, 3), **dd)\n"
"efg = dxtb.components.field.new_efield_grad(field_grad, **dd)"
"\ncalc = dxtb.calculators.GFN1Calculator(numbers, "
"interaction=efg, **dd)"
)
return func(self, positions, chrg, spin, *args, **kwargs)

Expand Down
1 change: 1 addition & 0 deletions src/dxtb/_src/calculators/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def shape_checks_chrg(
f"{name.title()} tensor has only one element. Please use a "
"scalar for single structures (e.g., `torch.tensor(1.0)`) and "
"a 1D tensor for batched calculations (e.g., "
"`torch.tensor([1.0, 0.0])`)."
)

if ndims != t.ndim + 1:
Expand Down
3 changes: 2 additions & 1 deletion src/dxtb/_src/cli/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ def singlepoint(self) -> Result | Tensor:

# setup config and write to output
config = Config.from_args(args)
io.OutputHandler.write(config.info())
io.OutputHandler.write(config.info(), v=5)
io.OutputHandler.write_stdout("", v=5)

# Broyden is not supported in full SCF mode
if (
Expand Down
9 changes: 5 additions & 4 deletions src/dxtb/_src/components/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def update(self, **kwargs: Any) -> None:
.. code-block:: python

import torch
from dxtb._src.components.interactions.field import ElectricField
from dxtb.components.field import ElectricField

ef = ElectricField(field=torch.tensor([0.0, 0.0, 0.0]))
ef.update(field=torch.tensor([1.0, 0.0, 0.0]))
Expand All @@ -152,8 +152,9 @@ def update(self, **kwargs: Any) -> None:

def reset(self) -> None:
"""
Reset the tensor attributes of the `Component` instance to their
original states or to specified values.
Reset the tensor attributes of the
:class:`dxtb.components.base.Component` instance to their original
states or to specified values.

This method iterates through the attributes defined in ``__slots__`` and
resets any tensor attributes to a detached clone of their original
Expand All @@ -165,7 +166,7 @@ def reset(self) -> None:
.. code-block:: python

import torch
from dxtb._src.components.interactions.external.field import ElectricField
from dxtb.components.base.field import ElectricField

ef = ElectricField(field=torch.tensor([0.0, 0.0, 0.0]))
ef.reset()
Expand Down
6 changes: 3 additions & 3 deletions src/dxtb/_src/components/classicals/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
This module contains the abstract base class for all classical (i.e., non-
selfconsistent or non-density-dependent) energy terms.

Every contribution contains a class:`dxtb.components.ComponentCache` that holds
position-independent variables. Therefore, the positions must always be
supplied to the ``get_energy`` (or ``get_grad``) method.
Every contribution contains a :class:`dxtb.components.base.ComponentCache` that
holds position-independent variables. Therefore, the positions must always be
supplied to the :meth:`get_energy` (or :meth:`get_grad``) method.
"""

from __future__ import annotations
Expand Down
14 changes: 12 additions & 2 deletions src/dxtb/_src/components/classicals/dispersion/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import torch

from dxtb import IndexHelper
from dxtb._src.typing import Any, Tensor
from dxtb._src.typing import Any, Literal, Tensor

from ...classicals import Classical, ClassicalCache

Expand All @@ -49,20 +49,30 @@ class Dispersion(Classical):
charge: Tensor | None
"""Total charge of the system."""

__slots__ = ["numbers", "param", "charge"]
ref_charges: Literal["eeq", "gfn2"]
"""
Reference charges for the dispersion model.
This is only required for charge-dependent models.

:default: ``"eeq"``
"""

__slots__ = ["numbers", "param", "charge", "ref_charges"]

def __init__(
self,
numbers: Tensor,
param: dict[str, Tensor],
charge: Tensor | None = None,
ref_charges: Literal["eeq", "gfn2"] = "eeq",
device: torch.device | None = None,
dtype: torch.dtype | None = None,
) -> None:
super().__init__(device, dtype)
self.numbers = numbers
self.param = param
self.charge = charge
self.ref_charges = ref_charges

@abstractmethod
def get_cache(
Expand Down
5 changes: 4 additions & 1 deletion src/dxtb/_src/components/classicals/dispersion/d3.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ def __init__(


class DispersionD3(Dispersion):
"""Representation of the DFT-D3(BJ) dispersion correction."""
"""
Representation of the DFT-D3(BJ) dispersion correction
(:class:`.DispersionD3`).
"""

@override
def get_cache(
Expand Down
Loading