def metric_tensor_cog(self, p): """calculate the metric tensor when for w_i != m_i Note: js850> why is x not used in this function? """ R, R1, R2, R3 = rot_mat_derivatives(p, True) g = np.zeros([6, 6]) # the com part g[0:3, 0:3] = self.W * np.identity(3) # the rotational part g[3, 3] = np.trace(np.dot(R1, np.dot(self.Sm, R1.transpose()))) g[3, 4] = np.trace(np.dot(R1, np.dot(self.Sm, R2.transpose()))) g[3, 5] = np.trace(np.dot(R1, np.dot(self.Sm, R3.transpose()))) g[4, 4] = np.trace(np.dot(R2, np.dot(self.Sm, R2.transpose()))) g[4, 5] = np.trace(np.dot(R2, np.dot(self.Sm, R3.transpose()))) g[5, 5] = np.trace(np.dot(R3, np.dot(self.Sm, R3.transpose()))) g[4, 3] = g[3, 4] g[5, 4] = g[4, 5] g[5, 3] = g[3, 5] # the mixing part # g[0:3,3] = 2.*self.W * np.dot(R1, self.cog) # g[0:3,4] = 2.*self.W * np.dot(R2, self.cog) # g[0:3,5] = 2.*self.W * np.dot(R3, self.cog) # #g[0:3,3:] = g[0:3,3:].transpose() # # g[3,0:3] = g[0:3,3] # g[4,0:3] = g[0:3,4] # g[5,0:3] = g[0:3,5] return g
def test(): # pragma: no cover from math import sin, cos, pi from copy import deepcopy water = RigidFragment() rho = 0.9572 theta = 104.52/180.0*pi water.add_atom("O", np.array([0., -1., 0.]), 1.) water.add_atom("O", np.array([0., 1., 0.]), 1.) #water.add_atom("H", rho*np.array([0.0, sin(0.5*theta), cos(0.5*theta)]), 1.) #water.add_atom("H", rho*np.array([0.0, -sin(0.5*theta), cos(0.5*theta)]), 1.) water.finalize_setup() # define the whole water system system = RBTopology() nrigid = 1 system.add_sites([deepcopy(water) for i in xrange(nrigid)]) from pele.utils import rotations rbcoords=np.zeros(6) rbcoords[3:]= rotations.random_aa() coords = system.to_atomistic(rbcoords) print "rb coords\n", rbcoords print "coords\n", coords grad = (np.random.random(coords.shape) -0.5) v = coords[1] - coords[0] v/=np.linalg.norm(v) grad[0] -= np.dot(grad[0], v)*v grad[1] -= np.dot(grad[1], v)*v grad -= np.average(grad, axis=0) grad /= np.linalg.norm(grad) print "torque", np.linalg.norm(np.cross(grad, v)) rbgrad = system.transform_gradient(rbcoords, grad) p = rbcoords[3:] x = rbcoords[0:3] gp = rbgrad[3:] gx = rbgrad[:3] R, R1, R2, R3 = rotations.rot_mat_derivatives(p) print "test1", np.linalg.norm(R1*gp[0]) print "test2", np.linalg.norm(R2*gp[1]) print "test3", np.linalg.norm(R3*gp[2]) print "test4", np.linalg.norm(R1*gp[0]) + np.linalg.norm(R2*gp[1]) + np.linalg.norm(R3*gp[2]) dR = R1*gp[0] + R2*gp[1] + R3*gp[2] print "test", np.linalg.norm(R1*gp[0] + R2*gp[1] + R3*gp[2]) print np.trace(np.dot(dR, dR.transpose())) G = water.metric_tensor_aa(p) print np.dot(p, np.dot(G, p)) exit() gnew = system.redistribute_forces(rbcoords, rbgrad) print gnew print system.transform_grad(rbcoords, gnew)
def transform_grad(self, p, g): g_com = np.sum(g, axis=0) R, R1, R2, R3 = rotations.rot_mat_derivatives(p) g_p = np.zeros_like(g_com) for ga, x in zip(g, self.atom_positions): g_p[0] += np.dot(ga, np.dot(R1, x)) g_p[1] += np.dot(ga, np.dot(R2, x)) g_p[2] += np.dot(ga, np.dot(R3, x)) return g_com, g_p
def redistribute_forces(self, p, grad_com, grad_p): R, R1, R2, R3 = rotations.rot_mat_derivatives(p) grad = np.dot(R1, np.transpose(self.atom_positions)).transpose()*grad_p[0] grad += np.dot(R2, np.transpose(self.atom_positions)).transpose()*grad_p[1] grad += np.dot(R3, np.transpose(self.atom_positions)).transpose()*grad_p[2] grad += grad_com grad = (self.atom_masses * grad.transpose()).transpose()/self.M return grad
def test(): # pragma: no cover from math import pi from copy import deepcopy water = RigidFragment() rho = 0.9572 theta = 104.52 / 180.0 * pi water.add_atom("O", np.array([0., -1., 0.]), 1.) water.add_atom("O", np.array([0., 1., 0.]), 1.) # water.add_atom("H", rho*np.array([0.0, sin(0.5*theta), cos(0.5*theta)]), 1.) #water.add_atom("H", rho*np.array([0.0, -sin(0.5*theta), cos(0.5*theta)]), 1.) water.finalize_setup() # define the whole water system system = RBTopology() nrigid = 1 system.add_sites([deepcopy(water) for i in xrange(nrigid)]) from pele.utils import rotations rbcoords = np.zeros(6) rbcoords[3:] = rotations.random_aa() coords = system.to_atomistic(rbcoords) print "rb coords\n", rbcoords print "coords\n", coords grad = (np.random.random(coords.shape) - 0.5) v = coords[1] - coords[0] v /= np.linalg.norm(v) grad[0] -= np.dot(grad[0], v) * v grad[1] -= np.dot(grad[1], v) * v grad -= np.average(grad, axis=0) grad /= np.linalg.norm(grad) print "torque", np.linalg.norm(np.cross(grad, v)) rbgrad = system.transform_gradient(rbcoords, grad) p = rbcoords[3:] x = rbcoords[0:3] gp = rbgrad[3:] gx = rbgrad[:3] R, R1, R2, R3 = rotations.rot_mat_derivatives(p) print "test1", np.linalg.norm(R1 * gp[0]) print "test2", np.linalg.norm(R2 * gp[1]) print "test3", np.linalg.norm(R3 * gp[2]) print "test4", np.linalg.norm(R1 * gp[0]) + np.linalg.norm( R2 * gp[1]) + np.linalg.norm(R3 * gp[2]) dR = R1 * gp[0] + R2 * gp[1] + R3 * gp[2] print "test", np.linalg.norm(R1 * gp[0] + R2 * gp[1] + R3 * gp[2]) print np.trace(np.dot(dR, dR.transpose()))
def redistribute_forces(self, p, grad_com, grad_p): # js850> as far as I can tell this is never used. Maybe we should remove it? R, R1, R2, R3 = rotations.rot_mat_derivatives(p) grad = np.dot(R1, np.transpose(self.atom_positions)).transpose() * grad_p[0] grad += np.dot(R2, np.transpose(self.atom_positions)).transpose() * grad_p[1] grad += np.dot(R3, np.transpose(self.atom_positions)).transpose() * grad_p[2] grad += grad_com grad = (self.atom_masses * grad.transpose()).transpose() / self.M return grad
def redistribute_forces(self, p, grad_com, grad_p): R, R1, R2, R3 = rotations.rot_mat_derivatives(p) grad = np.dot(R1, np.transpose( self.atom_positions)).transpose() * grad_p[0] grad += np.dot(R2, np.transpose( self.atom_positions)).transpose() * grad_p[1] grad += np.dot(R3, np.transpose( self.atom_positions)).transpose() * grad_p[2] grad += grad_com grad = (self.atom_masses * grad.transpose()).transpose() / self.M return grad
def metric_tensor(self, p): """calculate the mass weighted metric tensor """ R, R1, R2, R3 = rot_mat_derivatives(p, True) g = np.zeros([3, 3]) g[0, 0] = np.trace(np.dot(R1, np.dot(self.Sm, R1.transpose()))) g[0, 1] = np.trace(np.dot(R1, np.dot(self.Sm, R2.transpose()))) g[0, 2] = np.trace(np.dot(R1, np.dot(self.Sm, R3.transpose()))) g[1, 1] = np.trace(np.dot(R2, np.dot(self.Sm, R2.transpose()))) g[1, 2] = np.trace(np.dot(R2, np.dot(self.Sm, R3.transpose()))) g[2, 2] = np.trace(np.dot(R3, np.dot(self.Sm, R3.transpose()))) g[1, 0] = g[0, 1] g[2, 1] = g[1, 2] g[2, 0] = g[0, 2] gx = np.identity(3) * self.M return gx, g