Source code for pysisyphus.intcoords.LinearDisplacement

import numpy as np

from pysisyphus.intcoords.Primitive import Primitive
from pysisyphus.intcoords.derivatives import dq_ld, d2q_ld
from pysisyphus.linalg import cross3, norm3


[docs] class LinearDisplacement(Primitive): def __init__(self, *args, complement=False, **kwargs): kwargs["calc_kwargs"] = ("complement", "cross_vec") super().__init__(*args, **kwargs) self.complement = complement self.cross_vec = None @staticmethod def _weight(atoms, coords3d, indices, f_damping): raise Exception("Not yet implemented!")
[docs] def calculate(self, coords3d, indices=None, gradient=False): if self.cross_vec is None: self.set_cross_vec(coords3d, indices) return super().calculate(coords3d, indices, gradient)
@staticmethod def _calculate(coords3d, indices, gradient=False, complement=False, cross_vec=None): m, o, n = indices w_dash = coords3d[n] - coords3d[m] w = w_dash / norm3(w_dash) u_dash = coords3d[m] - coords3d[o] v_dash = coords3d[n] - coords3d[o] u = u_dash / norm3(u_dash) v = v_dash / norm3(v_dash) # Vector for cross product to determine first orthogonal direction if cross_vec is None: cross_vec = LinearDisplacement._get_cross_vec(coords3d, indices) if complement: cross_vec = cross3(w, cross_vec) cross_vec /= norm3(cross_vec) # Orthogonal direction y = cross3(w, cross_vec) y /= norm3(y) lin_disp = y.dot(u) + y.dot(v) if gradient: row = np.zeros_like(coords3d) row[indices] = dq_ld(*coords3d[indices].flatten(), *cross_vec).reshape(-1, 3) return lin_disp, row.flatten() return lin_disp
[docs] def jacobian(self, coords3d, indices=None): if self.cross_vec is None: self.set_cross_vec(coords3d, indices) return super().jacobian(coords3d, indices)
@staticmethod def _jacobian(coords3d, indices, complement=False, cross_vec=None): if cross_vec is None: cross_vec = LinearDisplacement._get_cross_vec(coords3d, indices) if complement: m, _, n = indices w_dash = coords3d[n] - coords3d[m] w = w_dash / norm3(w_dash) cross_vec = cross3(w, cross_vec) return d2q_ld(*coords3d[indices].flatten(), *cross_vec) def __str__(self): return ( f"LinearDisplacement({tuple(self.indices)}, complement={self.complement})" )