Molecule: Bonds#

Module for estimating or guessing bond orders between atoms. This module uses a geometric model to obtain the optimal bond distance between a pair of atoms, which is compared with the actual distance between the atoms to obtain the liklihood of the bond being present.

Based on S. Spicher and S. Grimme, Angew. Chem. Int. Ed., 2020, 59, 15665–15673 (DOI).

Example

>>> import torch
>>> from tad_mctc.molecule.bond import guess_bond_order
>>> numbers = torch.tensor([7, 7, 1, 1, 1, 1, 1, 1])
>>> positions = torch.tensor([
...     [-2.98334550857544, -0.08808205276728, +0.00000000000000],
...     [+2.98334550857544, +0.08808205276728, +0.00000000000000],
...     [-4.07920360565186, +0.25775116682053, +1.52985656261444],
...     [-1.60526800155640, +1.24380481243134, +0.00000000000000],
...     [-4.07920360565186, +0.25775116682053, -1.52985656261444],
...     [+4.07920360565186, -0.25775116682053, -1.52985656261444],
...     [+1.60526800155640, -1.24380481243134, +0.00000000000000],
...     [+4.07920360565186, -0.25775116682053, +1.52985656261444],
... ])
>>> cn = torch.tensor([3.0, 3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
>>> bond_order = guess_bond_order(numbers, positions, cn)
>>> print(bond_order)
tensor([[0.0000, 0.0000, 0.4403, 0.4334, 0.4403, 0.0000, 0.0000, 0.0000],
        [0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.4403, 0.4334, 0.4403],
        [0.4403, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
        [0.4334, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
        [0.4403, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
        [0.0000, 0.4403, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
        [0.0000, 0.4334, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
        [0.0000, 0.4403, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000]])
>>> print(bond_order > 0.3)
tensor([[False, False,  True,  True,  True, False, False, False],
        [False, False, False, False, False,  True,  True,  True],
        [ True, False, False, False, False, False, False, False],
        [ True, False, False, False, False, False, False, False],
        [ True, False, False, False, False, False, False, False],
        [False,  True, False, False, False, False, False, False],
        [False,  True, False, False, False, False, False, False],
        [False,  True, False, False, False, False, False, False]])
tad_mctc.molecule.bond.guess_bond_length(numbers, cn)[source]#

Estimate equilibrium bond lengths using a geometric model.

Parameters:
  • numbers (Tensor) – Atomic numbers for all atoms in the system.

  • cn (Tensor) – Coordination numbers for all atoms in the system.

Returns:

Estimated bond lengths for all atom pairs

Return type:

Tensor

Example

>>> import torch
>>> from tad_mctc.molecule.bond import guess_bond_length
>>> numbers = torch.tensor([6, 8, 7, 1, 1, 1])
>>> cn = torch.tensor([3.0059586, 1.0318390, 3.0268824, 1.0061584, 1.0036336, 0.9989871])
>>> print(guess_bond_length(numbers, cn))
tensor([[2.5983, 2.2588, 2.5871, 1.9833, 1.9828, 1.9820],
        [2.2588, 2.1631, 2.2855, 1.5542, 1.5538, 1.5531],
        [2.5871, 2.2855, 2.5589, 1.8902, 1.8897, 1.8890],
        [1.9833, 1.5542, 1.8902, 1.4750, 1.4746, 1.4737],
        [1.9828, 1.5538, 1.8897, 1.4746, 1.4741, 1.4733],
        [1.9820, 1.5531, 1.8890, 1.4737, 1.4733, 1.4724]])
tad_mctc.molecule.bond.guess_bond_order(numbers, positions, cn, counting_function=<function erf_count>, **kwargs)[source]#

Try to guess whether an atom pair is bonded using a geometric criterium. This measure is based on model taking into account the coordination number of each atom as well as the polarity of the bond.

Parameters:
  • numbers (Tensor) – Atomic numbers for all atoms in the system of shape (..., nat).

  • positions (Tensor) – Cartesian coordinates of all atoms (shape: (..., nat, 3)).

  • cn (Tensor) – Coordination numbers for all atoms (shape: (..., nat)).

  • counting_function (CountingFunction) – Function to determine whether two atoms are bonded, additional arguments are passed to the counting function.

  • kcn (float, optional) – Steepness of the counting function.

Returns:

Bond order for all atom pairs.

Return type:

Tensor

Example

>>> import torch
>>> from tad_mctc.molecule.bond import guess_bond_order
>>> from tad_mctc.batch import pack
>>> numbers = pack((
...     torch.tensor([7, 1, 1, 1]),
...     torch.tensor([6, 8, 8, 1, 1]),
... ))
>>> positions = pack((
...     torch.tensor([
...         [+0.00000000000000, +0.00000000000000, -0.54524837997150],
...         [-0.88451840382282, +1.53203081565085, +0.18174945999050],
...         [-0.88451840382282, -1.53203081565085, +0.18174945999050],
...         [+1.76903680764564, +0.00000000000000, +0.18174945999050],
...     ]),
...     torch.tensor([
...         [-0.53424386915034, -0.55717948166537, +0.00000000000000],
...         [+0.21336223456096, +1.81136801357186, +0.00000000000000],
...         [+0.82345103924195, -2.42214694643037, +0.00000000000000],
...         [-2.59516465056138, -0.70672678063558, +0.00000000000000],
...         [+2.09259524590881, +1.87468519515944, +0.00000000000000],
...     ]),
... ))
>>> cn = torch.tensor([
...     [2.9901006, 0.9977214, 0.9977214, 0.9977214, 0.0000000],
...     [3.0093639, 2.0046251, 1.0187057, 0.9978270, 1.0069743],
... ])
>>> bond_order = guess_bond_order(numbers, positions, cn)
>>> print(bond_order[0, ...])
tensor([[0.0000, 0.4392, 0.4392, 0.4392, 0.0000],
        [0.4392, 0.0000, 0.0000, 0.0000, 0.0000],
        [0.4392, 0.0000, 0.0000, 0.0000, 0.0000],
        [0.4392, 0.0000, 0.0000, 0.0000, 0.0000],
        [0.0000, 0.0000, 0.0000, 0.0000, 0.0000]])
>>> print(bond_order[1, ...])
tensor([[0.0000, 0.5935, 0.4043, 0.3262, 0.0000],
        [0.5935, 0.0000, 0.0000, 0.0000, 0.3347],
        [0.4043, 0.0000, 0.0000, 0.0000, 0.0000],
        [0.3262, 0.0000, 0.0000, 0.0000, 0.0000],
        [0.0000, 0.3347, 0.0000, 0.0000, 0.0000]])