def test_transform_gradient(self): tai, atom_indices = self.make_atom_indices_python_topology() tnorm = self.make_normal_python_topology() coords = self.get_random_rbcoords() aai = tai.to_atomistic(coords.copy()) anorm = tnorm.to_atomistic(coords.copy()) lj = LJ() # atomistic_coords = np.random.uniform(-1, 1, 3*len(atom_indices)) # e, atomistic_grad = lj.getEnergyGradient(atomistic_coords) e1, gai = lj.getEnergyGradient(aai.ravel()) e2, gnorm = lj.getEnergyGradient(anorm.ravel()) self.assertAlmostEqual(e1, e2) assert_arrays_almost_equal(self, gai.reshape(-1,3)[atom_indices], gnorm.reshape(-1,3)) rb_gai = tai.transform_gradient(coords.copy(), gai) rb_gnorm = tnorm.transform_gradient(coords.copy(), gnorm) assert_arrays_almost_equal(self, rb_gai, rb_gnorm)
class TestLJ_CPP(unittest.TestCase): def setUp(self): self.natoms = 18 self.pot = _lj.LJ() self.pot_comp = LJ() x = np.random.uniform(-1, 1, 3 * self.natoms) ret = mylbfgs(x, self.pot_comp, tol=10.) self.x = ret.coords def test(self): eonly = self.pot.getEnergy(self.x) e, g = self.pot.getEnergyGradient(self.x) self.assertAlmostEqual(e, eonly, delta=1e-6) et, gt = self.pot_comp.getEnergyGradient(self.x) self.assertAlmostEqual(e, et, delta=1e-6) self.assertLess(np.max(np.abs(g - gt)), 1e-6) def test_numerical_gradient(self): e, g = self.pot.getEnergyGradient(self.x) gnum = self.pot.NumericalDerivative(self.x) gnum_old = self.pot_comp.NumericalDerivative(self.x) self.assertLess(np.max(np.abs(gnum_old - gnum)), 1e-6) self.assertLess(np.max(np.abs(g - gnum)), 1e-6) def test_numerical_hessian(self): # e, g = self.pot.getEnergyGradient(self.x) h = self.pot.NumericalHessian(self.x) h_old = self.pot_comp.NumericalHessian(self.x) self.assertLess(np.max(np.abs(h_old - h)), 1e-6)
class TestLJ_CPP(unittest.TestCase): def setUp(self): self.natoms = 18 self.pot = _lj.LJ() self.pot_comp = LJ() x = np.random.uniform(-1,1, 3*self.natoms) ret = mylbfgs(x, self.pot_comp, tol=10.) self.x = ret.coords def test(self): eonly = self.pot.getEnergy(self.x) e, g = self.pot.getEnergyGradient(self.x) self.assertAlmostEqual(e, eonly, delta=1e-6) et, gt = self.pot_comp.getEnergyGradient(self.x) self.assertAlmostEqual(e, et, delta=1e-6) self.assertLess(np.max(np.abs(g - gt)), 1e-6) def test_numerical_gradient(self): e, g = self.pot.getEnergyGradient(self.x) gnum = self.pot.NumericalDerivative(self.x) gnum_old = self.pot_comp.NumericalDerivative(self.x) self.assertLess(np.max(np.abs(gnum_old - gnum)), 1e-6) self.assertLess(np.max(np.abs(g - gnum)), 1e-6) def test_numerical_hessian(self): # e, g = self.pot.getEnergyGradient(self.x) h = self.pot.NumericalHessian(self.x) h_old = self.pot_comp.NumericalHessian(self.x) self.assertLess(np.max(np.abs(h_old - h)), 1e-6)
class ATLJ(BasePotential): """ Lennard Jones + three body Axilrod-Teller term V = sum_ij VLJ_ij + sum_ijk Z * (1 + 3*cos(t1)*cos(t2)*cos(t3)) / (rij * rjk * rik)**3 ) where t1, t2, t3 are the internal angles of the triangle ijk Z > 0 stabilizes linear vs. triangular geometries """ def __init__(self, eps=1.0, sig=1.0, Z=1.): """ simple lennard jones potential""" self.sig = sig self.eps = eps self.Z = Z self.lj = LJ(self.sig, self.eps) def getEnergySlow(self, coords): Elj = self.lj.getEnergy(coords) natoms = coords.size / 3 X = np.reshape(coords, [natoms, 3]) Z = self.Z energy = 0. for i in range(natoms): for j in range(i): for k in range(j): drij = X[i, :] - X[j, :] drik = X[i, :] - X[k, :] drjk = X[j, :] - X[k, :] rij = np.linalg.norm(drij) rik = np.linalg.norm(drik) rjk = np.linalg.norm(drjk) energy += (Z * (1. + 3. * np.dot(drij, -drjk) * np.dot(-drij, -drik) * np.dot(drik, drjk) / (rij * rik * rjk) ** 2) / (rij * rik * rjk) ** 3 ) energy += Elj return energy def getEnergyFortran(self, coords): garbage, e = ATfort.axt(coords, False, self.Z) Elj = self.lj.getEnergy(coords) return e + Elj def getEnergyGradientFortran(self, coords): grad, e = ATfort.axt(coords, True, self.Z) elj, gradlj = self.lj.getEnergyGradient(coords) return e + elj, grad + gradlj def getEnergy(self, coords): return self.getEnergyFortran(coords) def getEnergyGradient(self, coords): return self.getEnergyGradientFortran(coords)
class ATLJ(BasePotential): """ Lennard Jones + three body Axilrod-Teller term V = sum_ij VLJ_ij + sum_ijk Z * (1 + 3*cos(t1)*cos(t2)*cos(t3)) / (rij * rjk * rik)**3 ) where t1, t2, t3 are the internal angles of the triangle ijk Z > 0 stabilizes linear vs. triangular geometries """ def __init__(self, eps=1.0, sig=1.0, Z=1.): """ simple lennard jones potential""" self.sig = sig self.eps = eps self.Z = Z self.lj = LJ(self.sig, self.eps) def getEnergySlow(self, coords): Elj = self.lj.getEnergy(coords) natoms = coords.size // 3 X = np.reshape(coords, [natoms, 3]) Z = self.Z energy = 0. for i in range(natoms): for j in range(i): for k in range(j): drij = X[i, :] - X[j, :] drik = X[i, :] - X[k, :] drjk = X[j, :] - X[k, :] rij = np.linalg.norm(drij) rik = np.linalg.norm(drik) rjk = np.linalg.norm(drjk) energy += (Z * (1. + 3. * np.dot(drij, -drjk) * np.dot(-drij, -drik) * np.dot(drik, drjk) / (rij * rik * rjk)**2) / (rij * rik * rjk)**3) energy += Elj return energy def getEnergyFortran(self, coords): garbage, e = ATfort.axt(coords, False, self.Z) Elj = self.lj.getEnergy(coords) return e + Elj def getEnergyGradientFortran(self, coords): grad, e = ATfort.axt(coords, True, self.Z) elj, gradlj = self.lj.getEnergyGradient(coords) return e + elj, grad + gradlj def getEnergy(self, coords): return self.getEnergyFortran(coords) def getEnergyGradient(self, coords): return self.getEnergyGradientFortran(coords)
def test_to_atomistic2(self): x0 = np.array(list(range(self.nrigid * 6)), dtype=float) x2 = x0.reshape([-1, 3]) for p in x2[self.nrigid:, :]: p /= np.linalg.norm(p) atomistic = self.topology.to_atomistic(x0).flatten() from pele.potentials import LJ lj = LJ() e, g = lj.getEnergyGradient(atomistic.reshape(-1)) grb = self.topology.transform_gradient(x0, g) rbpot = RBPotentialWrapper(self.topology, lj) print(rbpot.getEnergy(x0))
def test_to_atomistic2(self): x0 = np.array(list(range(self.nrigid * 6)), dtype=float) x2 = x0.reshape([-1,3]) for p in x2[self.nrigid:,:]: p /= np.linalg.norm(p) atomistic = self.topology.to_atomistic(x0).flatten() from pele.potentials import LJ lj = LJ() e, g = lj.getEnergyGradient(atomistic.reshape(-1)) grb = self.topology.transform_gradient(x0, g) rbpot = RBPotentialWrapper(self.topology, lj) print(rbpot.getEnergy(x0))
def test_transform_gradient(self): tai, atom_indices = self.make_atom_indices_python_topology() tnorm = self.make_normal_python_topology() coords = self.get_random_rbcoords() aai = tai.to_atomistic(coords.copy()) anorm = tnorm.to_atomistic(coords.copy()) lj = LJ() # atomistic_coords = np.random.uniform(-1, 1, 3*len(atom_indices)) # e, atomistic_grad = lj.getEnergyGradient(atomistic_coords) e1, gai = lj.getEnergyGradient(aai.ravel()) e2, gnorm = lj.getEnergyGradient(anorm.ravel()) self.assertAlmostEqual(e1, e2) assert_arrays_almost_equal(self, gai.reshape(-1, 3)[atom_indices], gnorm.reshape(-1, 3)) rb_gai = tai.transform_gradient(coords.copy(), gai) rb_gnorm = tnorm.transform_gradient(coords.copy(), gnorm) assert_arrays_almost_equal(self, rb_gai, rb_gnorm)
class TestLJ_CPP_Ilist(unittest.TestCase): def setUp(self): self.natoms = 18 self.ilist = np.array([(i,j) for i in range(self.natoms) for j in range(i+1,self.natoms)]).reshape(-1) assert self.ilist.size == self.natoms*(self.natoms-1) # print self.ilist self.pot = _lj.LJInteractionList(self.ilist) self.pot_comp = LJ() x = np.random.uniform(-1,1, 3*self.natoms) ret = mylbfgs(x, self.pot_comp, tol=10.) self.x = ret.coords def test(self): eonly = self.pot.getEnergy(self.x) e, g = self.pot.getEnergyGradient(self.x) self.assertAlmostEqual(e, eonly, delta=1e-6) et, gt = self.pot_comp.getEnergyGradient(self.x) self.assertAlmostEqual(e, et, delta=1e-6) self.assertLess(np.max(np.abs(g - gt)), 1e-6)
class TestLJ_CPP_Ilist(unittest.TestCase): def setUp(self): self.natoms = 18 self.ilist = np.array([(i,j) for i in xrange(self.natoms) for j in xrange(i+1,self.natoms)]).reshape(-1) assert self.ilist.size == self.natoms*(self.natoms-1) # print self.ilist self.pot = _lj.LJInteractionList(self.ilist) self.pot_comp = LJ() x = np.random.uniform(-1,1, 3*self.natoms) ret = mylbfgs(x, self.pot_comp, tol=10.) self.x = ret.coords def test(self): eonly = self.pot.getEnergy(self.x) e, g = self.pot.getEnergyGradient(self.x) self.assertAlmostEqual(e, eonly, delta=1e-6) et, gt = self.pot_comp.getEnergyGradient(self.x) self.assertAlmostEqual(e, et, delta=1e-6) self.assertLess(np.max(np.abs(g - gt)), 1e-6)
def test_to_atomistic2(self): x0 = np.array(range(self.nrigid * 6), dtype=float); x2 = x0.reshape([-1,3]) for p in x2[self.nrigid:,:]: p /= np.linalg.norm(p); print x0 print "range to atomistic" print x0 atomistic = self.topology.to_atomistic(x0).flatten() print atomistic print atomistic.size print atomistic[14] print atomistic[23] from pele.potentials import LJ lj = LJ() e, g = lj.getEnergyGradient(atomistic.reshape(-1)) grb = self.topology.transform_gradient(x0, g); print "transformed gradient" print grb print "rbpotential" rbpot = RBPotentialWrapper(self.topology, lj); print rbpot.getEnergy(x0);
class ATLJ(BasePotential): """ Lennard Jones + three body Axilrod-Teller term V = sum_ij VLJ_ij + sum_ijk Z * (1 + 3*cos(t1)*cos(t2)*cos(t3)) / (rij * rjk * rik)**3 ) where t1, t2, t3 are the internal angles of the triangle ijk Z > 0 stabilizes linear vs. triangular geometries """ def __init__(self, eps=1.0, sig=1.0, Z=1.): """ simple lennard jones potential""" self.sig = sig self.eps = eps self.Z = Z self.lj = LJ(self.sig, self.eps) # def getEnergyWeave(self, coords): # """ # use weave inline # """ # Elj = self.lj.getEnergy(coords) # # natoms = coords.size/3 # coords = np.reshape(coords, [natoms,3]) # energy=0. # Z = self.Z # #support_code # code = """ # double drij[3]; # double drik[3]; # double drjk[3]; # energy = 0.; # for (int i=0; i < natoms; ++i){ # for (int j=0; j<i; ++j){ # for (int k=0; k<j; ++k){ # # double rij = 0.; # double rik = 0.; # double rjk = 0.; # # for (int d=0; d<3; ++d){ # drij[d] = coords(i,d) - coords(j,d); # rij += drij[d]*drij[d]; # } # for (int d=0; d<3; ++d){ # drjk[d] = coords(j,d) - coords(k,d); # rjk += drjk[d]*drjk[d]; # } # for (int d=0; d<3; ++d){ # drik[d] = coords(i,d) - coords(k,d); # rik += drik[d]*drik[d]; # } # # rij = sqrt(rij); # rjk = sqrt(rjk); # rik = sqrt(rik); # # double ctijk = ( -(drij[0]*drjk[0] + drij[1]*drjk[1] + drij[2]*drjk[2]) / (rij * rjk) ); # double ctjki = ( (drjk[0]*drik[0] + drjk[1]*drik[1] + drjk[2]*drik[2]) / (rjk * rik) ); # double ctkij = ( (drik[0]*drij[0] + drik[1]*drij[1] + drik[2]*drij[2]) / (rik * rij) ); # # double r3 = rij*rjk*rik; # energy += Z*(1. + 3. * ctijk * ctjki * ctkij) / (r3*r3*r3); # } # } # } # return_val= energy; # """ # energy = weave.inline(code, ["coords", "energy", "Z", "natoms"], type_converters=converters.blitz, verbose=2) # #print "fast energy", Elj, energy # energy += Elj # return energy def getEnergySlow(self, coords): Elj = self.lj.getEnergy(coords) natoms = coords.size/3 X = np.reshape(coords, [natoms,3]) Z = self.Z energy = 0. for i in range(natoms): for j in range(i): for k in range(j): #print i, j, k drij = X[i,:] - X[j,:] drik = X[i,:] - X[k,:] drjk = X[j,:] - X[k,:] rij = np.linalg.norm( drij ) rik = np.linalg.norm( drik ) rjk = np.linalg.norm( drjk ) energy += Z * (1. + 3.*\ np.dot( drij, -drjk ) * \ np.dot(-drij, -drik ) * \ np.dot( drik, drjk ) / (rij*rik*rjk)**2) \ / (rij*rik*rjk)**3 #print "slow energy", Elj, energy energy += Elj return energy def getEnergyFortran(self, coords): #grad,potel = axt(x,gradt,zstar,[n]) natoms = len(coords)/3 garbage, e = ATfort.axt(coords, False, self.Z) Elj = self.lj.getEnergy(coords) return e + Elj def getEnergyGradientFortran(self, coords): #grad,potel = axt(x,gradt,zstar,[n]) natoms = len(coords)/3 grad, e = ATfort.axt(coords, True, self.Z) elj, gradlj = self.lj.getEnergyGradient(coords) return e + elj, grad + gradlj def getEnergy(self, coords): return self.getEnergyFortran(coords) def getEnergyGradient(self, coords): #return self.getEnergyGradientNumerical(coords) return self.getEnergyGradientFortran(coords)
def getEnergyGradient(self, coords): atom_coords = self.aatopology.to_atomistic(coords) e, atom_grad = LJ.getEnergyGradient(self, atom_coords.flatten()) grad = self.aatopology.transform_gradient(coords, atom_grad) return e, grad