예제 #1
0
 def test_110(self):
     axes = np.array([[ 1, 1, 0], 
                      [-1, 1, 0], 
                      [ 0, 0, 1]])
     
     uaxes = np.array([[ 2.**0.5/2., 2.**0.5/2., 0], 
                       [-2.**0.5/2., 2.**0.5/2., 0], 
                       [ 0, 0, 1.0]])
     assert np.allclose(axes_check(axes), uaxes)
예제 #2
0
 def test_110(self):
     axes = np.array([[ 1, 1, 0], 
                      [-1, 1, 0], 
                      [ 0, 0, 1]])
     
     uaxes = np.array([[ 2.**0.5/2., 2.**0.5/2., 0], 
                       [-2.**0.5/2., 2.**0.5/2., 0], 
                       [ 0, 0, 1.0]])
     assert np.allclose(axes_check(axes), uaxes)
예제 #3
0
 def test_not_orthogonal(self):
     axes = np.array([[ 1, 1, 0], 
                      [ 1,-3, 0], 
                      [ 0, 0, 1]])
     with pytest.raises(ValueError):
         axes_check(axes)        
예제 #4
0
 def test_left_handed(self):
     axes = np.array([[ 1, 1, 0], 
                      [ 1,-1, 0], 
                      [ 0, 0, 1]])
     with pytest.raises(ValueError):
         axes_check(axes)
예제 #5
0
 def test_bad_shape(self):
     with pytest.raises(AssertionError):
         axes_check([[12,124], [124,62], [1234, 124]])
예제 #6
0
 def test_parallel(self):
     assert np.allclose(axes_check(5*np.eye(3)), np.eye(3))
예제 #7
0
파일: nye.py 프로젝트: lmhale99/atomman
def nye(system, p, neighbor_list=None, neighbor_list_cutoff=None, axes=None, tmax = 27):
    axes = system.prop('axes')
    nlist = system.prop('nlist')
    natoms = system.natoms()
    
    T,vmag = axes_check(axes)
    if len(p) == 1:
        p = p[0]
    else:
        raise ValueError('Multiple unique sites not supported yet')
    
    p = p.dot(np.transpose(T))
    
    #Change tmax=angle to tmax=cos(angle)
    tmax = np.cos(tmax * np.pi / 180)  
    iden = np.identity(3)
    eps = np.array([[[ 0, 0, 0],[ 0, 0, 1],[ 0,-1, 0]],
                    [[ 0, 0,-1],[ 0, 0, 0],[ 1, 0, 0]],
                    [[ 0, 1, 0],[-1, 0, 0],[ 0, 0, 0]]])
    
    #Set r1 to smallest interatomic distance from p
    r1 = 50.
    for pi in p:
        if r1 > mag(pi): r1 = mag(pi)
    
    #Identify largest number of nearest neighbors
    nmax = 0
    for ns in nlist:
        if ns[0] > nmax: nmax=ns[0]
    
    #Initialize variables (done here to reduce memory allocations making it slightly faster)
    q = np.zeros((nmax, 3))
    temp = [-1 for y in xrange(nmax)]
    P = np.zeros((nmax, 3))            
    Q = np.zeros((nmax, 3))
    G = [[] for y in xrange(natoms)]
    nye = np.zeros((3, 3))
    gradG = np.zeros((3, 3, 3))
    
    #Loop to calculate correspondence tensor, G, and strain data   
    for i in xrange(natoms):
        #Reset temp list used to identify p-q pairs
        for t in xrange(len(temp)):
            temp[t] = -1
        
        #Calculate radial neighbor vectors, q, and associate to perfect crystal vectors, p using theta.
        #Only match p-q if cos(angle) between them is largest and greater than tmax.
        for n in xrange(nlist[i][0]):
            j = nlist[i][n+1]
            q[n] = system.dvect(i, j)
            theta = tmax
            for s in xrange(len(p)):
                if (p[s].dot(q[n]) / (mag(p[s]) * mag(q[n])) > theta):
                    temp[n] = s
                    theta = p[s].dot(q[n]) / (mag(p[s]) * mag(q[n]))
                       
            #Check if the particular p has already been assigned to another q
            #Remove the p-q pair that is farther from r1
            if temp[n] >=0:
                for k in xrange(n):
                    if temp[n] == temp[k]:
                        nrad = abs(r1 - mag(q[n]))
                        krad = abs(r1 - mag(q[k]))
                        if nrad < krad:
                            temp[k]=-1
                        else:
                            temp[n]=-1

        #Construct reduced P, Q matrices from p-q pairs
        c = 0
        for n in xrange(nlist[i][0]):
            if temp[n] >= 0:
                Q[c] = q[n]
                P[c] = p[temp[n]]
                c+=1   
        #Compute lattice correspondence tensor, G, from P and Q
        if c == 0:
            G[i] = iden
            print i+1
            raise ValueError('An atom lacks pair sets. Check neighbor list')
        else:   
            G[i], resid, rank, s = np.linalg.lstsq(Q[:c], P[:c])
        
        #Compute strain properties
        strain = ((iden - G[i]) + (iden - G[i]).T) / 2.
        inv1 = strain[0,0] + strain[1,1] + strain[2,2]
        inv2 = (strain[0,0] * strain[1,1] + strain[0,0] * strain[2,2] + strain[1,1] * strain[2,2] 
                - strain[0,1]**2 - strain[0,2]**2 - strain[1,2]**2)
        rot = ((iden - G[i]) - (iden - G[i]).T) / 2.
        ang_vel = (rot[0,1]**2 + rot[0,2]**2 + rot[1,2]**2)**0.5
        
        system.atoms(i, 'strain', strain)
        system.atoms(i, 'strain_invariant_1', inv1)
        system.atoms(i, 'strain_invariant_2', inv2)
        system.atoms(i, 'angular_velocity', ang_vel)

    #Construct the gradient tensor of G, gradG
    for i in xrange(natoms):
        for x in xrange(3):
            for y in xrange(3):
                Q = np.zeros((nlist[i][0], 3))
                dG = np.zeros((nlist[i][0]))
                for n in xrange(nlist[i][0]):
                    j = nlist[i][n+1]
                    Q[n] = system.dvect(i, j)
                    dG[n] = G[j][x,y] - G[i][x,y]
                gradG[x, y], resid, rank, s = np.linalg.lstsq(Q, dG)  
        
        #Use gradG to build the nye tensor, nye
        for ij in xrange(3):
            nye[0,ij] = -gradG[2, ij, 1] + gradG[1, ij, 2]
            nye[1,ij] = -gradG[0, ij, 2] + gradG[2, ij, 0]
            nye[2,ij] = -gradG[1, ij, 0] + gradG[0, ij, 1]
                
        system.atoms(i, 'Nye', nye)
예제 #8
0
 def test_not_orthogonal(self):
     axes = np.array([[ 1, 1, 0], 
                      [ 1,-3, 0], 
                      [ 0, 0, 1]])
     with pytest.raises(ValueError):
         axes_check(axes)        
예제 #9
0
 def test_left_handed(self):
     axes = np.array([[ 1, 1, 0], 
                      [ 1,-1, 0], 
                      [ 0, 0, 1]])
     with pytest.raises(ValueError):
         axes_check(axes)
예제 #10
0
 def test_bad_shape(self):
     with pytest.raises(AssertionError):
         axes_check([[12,124], [124,62], [1234, 124]])
예제 #11
0
 def test_parallel(self):
     assert np.allclose(axes_check(5*np.eye(3)), np.eye(3))
예제 #12
0
파일: Stroh.py 프로젝트: lmhale99/atomman
    def solve(self, C, burgers, axes=None, tol=1e-8):
        """Performs the Stroh method to obtain solution terms p, A, L, and k.
        
        Required Arguments:
        C -- an instance of ElasticConstants.
        b -- a numpy array representing the Burgers vector.
        
        Keyword Arguments:
        axes -- rotational axes of the system. If given, then C and b will be 
                transformed.
        tol -- tolerance parameter used to round off near-zero values.
        """
        burgers = np.asarray(burgers, dtype='float64')
        if axes is not None:
            T = axes_check(axes)
            burgers = T.dot(burgers)
            C = C.transform(axes)
        Cijkl = C.Cijkl   
        
        m = np.array([1.0, 0.0, 0.0])
        n = np.array([0.0, 1.0, 0.0])
        
        #Matrixes of Cijkl constants used to construct N
        mm = np.einsum('i,ijkl,l', m, Cijkl, m)
        mn = np.einsum('i,ijkl,l', m, Cijkl, n)
        nm = np.einsum('i,ijkl,l', n, Cijkl, m)
        nn = np.einsum('i,ijkl,l', n, Cijkl, n)
        
        #The four 3x3 matrixes that represent the quadrants of N
        NB = -np.linalg.inv(nn)
        NA = NB.dot(nm)
        NC = mn.dot(NA) + mm
        ND = mn.dot(NB)
        
        #N is the 6x6 array, where the eigenvalues are the roots p
        #and the eigenvectors give A and L
        N =  np.array(np.vstack((np.hstack((NA, NB)), np.hstack((NC, ND)))))
        
        #Calculate the eigenvectors and eigenvalues
        eig = np.linalg.eig(N)
        p = eig[0]
        eigvec = np.transpose(eig[1])

        #separate the eigenvectors into A and L
        A = np.array([eigvec[0,:3], eigvec[1,:3], eigvec[2,:3], eigvec[3,:3], eigvec[4,:3], eigvec[5,:3]])
        L = np.array([eigvec[0,3:], eigvec[1,3:], eigvec[2,3:], eigvec[3,3:], eigvec[4,3:], eigvec[5,3:]])
        
        #calculate k
        k = 1. / (2. * np.einsum('si,si->s', A, L))
        
        #Calculation verification checks
        try:
            assert np.allclose(np.einsum('s,si,sj->ij', k,A,L), np.identity(3, dtype='complex128'), atol=tol)
            assert np.allclose(np.einsum('s,si,sj->ij', k,A,A), np.zeros((3,3), dtype='complex128'), atol=tol)
            assert np.allclose(np.einsum('s,si,sj->ij', k,L,L), np.zeros((3,3), dtype='complex128'), atol=tol)
            assert np.allclose(np.einsum('s,t,si,ti->st', k**.5,k**.5,A,L) + np.einsum('s,t,ti,si->st', k**.5,k**.5,A,L),
                                         np.identity(6, dtype='complex128'), atol = tol)
        except:
            raise ValueError('Stroh checks failed!')
    
        #assign property values
        self.__burgers = burgers
        self.__Cijkl = Cijkl
        self.__tol = tol
        self.__p = p
        self.__A = A
        self.__L = L
        self.__k = k
        self.__m = m
        self.__n = n