Exemple #1
0
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)
Exemple #2
0
 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
Exemple #3
0
 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
Exemple #4
0
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):
    x = 1. * np.random.random(3 * natoms)
    ret = mylbfgs(x, pot_old, tol=1e-5)
    print "PY:", np.linalg.norm(pot_old.getEnergyGradient(ret[0])[1])

print time.time() - t1, t1 - t0

t0 = time.time()
for i in xrange(N):
    e, g = pot_old.getEnergyGradient(x)
time_f2py = time.time() - t0
print "f2py potential", e, "time", time.time() - t0

t0 = time.time()
for i in xrange(N):
    e, g = pot.get_energy_gradient(x)
time_cython = time.time() - t0
print "cython potential", e, "time", time.time() - t0
Exemple #5
0
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):
    x = 1.*np.random.random(3*natoms)
    ret = mylbfgs(x, pot_old, tol=1e-5)
    print "PY:", np.linalg.norm(pot_old.getEnergyGradient(ret[0])[1])

print time.time()-t1, t1-t0

t0 = time.time()
for i in xrange(N):
    e, g = pot_old.getEnergyGradient(x)
time_f2py = time.time() - t0
print "f2py potential",e,"time",time.time() - t0

t0 = time.time()
for i in xrange(N):
    e, g = pot.get_energy_gradient(x)
time_cython = time.time() - t0
print "cython potential",e,"time",time.time() - t0
Exemple #6
0
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)