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)
def test2(): import numpy as np from pele.potentials import LJ from pele.utils.frozen_atoms import FrozenPotWrapper from pele.optimize import mylbfgs natoms = 4 pot = LJ() reference_coords = np.random.uniform(-1, 1, [3 * natoms]) print reference_coords # freeze the first two atoms (6 degrees of freedom) frozen_dof = range(6) fpot = FrozenPotWrapper(pot, reference_coords, frozen_dof) reduced_coords = fpot.coords_converter.get_reduced_coords(reference_coords) print "the energy in the full representation:" print pot.getEnergy(reference_coords) print "is the same as the energy in the reduced representation:" print fpot.getEnergy(reduced_coords) ret = mylbfgs(reduced_coords, fpot) print "after a minimization the energy is ", ret.energy, "and the rms gradient is", ret.rms print "the coordinates of the frozen degrees of freedom are unchanged" print "starting coords:", reference_coords print "minimized coords:", fpot.coords_converter.get_full_coords(ret.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))
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)
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 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 main(): natoms = 4 pot = LJ() reference_coords = np.random.uniform(-1, 1, [3 * natoms]) print reference_coords # freeze the first two atoms (6 degrees of freedom) frozen_dof = range(6) fpot = FrozenPotentialWrapper(pot, reference_coords, frozen_dof) reduced_coords = fpot.get_reduced_coords(reference_coords) print "the energy in the full representation:" print pot.getEnergy(reference_coords) print "is the same as the energy in the reduced representation:" print fpot.getEnergy(reduced_coords) ret = mylbfgs(reduced_coords, fpot) print "after a minimization the energy is ", ret.energy, "and the rms gradient is", ret.rms print "the coordinates of the frozen degrees of freedom are unchanged" print "starting coords:", reference_coords print "minimized coords:", fpot.get_full_coords(ret.coords)
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 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 __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 get_potential(self): return LJ(self.natoms)
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
In the above we used three imports. We used the `numpy` library to construct a random one dimensional array. We used the Lennard-Jones potential :class:`.LJ`, and we used the minimization routine :func:`.lbfgs_py` which is just a wrapper for the class :class:`.LBFGS`. The return value is an optimization result, which is just a container (:class:`.Result`) that stores the final energy, final coordinates, the number of function calls, etc. If we want to then save the minimized coordinates in an xyz file we can use the function :func:`.write_xyz` :: from pele.utils.xyz import write_xyz with open("out.xyz", "w") as fout: title = "energy = " + str(result.energy) write_xyz(fout, result.coords, title=title) """ import numpy as np from pele.potentials import LJ from pele.optimize import lbfgs_py natoms = 5 x = np.random.uniform(-2, 2, natoms * 3) pot = LJ() result = lbfgs_py(x, pot) print result from pele.utils.xyz import write_xyz with open("out.xyz", "w") as fout: title = "energy = " + str(result.energy) write_xyz(fout, result.coords, title=title)
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 get_potential(self): return LJ()
# finalize the rigid body setup for rb in rb_sites: rb.finalize_setup() # define a new rigid body system rbsystem = rigidbody.RBSystem() rbsystem.add_sites(rb_sites) print len(rbsystem.sites), len(rbsystem.indices) rbcoords = rbsystem.coords_adapter(np.zeros(len(rbsystem.sites)*6)) for site, com in zip(rbsystem.sites, rbcoords.posRigid): com[:] = ref.coords[site.indices[0]] - site.atom_positions[0] # for simplicity just use a lj potential here pot = LJ(sigma=2.) # get the flattened coordinate array print pot.getEnergy(ref.coords.flatten()) rbpot = rigidbody.RBPotentialWrapper(rbsystem, pot) print rbpot.getEnergy(rbcoords.coords) e, g = rbpot.getEnergyGradient(rbcoords.coords) g_n = rbpot.NumericalDerivative(rbcoords.coords, eps=1e-4) cg = rbsystem.coords_adapter(g-g_n) print cg.posRigid print cg.rotRigid ret = lbfgs_py(rbcoords.coords, rbpot) print ret.energy xyz.write_xyz(open("quenched.xyz", "w"), rbsystem.to_atomistic(ret.coords), atomtypes=ref.atomtypes)
def get_potential(self, eps, sig, boxl=None): # return LJ(self.natoms, sig=sig, boxl = boxl) return LJ(eps, sig, boxl=boxl)
import _pele import numpy as np import time import sys import _lj import _lbfgs from pele.optimize import mylbfgs N = 100 natoms = [ 10, 13, 20, 30, 31, 38, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150 ] print("benchmarking lennard jones potential, %d atoms, %d calls", natoms, N) pot_old = LJ() pot = _lj.LJ() clbfgs = _lbfgs.LBFGS(pot) res = open("results.txt", "w") for na in natoms: t0 = time.time() for i in range(N): x = np.random.random(3 * na) - 0.5 ret = clbfgs.run(x) t1 = time.time() for i in range(N): x = np.random.random(3 * na) - 0.5
import _pele import numpy as np import time import sys import _lj import _lbfgs from pele.optimize import mylbfgs from . import _lj_cython import _pythonpotential N = int(sys.argv[2]) natoms = int(sys.argv[1]) print("benchmarking lennard jones potential, %d atoms, %d calls" % (natoms, N)) pot_old = LJ() pot = _lj.LJ() t0 = time.time() for i in range(N): x = 1. * (np.random.random(3 * natoms) - 0.5) clbfgs = _lbfgs.LBFGS_CPP(pot, x, tol=1e-4) ret = clbfgs.run() t1 = time.time() for i in range(N): x = 1. * (np.random.random(3 * natoms) - 0.5) ret = mylbfgs(x, pot_old, tol=1e-4) t2 = time.time()
def getEnergy(self, coords): atom_coords = self.aatopology.to_atomistic(coords) return LJ.getEnergy(self, atom_coords.flatten())
def setUp(self): from pele.potentials import LJ self.x0 = np.zeros(6) self.x0[0] = 2. self.pot = LJ()
def __init__(self, aatopology): self.aatopology = aatopology LJ.__init__(self)