Skip to content

Commit

Permalink
More comprehensive primitive generation (#314)
Browse files Browse the repository at this point in the history
* initial commit

* second commit

* second commit

* simplify code

* linear angle

* linear angle

* test update, more fixes needed

* unifinished update

* linear angle update

* unfinished update

* unfinished update

* unifinished update

* unfinished update

* better linear angles

* better linear angles

* minor change

* fix linear bend code

* fix some tests

* add tests

* fix failing test

* add tests

* minor dihedral fix

* dihedral code fix

* add test for linear bend with ref

* add test for linear bend with ref

* add tests

* make bond angle consistent

* add tests and fix value bug

* add tests

* fix test

* change backup hessian update scheme for crfo

* revert change to hessian update scheme

* correction to angle code

* assert only for graph

* fix tests

* pr suggestions 1

* pr suggestions 2 partial

* test fix

* put methods into anypic class

* pr update 3

* pr update 4

* pr update 5

* pr update 6

* pr update 7

* pr update 8

* pr update

* pr update, changelog update
  • Loading branch information
shoubhikraj authored Jan 4, 2024
1 parent 3199ba5 commit 05b2d98
Show file tree
Hide file tree
Showing 14 changed files with 910 additions and 184 deletions.
5 changes: 3 additions & 2 deletions autode/atoms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1041,9 +1041,10 @@ def angle(self, i: int, j: int, k: int) -> Angle:
f"least one zero vector"
)

value = np.arccos(np.dot(vec1, vec2) / norms)
# Cos(theta) must lie within [-1, 1]
cos_value = np.clip(np.dot(vec1, vec2) / norms, a_min=-1, a_max=1)

return Angle(value)
return Angle(np.arccos(cos_value))

def dihedral(self, w: int, x: int, y: int, z: int) -> Angle:
r"""
Expand Down
9 changes: 9 additions & 0 deletions autode/mol_graphs.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ def node_matcher(self):

return matcher

@property
def is_connected(self) -> bool:
"""Is this graph fully connected (i.e. not separate parts)"""
return nx.is_connected(self)

def connected_components(self):
"""Generate the separate connected components"""
return nx.connected_components(self)


def make_graph(
species: "Species",
Expand Down
2 changes: 1 addition & 1 deletion autode/opt/coordinates/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from autode.opt.coordinates.base import OptCoordinates, CartesianComponent
from autode.opt.coordinates.base import OptCoordinates
from autode.opt.coordinates.cartesian import CartesianCoordinates
from autode.opt.coordinates.dic import DIC, DICWithConstraints
31 changes: 24 additions & 7 deletions autode/opt/coordinates/_autodiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,9 @@ class DifferentiableVector3D:
hyper-dual numbers
"""

def __init__(self, items: Sequence["VectorHyperDual"]):
def __init__(
self, items: Sequence[Union["VectorHyperDual", numeric_type]]
):
"""
Initialise the 3D vector from a list of 3 hyperdual numbers
Expand All @@ -590,7 +592,9 @@ def __init__(self, items: Sequence["VectorHyperDual"]):
items = list(items)
if len(items) != 3:
raise ValueError("A 3D vector must have only 3 components")
assert all(isinstance(item, VectorHyperDual) for item in items)
assert all(
isinstance(item, (VectorHyperDual, *numeric)) for item in items
)
self._data = items

@staticmethod
Expand All @@ -600,7 +604,9 @@ def _check_same_type(other) -> None:
raise ValueError("Operation must be done with another 3D vector!")
return None

def dot(self, other: "DifferentiableVector3D") -> "VectorHyperDual":
def dot(
self, other: "DifferentiableVector3D"
) -> Union["VectorHyperDual", numeric_type]:
"""
Dot product of two 3D vectors
Expand All @@ -611,13 +617,12 @@ def dot(self, other: "DifferentiableVector3D") -> "VectorHyperDual":
(VectorHyperDual): A scalar number (with derivatives)
"""
self._check_same_type(other)
dot = 0
dot: Union[VectorHyperDual, numeric_type] = 0
for k in range(3):
dot = dot + self._data[k] * other._data[k]
assert isinstance(dot, VectorHyperDual)
return dot

def norm(self) -> "VectorHyperDual":
def norm(self) -> Union["VectorHyperDual", numeric_type]:
"""
Euclidean (l2) norm of this 3D vector
Expand All @@ -627,7 +632,6 @@ def norm(self) -> "VectorHyperDual":
norm = DifferentiableMath.sqrt(
self._data[0] ** 2 + self._data[1] ** 2 + self._data[2] ** 2
)
assert isinstance(norm, VectorHyperDual)
return norm

def __add__(
Expand Down Expand Up @@ -690,6 +694,18 @@ def __rmul__(self, other):
"""Multiplication of scalar and vector is commutative"""
return self.__mul__(other)

def __truediv__(self, other: Union[VectorHyperDual, numeric_type]):
"""
Division of a 3D vector with a scalar
Args:
other (VectorHyperDual|float|int):
Returns:
(DifferentiableVector3D):
"""
return self.__mul__(1 / other)

def cross(
self, other: "DifferentiableVector3D"
) -> "DifferentiableVector3D":
Expand All @@ -702,6 +718,7 @@ def cross(
Returns:
(DifferentiableVector3D):
"""
self._check_same_type(other)
return DifferentiableVector3D(
[
self._data[1] * other._data[2]
Expand Down
10 changes: 0 additions & 10 deletions autode/opt/coordinates/base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# mypy: disable-error-code="has-type"
import numpy as np
from copy import deepcopy
from enum import IntEnum, unique
from typing import Optional, Union, Sequence, List, TYPE_CHECKING
from abc import ABC, abstractmethod

Expand All @@ -15,15 +14,6 @@
from autode.hessians import Hessian


@unique
class CartesianComponent(IntEnum):
"""Cartesian component in 3D space"""

x = 0
y = 1
z = 2


class OptCoordinates(ValueArray, ABC):
"""Coordinates used to perform optimisations"""

Expand Down
Loading

0 comments on commit 05b2d98

Please sign in to comment.