def setUp(self): from pygmin.potentials import LJ from pygmin import defaults from pygmin.mindist import CoMToOrigin self.natoms = 15 self.pot = LJ(self.natoms) self.permlist = [range(self.natoms)] self.X1 = np.random.uniform(-1,1,[self.natoms*3])*(float(self.natoms))**(1./3)/2 ret = defaults.quenchRoutine(self.X1, self.pot.getEnergyGradient, tol=.1) self.X1 = ret[0] self.X1 = CoMToOrigin(self.X1)
def testGradient(self): natoms = 10 coords = np.random.uniform(-1, 1, natoms * 3) * 2 lj = LJ() atlj = ATLJ(Z=3.) e, Gf = atlj.getEnergyGradientFortran(coords) e, Gn = atlj.getEnergyGradientNumerical(coords) print Gf print Gn maxdiff = np.max(np.abs(Gf - Gn)) maxnorm = np.max(np.abs(Gf + Gn)) / 2 maxrel = np.max(np.abs((Gf - Gn) / (Gf + Gn) * 2.)) print "maximum relative difference in gradients", maxdiff, maxdiff / maxnorm self.assertTrue( maxdiff / maxnorm < 1e-4, "ATLJ: gradient differs from numerical gradient by %g" % (maxdiff))
def testenergy(self): natoms = 10 coords = np.random.uniform(-1, 1, natoms * 3) * 2 from pygmin.optimize import mylbfgs as quench lj = LJ() ret = quench(coords, lj) coords = ret.coords atlj = ATLJ(Z=3.) e2 = atlj.getEnergySlow(coords) # e1 = atlj.getEnergyWeave(coords) # #print "%g - %g = %g" % (e1, e2, e1-e2) # self.assertTrue( abs(e1 - e2) < 1e-12, "ATLJ: two energy methods give different results: %g - %g = %g" % (e1, e2, e1-e2) ) e1 = atlj.getEnergyFortran(coords) #print "%g - %g = %g" % (e1, e2, e1-e2) #print e1/e2 self.assertTrue( abs(e1 - e2) < 1e-12, "ATLJ: fortran energy gives different results: %g - %g = %g" % (e1, e2, e1 - e2))
def mytest(nmin=40, natoms=13): from pygmin.landscape import DoubleEndedConnect from pygmin.landscape._graph import create_random_database from pygmin.mindist import minPermDistStochastic, MinDistWrapper from pygmin.potentials import LJ from pygmin.landscape import TSGraph pot = LJ() mindist = MinDistWrapper(minPermDistStochastic, permlist=[range(natoms)], niter=10) db = create_random_database(nmin=nmin, natoms=natoms) min1, min2 = list(db.minima())[:2] graph = TSGraph(db) connect = DoubleEndedConnect(min1, min2, pot, mindist, db, use_all_min=True, merge_minima=True, max_dist_merge=.1)
def getEnergy(self, coords): atom_coords = self.aatopology.to_atomistic(coords) return LJ.getEnergy(self, atom_coords.flatten())
def __init__(self, aatopology): self.aatopology = aatopology LJ.__init__(self)
# 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.getEnergyGradient) print ret[1] xyz.write_xyz(open("quenched.xyz", "w"), rbsystem.to_atomistic(ret[0]), atomtypes=ref.atomtypes)
import _pygmin import numpy as np import time import sys import _lj import _lbfgs from pygmin.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 xrange(N): x = np.random.random(3 * na) - 0.5 ret = clbfgs.run(x) t1 = time.time() for i in xrange(N): x = np.random.random(3 * na) - 0.5
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, [natoms]) 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, [natoms]) 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)
# benchmark all interface from pygmin.potentials import LJ import _pygmin import numpy as np import time import sys import _lj import _lbfgs from pygmin.optimize import mylbfgs N=10 # int(sys.argv[2]) natoms=38 #int(sys.argv[1]) print "benchmarking lennard jones potential, %d atoms, %d calls", natoms, N pot_old = LJ() pot = _lj.LJ() clbfgs = _lbfgs.LBFGS(pot) t0 = time.time() for i in xrange(100): x = 1.*(np.random.random(3*natoms) - 0.5) ret = clbfgs.run(x) #print ret #print ret[0] #print pot.get_energy(ret[0]) e, g = pot.get_energy_gradient(ret[0]) print "C", np.linalg.norm(g) t1 = time.time() for i in xrange(100):
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)
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, [natoms]) 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, [natoms]) 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(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
# benchmark all interface from pygmin.potentials import LJ import _pygmin import numpy as np import time import sys import _lj import _lbfgs from pygmin.optimize import mylbfgs N = 10 # int(sys.argv[2]) natoms = 38 #int(sys.argv[1]) print "benchmarking lennard jones potential, %d atoms, %d calls", natoms, N pot_old = LJ() pot = _lj.LJ() clbfgs = _lbfgs.LBFGS(pot) t0 = time.time() for i in xrange(100): x = 1. * (np.random.random(3 * natoms) - 0.5) ret = clbfgs.run(x) #print ret #print ret[0] #print pot.get_energy(ret[0]) e, g = pot.get_energy_gradient(ret[0]) print "C", np.linalg.norm(g) t1 = time.time() for i in xrange(100):
# 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): return LJ()