def angle_hessian(xyz, iangles): n_atoms, three = xyz.shape if three != 3: raise TypeError('xyz must be of length 3 in the last dimension.') n_angles, three = iangles.shape if three != 3: raise TypeError('angles must have 3 columns.') qa = internal.angles(xyz.reshape(1, n_atoms, 3), iangles).flatten() jacobian = internal_derivs.angle_derivs(xyz, iangles) hessian = np.zeros((n_angles, n_atoms, 3, n_atoms, 3)) for i, (m, o, n) in enumerate(iangles): u_prime = xyz[m] - xyz[o] v_prime = xyz[n] - xyz[o] lambda_u = np.linalg.norm(u_prime) lambda_v = np.linalg.norm(v_prime) u = u_prime / lambda_u v = v_prime / lambda_v jac = jacobian[i] cos = np.cos(qa[i]) sin = np.sin(qa[i]) uv = np.outer(u, v) uu = np.outer(u, u) vv = np.outer(v, v) eye = np.eye(3) term1 = (uv + uv.T + (-3 * uu + eye) * cos) / (lambda_u**2 * sin) term2 = (uv + uv.T + (-3 * vv + eye) * cos) / (lambda_v**2 * sin) term3 = (uu + vv - uv * cos - eye) / (lambda_u * lambda_v * sin) term4 = (uu + vv - uv.T * cos - eye) / (lambda_u * lambda_v * sin) hessian[i] = -(cos / sin) * np.outer( jac.flatten(), jac.flatten()).reshape(n_atoms, 3, n_atoms, 3) for a in [m, n, o]: for b in [m, n, o]: sign6(a, m, o, b, m, o) hessian[i, a, :, b, :] += sign6(a, m, o, b, m, o) * term1 hessian[i, a, :, b, :] += sign6(a, n, o, b, n, o) * term2 hessian[i, a, :, b, :] += sign6(a, m, o, b, n, o) * term3 hessian[i, a, :, b, :] += sign6(a, n, o, b, m, o) * term4 return hessian
def angle_hessian(xyz, iangles): n_atoms, three = xyz.shape if three != 3: raise TypeError('xyz must be of length 3 in the last dimension.') n_angles, three = iangles.shape if three != 3: raise TypeError('angles must have 3 columns.') qa = internal.angles(xyz.reshape(1, n_atoms, 3), iangles).flatten() jacobian = internal_derivs.angle_derivs(xyz, iangles) hessian = np.zeros((n_angles, n_atoms, 3, n_atoms, 3)) for i, (m, o, n) in enumerate(iangles): u_prime = xyz[m] - xyz[o] v_prime = xyz[n] - xyz[o] lambda_u = np.linalg.norm(u_prime) lambda_v = np.linalg.norm(v_prime) u = u_prime / lambda_u v = v_prime / lambda_v jac = jacobian[i] cos = np.cos(qa[i]) sin = np.sin(qa[i]) uv = np.outer(u, v) uu = np.outer(u, u) vv = np.outer(v, v) eye = np.eye(3) term1 = (uv + uv.T + (-3 * uu + eye) * cos) / (lambda_u**2 * sin) term2 = (uv + uv.T + (-3 * vv + eye) * cos) / (lambda_v**2 * sin) term3 = (uu + vv - uv * cos - eye) / (lambda_u * lambda_v * sin) term4 = (uu + vv - uv.T * cos - eye) / (lambda_u * lambda_v * sin) hessian[i] = -(cos / sin) * np.outer(jac.flatten(), jac.flatten()).reshape(n_atoms, 3, n_atoms, 3) for a in [m, n, o]: for b in [m, n, o]: sign6(a,m,o, b,m,o) hessian[i, a, :, b, :] += sign6(a,m,o, b,m,o) * term1 hessian[i, a, :, b, :] += sign6(a,n,o, b,n,o) * term2 hessian[i, a, :, b, :] += sign6(a,m,o, b,n,o) * term3 hessian[i, a, :, b, :] += sign6(a,n,o, b,m,o) * term4 return hessian
xyz = np.random.randn(4, 3) xyz2 = xyz.copy() xyz2[1, 1] += h ibonds = np.array([[0, 1], [0, 2]]) iangles = np.array([[0, 1, 2], [1, 2, 3]]) idihedrals = np.array([[0, 1, 2, 3]]) # print 'TESTING BOND HESSIAN' # jac1 = internal_derivs.bond_derivs(xyz, ibonds) # jac2 = internal_derivs.bond_derivs(xyz2, ibonds) # hessian = bond_hessian(xyz, ibonds) # print ((jac2-jac1)/h)[0] # print hessian[0, 1, 1] print '\nTESTING ANGLE HESSIAN' jac1 = internal_derivs.angle_derivs(xyz, iangles) jac2 = internal_derivs.angle_derivs(xyz2, iangles) hessian = angle_hessian(xyz, iangles) print((jac2 - jac1) / h)[0] print print hessian[0, 1, 1] print '\nTESTING DIHEDRAL HESSIAN' jac1, hessian = dihedral_hessian(xyz, idihedrals) jac2, hessian = dihedral_hessian(xyz2, idihedrals) print 'These matricies should match' print((jac2 - jac1) / h)[0] print print hessian[0][1, 1]
xyz2 = xyz.copy() xyz2[1,1] += h ibonds = np.array([[0,1], [0,2]]) iangles = np.array([[0,1,2], [1,2,3]]) idihedrals = np.array([[0,1,2,3]]) # print 'TESTING BOND HESSIAN' # jac1 = internal_derivs.bond_derivs(xyz, ibonds) # jac2 = internal_derivs.bond_derivs(xyz2, ibonds) # hessian = bond_hessian(xyz, ibonds) # print ((jac2-jac1)/h)[0] # print hessian[0, 1, 1] print '\nTESTING ANGLE HESSIAN' jac1 = internal_derivs.angle_derivs(xyz, iangles) jac2 = internal_derivs.angle_derivs(xyz2, iangles) hessian = angle_hessian(xyz, iangles) print ((jac2-jac1)/h)[0] print print hessian[0, 1, 1] print '\nTESTING DIHEDRAL HESSIAN' jac1, hessian = dihedral_hessian(xyz, idihedrals) jac2, hessian = dihedral_hessian(xyz2, idihedrals) print 'These matricies should match' print ((jac2-jac1)/h)[0] print print hessian[0][1,1]