Skip to content

Commit

Permalink
GFN2 Core Hamiltonian (grimme-lab#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
marvinfriede authored Jan 3, 2025
1 parent 38ad6fa commit 31b58a7
Show file tree
Hide file tree
Showing 26 changed files with 894 additions and 308 deletions.
3 changes: 2 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ repos:
hooks:
- id: isort
name: isort (python)
args: ["--profile", "black", "--filter-files"]
args: ["--profile", "black", "--line-length", "80", "--filter-files"]

- repo: https://github.com/psf/black
rev: 24.10.0
hooks:
- id: black
args: ["--line-length", "80"]
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ install_requires =
scipy
tad-dftd3>=0.3.0
tad-dftd4>=0.2.0
tad-mctc>=0.2.0
tad-mctc>=0.3.0
tad-multicharge
tomli
tomli-w
Expand Down
2 changes: 1 addition & 1 deletion src/dxtb/_src/basis/slater.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def slater_to_gauss(
# <φ|φ> = (2i-1)!!(2j-1)!!(2k-1)!!/(4α)^(i+j+k) · sqrt(π/2α)³
# N² = (4α)^(i+j+k)/((2i-1)!!(2j-1)!!(2k-1)!!) · sqrt(2α/π)³
# N = (4α)^((i+j+k)/2) / sqrt((2i-1)!!(2j-1)!!(2k-1)!!) · (2α/π)^(3/4)
if norm:
if norm is True:
coeff = coeff * (
(top * alpha) ** 0.75
* torch.sqrt(4 * alpha) ** l
Expand Down
1 change: 1 addition & 0 deletions src/dxtb/_src/calculators/gfn1.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def __init__(
# pylint: disable=import-outside-toplevel
from dxtb import GFN1_XTB

# constructor can be found in src/dxtb/_src/calculators/types/base.py
super().__init__(
numbers,
GFN1_XTB,
Expand Down
3 changes: 1 addition & 2 deletions src/dxtb/_src/calculators/gfn2.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def __init__(
# pylint: disable=import-outside-toplevel
from dxtb import GFN2_XTB

# constructor can be found in src/dxtb/_src/calculators/types/base.py
super().__init__(
numbers,
GFN2_XTB,
Expand All @@ -66,5 +67,3 @@ def __init__(
device=device,
dtype=dtype,
)

raise NotImplementedError("GFN2-xTB is not yet implemented.")
10 changes: 2 additions & 8 deletions src/dxtb/_src/components/classicals/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,16 +157,10 @@ def get_gradient(
###########################################################################

@overload
def get_interaction(
self,
name: Literal["Halogen"],
) -> Halogen: ...
def get_interaction(self, name: Literal["Halogen"]) -> Halogen: ...

@overload
def get_interaction(
self,
name: Literal["Repulsion"],
) -> Repulsion: ...
def get_interaction(self, name: Literal["Repulsion"]) -> Repulsion: ...

@override # generic implementation for typing
def get_interaction(self, name: str) -> Classical:
Expand Down
4 changes: 3 additions & 1 deletion src/dxtb/_src/components/classicals/repulsion/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ def new_repulsion(
"""

if hasattr(par, "repulsion") is False or par.repulsion is None:
# TODO: Repulsion is used in all models, so error or just warning?
# Although repulsion is used in all models, we do not want to exit
# for custom models that are loaded from a parameter file. Hence, we
# only issue a warning here, not an error.
warnings.warn("No repulsion scheme found.", ParameterWarning)
return None

Expand Down
8 changes: 4 additions & 4 deletions src/dxtb/_src/components/interactions/coulomb/thirdorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,9 @@ def get_cache(
Note
----
If the :class:`.ES3` interaction is evaluated within the
:class:`dxtb.components.InteractionList`, ``positions`` will be passed
as an argument, too. Hence, it is necessary in signature
of the function to absorb it (also see
:class:`dxtb.components.InteractionList`, ``positions`` will be
passed as an argument, too. Hence, it is necessary to absorb
the ``positions`` in the signature of the function (also see
:meth:`dxtb.components.Interaction.get_cache`).
"""
if numbers is None:
Expand Down Expand Up @@ -297,7 +297,7 @@ def new_es3(
if device is not None:
if device != numbers.device:
raise DeviceError(
f"Passed device ({device}) and device of electric field "
f"Passed device ({device}) and device of `numbers` tensor "
f"({numbers.device}) do not match."
)

Expand Down
9 changes: 5 additions & 4 deletions src/dxtb/_src/components/interactions/solvation/alpb.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,11 @@ def get_cache(
Note
----
If the :class:`.GeneralizedBorn` interaction is evaluated within the
:class:`dxtb.components.InteractionList`, the :class:`dxtb.IndexHelper`
will be passed as an argument, too. Hence, it is necessary in signature
of the function to absorb it.
If the :class:`.GeneralizedBorn` interaction is evaluated
within the :class:`dxtb.components.InteractionList`, the
:class:`dxtb.IndexHelper` will be passed as an argument, too. Hence,
it is necessary to absorb the ``positions`` in the signature of the
function.
"""
if numbers is None:
raise ValueError("Atomic numbers are required for cache.")
Expand Down
14 changes: 9 additions & 5 deletions src/dxtb/_src/components/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ def restore(self) -> None:
"""
pass

def __str__(self) -> str:
def __str__(self) -> str: # pragma: no cover
return f"{self.__class__.__name__}({list(self.keys())})"

def __repr__(self) -> str:
def __repr__(self) -> str: # pragma: no cover
return str(self)


Expand Down Expand Up @@ -238,7 +238,8 @@ def reset_all(self) -> None:

@property
def labels(self) -> list[str]:
return [component.label for component in self.components]
"""Alphabetically sorted list of all components labels."""
return sorted([component.label for component in self.components])

def get_interaction(self, name: str) -> C:
"""
Expand All @@ -265,10 +266,13 @@ def get_interaction(self, name: str) -> C:

raise ValueError(f"The component named '{name}' is not in the list.")

def __str__(self) -> str:
def __len__(self) -> int:
return len(self.components)

def __str__(self) -> str: # pragma: no cover
return f"{self.__class__.__name__}({self.labels})"

def __repr__(self) -> str:
def __repr__(self) -> str: # pragma: no cover
return str(self)

@override
Expand Down
17 changes: 17 additions & 0 deletions src/dxtb/_src/integral/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,23 @@ def reset_all(self) -> None:
if isinstance(i, BaseIntegral) or isinstance(i, BaseHamiltonian):
i.clear()

@property
def labels(self) -> list[str]:
"""Return all initialized integrals by label."""
return [
slot[1:]
for slot in self.__slots__
if slot.startswith("_") and getattr(self, slot) is not None
]

def __len__(self) -> int:
"""Print all initialized integrals."""
return sum(
1
for slot in self.__slots__
if slot.startswith("_") and getattr(self, slot) is not None
)

# pretty print

def __str__(self) -> str:
Expand Down
22 changes: 22 additions & 0 deletions src/dxtb/_src/xtb/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,28 @@ class HamiltonianABC(ABC):
Abstract base class for Hamiltonians.
"""

@abstractmethod
def _get_hscale(self) -> Tensor:
"""
Obtain the off-site scaling factor for the Hamiltonian.
Returns
-------
Tensor
Off-site scaling factor for the Hamiltonian.
"""

@abstractmethod
def _get_elem_valence(self) -> Tensor:
"""
Obtain a mask for valence and non-valence shells. This is only required for GFN1-xTB's second hydrogen s-function.
Returns
-------
Tensor
Mask indicating valence shells for each unique species.
"""

@abstractmethod
def build(self, positions: Tensor, overlap: Tensor | None = None) -> Tensor:
"""
Expand Down
Loading

0 comments on commit 31b58a7

Please sign in to comment.