def eval(self, coords, grad=False):
v1 = (coords[self.i]-coords[self.j])/bohr
v2 = (coords[self.k]-coords[self.j])/bohr
dot_product = np.dot(v1, v2)/(norm(v1)*norm(v2))
if dot_product < -1:
dot_product = -1
elif dot_product > 1:
dot_product = 1
phi = np.arccos(dot_product)
if not grad:
return phi
if abs(phi) > pi-1e-6:
grad = [
(pi-phi)/(2*norm(v1)**2)*v1,
(1/norm(v1)-1/norm(v2))*(pi-phi)/(2*norm(v1))*v1,
(pi-phi)/(2*norm(v2)**2)*v2
]
else:
grad = [
1/np.tan(phi)*v1/norm(v1)**2-v2/(norm(v1)*norm(v2)*np.sin(phi)),
(v1+v2)/(norm(v1)*norm(v2)*np.sin(phi)) -
1/np.tan(phi)*(v1/norm(v1)**2+v2/norm(v2)**2),
1/np.tan(phi)*v2/norm(v2)**2-v1/(norm(v1)*norm(v2)*np.sin(phi))
]
return phi, grad
评论列表
文章目录