コード例 #1
0
ファイル: slip_vector.py プロジェクト: yfyh2013/atomman
def slip_vector(system_0,
                system_1,
                neighbor_list=None,
                neighbor_list_cutoff=None):
    """Compute the slip vectors for all atoms in system_1 relative to system_0."""

    assert system_0.natoms == system_1.natoms, 'systems have different number of atoms'

    #neighbor list setup
    if neighbor_list is not None:
        assert neighbor_list_cutoff is None, 'neighbor_list and neighbor_list_cutoff cannot both be given'
    elif neighbor_list_cutoff is not None:
        neighbor_list = am.nlist(system_0, neighbor_list_cutoff)
    elif 'neighbors' in system_0.prop:
        neighbor_list = system_0.prop['neighbors']
    elif 'nlist' in system_0.prop:
        neighbor_list = system_0.prop['nlist']

    if isinstance(neighbor_list, am.NeighborList):
        objectnlist = True
    else:
        objectnlist = False

    #Calculate the slip vector
    slip = np.zeros((system_0.natoms, 3))

    for i in xrange(system_0.natoms):
        if objectnlist:
            js = neighbor_list[i]
        else:
            js = neighbor_list[i, 1:neighbor_list[i, 0] + 1]
        slip[i] = -np.sum(system_1.dvect(i, js) - system_0.dvect(i, js),
                          axis=0)

    return slip
コード例 #2
0
ファイル: slip_vector.py プロジェクト: hlyang1992/atomman
def slip_vector(system_0, system_1, neighbor_list=None, neighbor_list_cutoff=None):
    """Compute the slip vectors for all atoms in system_1 relative to system_0."""

    assert system_0.natoms == system_1.natoms,  'systems have different number of atoms'

    #neighbor list setup
    if neighbor_list is not None:
        assert neighbor_list_cutoff is None, 'neighbor_list and neighbor_list_cutoff cannot both be given'
    elif neighbor_list_cutoff is not None:
        neighbor_list = am.nlist(system_0, neighbor_list_cutoff)
    elif 'neighbors' in system_0.prop:
        neighbor_list = system_0.prop['neighbors']
    elif 'nlist' in system_0.prop:
        neighbor_list = system_0.prop['nlist']
    
    if isinstance(neighbor_list, am.NeighborList):
        objectnlist = True
    else:
        objectnlist = False
    
    #Calculate the slip vector
    slip = np.zeros((system_0.natoms, 3))
    
    for i in xrange(system_0.natoms):
        if objectnlist:
            js = neighbor_list[i]
        else:
            js = neighbor_list[i, 1:neighbor_list[i, 0]+1]
        slip[i] = -np.sum(system_1.dvect(i, js) - system_0.dvect(i, js), axis=0)
            
    return slip
    
コード例 #3
0
ファイル: System.py プロジェクト: lmhale99/atomman
 def nlist(self, cutoff, cmult=1):
     """Build neighbor list for all atoms based on a cutoff.
     
     Keyword Arguments:
     cutoff -- radial cutoff distance for including atoms as neighbors.
     cmult -- int factor that changes the underlying binning algorithm. Default is 1, which should be the fastest. 
     """
     self.prop['nlist'] = am.nlist(self, cutoff, cmult)
コード例 #4
0
ファイル: System.py プロジェクト: yfyh2013/atomman
 def nlist(self, cutoff, cmult=1):
     """Build neighbor list for all atoms based on a cutoff.
     
     Keyword Arguments:
     cutoff -- radial cutoff distance for including atoms as neighbors.
     cmult -- int factor that changes the underlying binning algorithm. Default is 1, which should be the fastest. 
     """
     with warnings.catch_warnings():
         warnings.simplefilter('always')
         warnings.warn('nlist method is replaced with neighbors method', DeprecationWarning)
     self.prop['nlist'] = am.nlist(self, cutoff, cmult=cmult)
コード例 #5
0
ファイル: slip_vector.py プロジェクト: lmhale99/atomman
def slip_vector(system_0, system_1, neighbor_list=None, neighbor_list_cutoff=None):
    """Compute the slip vectors for all atoms in system_1 relative to system_0."""

    assert system_0.natoms == system_1.natoms, "systems have different number of atoms"

    # neighbor list setup
    if neighbor_list is not None:
        assert neighbor_list_cutoff is None, "neighbor_list and neighbor_list_cutoff cannot both be given"
    elif neighbor_list_cutoff is not None:
        neighbor_list = am.nlist(system_0, neighbor_list_cutoff)
    elif "nlist" in system_0.prop:
        neighbor_list = system_0.prop["nlist"]

    # Calculate the slip vector
    slip = np.zeros((system_0.natoms, 3))

    for i in xrange(system_0.natoms):
        js = neighbor_list[i, 1 : neighbor_list[i, 0] + 1]
        slip[i] = -np.sum(system_1.dvect(i, js) - system_0.dvect(i, js), axis=0)

    return slip
コード例 #6
0
def differential_displacement(base_system, disl_system, burgers_vector, plot_range, 
       neighbor_list = None, neighbor_list_cutoff = None, component = 'standard',
       axes = None, plot_scale = 1, save_file = None, show = True):
    """
    Function for generating a differential displacement plot for a 
    dislocation containing system.
    
    Arguments:
    base_system -- atomman.System defect-free reference system corresponding 
                   to disl_system.
    disl_system -- atomman.System system containing the defect.
    burgers_vector -- 3x1 numpy array for the dislocation's Burgers vector.
    plot_range -- 3x3 numpy array specifying the Cartesian space to include 
                  atoms in the plot.
    
    Optional Keyword Arguments:
    neighbor_list -- pre-computed neighbor list for base_system.
    neighbor_list_cutoff -- cutoff for computing a neighbor list for 
                            base_system.
    component -- indicates the style of the calculation to use.
    axes -- 3x3 numpy array indicating the crystallographic 
                             axes corresponding to the box's Cartesian axes. 
                             If given, only used for transforming the 
                             burgers_vector.
    plot_scale -- scalar for multiplying the magnitude of the differential 
                  displacement arrows.
    save_file -- if given then the plot will be saved to a file with this name.
    show -- Boolean flag for showing the figure. Default is True.  
    """
    #Burgers vector setup
    if axes is not None:
        T = am.tools.axes_check(axes)
        burgers_vector = T.dot(burgers_vector)
    burgers_vector_magnitude = np.linalg.norm(burgers_vector)
    burgers_vector_uvect = burgers_vector / burgers_vector_magnitude    
    
    #neighbor list setup
    if neighbor_list is not None:
        assert neighbor_list_cutoff is None, 'neighbor_list and neighbor_list_cutoff cannot both be given'
    elif neighbor_list_cutoff is not None:
        neighbor_list = am.nlist(base_system, neighbor_list_cutoff)
    elif 'nlist' in base_system.prop:
        neighbor_list = base_system.prop['nlist']
    
    #Identify atoms in plot range
    base_pos = base_system.atoms_prop(key='pos')
    plot_range_indices = np.where((base_pos[:, 0] > plot_range[0,0]) & (base_pos[:, 0] < plot_range[0,1]) & 
                                  (base_pos[:, 1] > plot_range[1,0]) & (base_pos[:, 1] < plot_range[1,1]) &
                                  (base_pos[:, 2] > plot_range[2,0]) & (base_pos[:, 2] < plot_range[2,1]))[0]
    
    #initial plot setup and parameters
    fig, ax1, = plt.subplots(1, 1, squeeze=True, figsize=(7,7), dpi=72)
    ax1.axis([plot_range[0,0], plot_range[0,1], plot_range[1,0], plot_range[1,1]])
    atom_circle_radius = burgers_vector_magnitude / 10
    arrow_width_scale = 1. / 200.

    #Loop over all atoms i in plot range
    for i in plot_range_indices:

        #Plot a circle for atom i
        color = cm.hsv((base_pos[i, 2] - plot_range[2,0]) / (plot_range[2,1] - plot_range[2,0]))
        ax1.add_patch(mpatches.Circle(base_pos[i, :2], atom_circle_radius, fc=color))
    
        #make list of all neighbors for atom i
        neighbor_indices = neighbor_list[i, 1 : neighbor_list[i, 0] + 1]

        #Compute distance vectors between atom i and its neighbors for both systems        
        base_dvectors = base_system.dvect(int(i), neighbor_indices)
        disl_dvectors = disl_system.dvect(int(i), neighbor_indices)
    
        #Compute differential displacement vectors
        dd_vectors = disl_dvectors - base_dvectors
        
        #Compute centerpoint positions for the vectors
        arrow_centers = base_pos[i] + base_dvectors / 2
        
        if component == 'standard':
            #compute unit distance vectors
            base_uvectors = base_dvectors / np.linalg.norm(base_dvectors, axis=1)[:,np.newaxis]

            #compute component of the dd_vector parallel to the burgers vector
            dd_components = dd_vectors.dot(burgers_vector_uvect)        
            dd_components[dd_components > burgers_vector_magnitude / 2] -= burgers_vector_magnitude
            dd_components[dd_components < -burgers_vector_magnitude / 2] += burgers_vector_magnitude
            
            #scale arrow lengths and vectors
            arrow_lengths = base_uvectors * dd_components[:,np.newaxis] * plot_scale
            arrow_widths = arrow_width_scale * dd_components * plot_scale
        
            #plot the arrows
            for center, length, width in zip(arrow_centers, arrow_lengths, arrow_widths):
                if width > 1e-7:
                    ax1.quiver(center[0], center[1], length[0], length[1], pivot='middle',
                               angles='xy', scale_units='xy', scale=1, width=width)
                
        elif component == 'xy':
            #scale arrow lengths and vectors
            arrow_lengths = dd_vectors[:, :2] * plot_scale
            arrow_lengths[dd_vectors[:, 2] > 0] *= -1
            arrow_widths = arrow_width_scale * (arrow_lengths[:,0]**2+arrow_lengths[:,1]**2)**0.5

            #plot the arrows
            for center, length, width in zip(arrow_centers, arrow_lengths, arrow_widths):
                if width > 1e-7:
                    ax1.quiver(center[0], center[1], length[0], length[1], width=width,
                               pivot='middle', angles='xy', scale_units='xy', scale=1)

    if save_file is not None:
        plt.savefig(save_file, dpi=800)
    if show == False:
        plt.close(fig)
    plt.show()        
コード例 #7
0
ファイル: nye_tensor.py プロジェクト: lmhale99/atomman
def nye_tensor(system, p_vectors, theta_max = 27, axes=None, neighbor_list=None, neighbor_list_cutoff=None):
    """Computes strain properties and Nye tensor for a defect containing system."""

    #neighbor list setup
    if neighbor_list is not None:
        assert neighbor_list_cutoff is None, 'neighbor_list and neighbor_list_cutoff cannot both be given'
    elif neighbor_list_cutoff is not None:
        neighbor_list = am.nlist(system, neighbor_list_cutoff)
    elif 'nlist' in system.prop:
        neighbor_list = system.prop['nlist']
    
    #If p_vectors is only given for one atom, apply to all atoms
    if len(p_vectors) == 1:
        p_vectors = np.broadcast_to(p_vectors, (system.natoms, len(p_vectors[0]), 3))
    elif len(p_vectors) != system.natoms:
        p_vectors = np.broadcast_to(p_vectors, (system.natoms, len(p_vectors), 3))        
    
    #If axes are given, transform p accordingly
    if axes is not None:
        p_vectors = np.inner(p_vectors, am.tools.axes_check(axes))
        
    #get cos of theta_max
    cos_theta_max = np.cos(theta_max * np.pi / 180)  
    
    #Define identity and epsilon arrays   
    #iden = 
    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]]])
    
    #Identify largest number of nearest neighbors
    nmax = 0
    for ns in neighbor_list:
        if ns[0] > nmax: nmax=ns[0]
    
    #Initialize variables (done here to reduce memory allocations making it slightly faster)
    strain = np.empty((system.natoms, 3, 3))
    inv1 = np.empty(system.natoms)
    inv2 = np.empty(system.natoms)
    ang_vel = np.empty(system.natoms)
    nye = np.empty((system.natoms, 3, 3))
    P = np.zeros((nmax, 3))            
    Q = np.zeros((nmax, 3))
    G = np.empty((system.natoms, 3, 3))
    gradG = np.empty((3, 3, 3))
    
    #Loop to calculate correspondence tensor, G, and strain data   
    for i in xrange(system.natoms):
        p = np.asarray(p_vectors[i])
        if p.ndim == 1:
            p = np.array([p])
        p_mags = np.linalg.norm(p, axis=1)
        r1 = p_mags.min()
        
        #Calculate radial neighbor vectors, q
        q = system.dvect(i, neighbor_list[i][1:neighbor_list[i][0]+1])
        if q.ndim == 1:
            q = np.array([q])
        q_mags = np.linalg.norm(q, axis=1)
        
        #Calculate cos_thetas between all p's and q's.
        cos_thetas = (np.dot(p, q.T) /q_mags ).T / p_mags
        
        #Identify best index matches 
        index_pairing = cos_thetas.argmax(1)
        
        #Exclude values where theta is greater than theta_max
        index_pairing[cos_thetas.max(1) < cos_theta_max] = -1
        
        #Search for duplicate index_pairings
        u, u_count = np.unique(index_pairing, return_counts=True)
        for match in u[(u!=-1) & (u_count > 1)]:
            print index_pairing==match
        
        for n in xrange(neighbor_list[i][0]):               
            #Check if the particular p has already been assigned to another q
            #Remove the p-q pair that is farther from r1
            if index_pairing[n] >=0:
                for k in xrange(n):
                    if index_pairing[n] == index_pairing[k]:
                        nrad = abs(r1 - q_mags[n])
                        krad = abs(r1 - q_mags[k])
                        if nrad < krad:
                            index_pairing[k]=-1
                        else:
                            index_pairing[n]=-1

        #Construct reduced P, Q matrices from p-q pairs
        c = 0
        for n in xrange(neighbor_list[i][0]):
            if index_pairing[n] >= 0:
                Q[c] = q[n]
                P[c] = p[index_pairing[n]]
                c+=1   
        #Compute lattice correspondence tensor, G, from P and Q
        if c == 0:
            G[i] = np.identity(3)
            warnings.warn('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[i] = ((np.identity(3) - G[i]) + (np.identity(3) - G[i]).T) / 2.
        inv1[i] = strain[i,0,0] + strain[i,1,1] + strain[i,2,2]
        inv2[i] = (strain[i,0,0] * strain[i,1,1] + strain[i,0,0] * strain[i,2,2] + strain[i,1,1] * strain[i,2,2] 
                - strain[i,0,1]**2 - strain[i,0,2]**2 - strain[i,1,2]**2)
        rot = ((np.identity(3) - G[i]) - (np.identity(3) - G[i]).T) / 2.
        ang_vel[i] = (rot[0,1]**2 + rot[0,2]**2 + rot[1,2]**2)**0.5

    #Construct the gradient tensor of G, gradG
    for i in xrange(system.natoms):
        neighbors = neighbor_list[i][1:neighbor_list[i][0]+1]
        Q = system.dvect(i, neighbors)
        if Q.ndim == 1:
            Q = np.array([Q])
        dG = G[neighbors] - G[i]        
        for x in xrange(3):
            gradG[x,:] = np.linalg.lstsq(Q, dG[:,x,:])[0].T
        
        #Use gradG to build the nye tensor, nye
        nye[i] = -np.einsum('ijm,ikm->jk', eps, gradG) 
    
    return {'strain':strain, 'strain_invariant_1':inv1, 'strain_invariant_2':inv2, 'angular_velocity':ang_vel, 'Nye_tensor':nye}