예제 #1
0
def chiral_nanotube(n, m, R=1.42, element='C'):
    """
    Construct a nanotube with a chiral container.
    
    parameters:
    ===========
    n,m:     chiral indices
    R:       bond length
    element: element type 
    """
    from hotbit import Atoms
    a = np.sqrt(3) * R
    a1 = np.array([a, 0, 0])
    a2 = np.array([0.5 * a, -1.5 * R, 0])

    rl = []
    shift = (a / 2, -0.5 * R, 0)
    for i in range(n):
        origin = i * a1
        rl.append(origin)
        rl.append(origin + shift)

    for j in range(m):
        origin = (n - 1) * a1 + (j + 1) * a1
        rl.append(origin)
        rl.append(origin + shift)

    atoms = Atoms()
    C = n * a1 + m * a2
    Cn = np.linalg.norm(C)
    T = np.array([C[1], -C[0], 0])
    t = T / np.linalg.norm(T)
    radius = Cn / (2 * pi)

    atoms = Atoms()
    for r in rl:
        phi = np.dot(r, C) / Cn**2 * 2 * pi
        atoms += Atom(
            element,
            (radius * np.cos(phi), radius * np.sin(phi), np.dot(r, t)))

    atoms = Atoms(atoms, container='Chiral')
    height = np.abs(np.dot(a1 - a2, t))
    angle = -np.dot(a1 - a2, C) / Cn**2 * 2 * pi
    atoms.set_container(angle=angle, height=height)

    data = nanotube_data(n, m, R)
    T, Ntot = data['T'], 2 * data['hexagons_per_cell']
    data['height'] = height
    data['twist'] = angle
    atoms.data = data
    return atoms
예제 #2
0
def chiral_nanotube(n,m,R=1.42,element='C'):
    """
    Construct a nanotube with a chiral container.
    
    parameters:
    ===========
    n,m:     chiral indices
    R:       bond length
    element: element type 
    """
    from hotbit import Atoms
    a = np.sqrt(3)*R
    a1 = np.array([a,0,0])
    a2 = np.array([0.5*a,-1.5*R,0])
    
    rl = []
    shift = (a/2,-0.5*R,0)
    for i in range(n):
        origin = i*a1
        rl.append( origin )
        rl.append( origin+shift )
          
    for j in range(m):
        origin = (n-1)*a1 + (j+1)*a1
        rl.append( origin )
        rl.append( origin + shift )
        
    atoms = Atoms()
    C = n*a1 + m*a2
    Cn = np.linalg.norm(C)
    T = np.array([C[1],-C[0],0])
    t = T/np.linalg.norm(T)
    radius = Cn/(2*pi)
    
    atoms = Atoms()
    for r in rl:
        phi = np.dot(r,C)/Cn**2 * 2*pi
        atoms += Atom( element,(radius*np.cos(phi),radius*np.sin(phi),np.dot(r,t)) )
    
    atoms = Atoms(atoms,container='Chiral')
    height = np.abs( np.dot(a1-a2,t) )
    angle = -np.dot(a1-a2,C)/Cn**2 * 2*pi
    atoms.set_container(angle=angle,height=height) 
    
    data = nanotube_data(n,m,R)
    T, Ntot = data['T'],2*data['hexagons_per_cell']
    data['height']=height
    data['twist']=angle
    atoms.data = data
    return atoms
예제 #3
0
def setup_bending(atoms, angle, radius, rotation=0.0, physical=True):
    """
    Prepare a bending setup for a tube or slab.
    
    Tube should be originally periodic in z-direction with
    the correct cell, and optionally periodic in y-direction.
    
    Then atoms are set up for bending with hotbit.Wedge class
    with bending wrt. z-axis, and optionally periodic along
    z-axis.
    
    Atoms are first rotated pi/2 around -x-axis, then
    rotated an angle 'rotation' around y-axis, then
    transformed the distance 'radius' towards x-axis.
    The atoms are further adjusted for the wedge angle 'angle'.
    'physical' tells if the angle should be 2*pi/integer.
    """
    a = atoms.copy()
    a.rotate('-x', np.pi / 2)
    L = a.get_cell().diagonal()
    if abs(L.prod() - a.get_volume()) > 1E-10:
        raise AssertionError('Cell should be orthorhombic.')
    pbc = a.get_pbc()
    if not pbc[2] or pbc[0]:
        raise AssertionError(
            'Should be periodic in z-direction and not periodic in x-direction'
        )
    r = a.get_positions()
    if np.any(r[:, 1] < 0):  # index 1 is correct here
        raise AssertionError('For bending, all atoms should be above xy-plane')

    # move and adjust
    a.rotate('y', rotation)
    for i in range(len(a)):
        x, y = r[i, 0:2]
        R = x + radius
        phi = y * angle / L[2]
        r[i, 0] = R * np.cos(phi)
        r[i, 1] = R * np.sin(phi)
    a.set_positions(r)
    a = Atoms(a, container='Wedge')
    a.set_container(angle=angle, height=L[1], pbcz=pbc[1], physical=physical)
    return a
예제 #4
0
def setup_bending(atoms,angle,radius,rotation=0.0,physical=True):
    """
    Prepare a bending setup for a tube or slab.
    
    Tube should be originally periodic in z-direction with
    the correct cell, and optionally periodic in y-direction.
    
    Then atoms are set up for bending with hotbit.Wedge class
    with bending wrt. z-axis, and optionally periodic along
    z-axis.
    
    Atoms are first rotated pi/2 around -x-axis, then
    rotated an angle 'rotation' around y-axis, then
    transformed the distance 'radius' towards x-axis.
    The atoms are further adjusted for the wedge angle 'angle'.
    'physical' tells if the angle should be 2*pi/integer.
    """
    a = atoms.copy()
    a.rotate('-x',np.pi/2)
    L = a.get_cell().diagonal()
    if abs(L.prod()-a.get_volume())>1E-10:
        raise AssertionError('Cell should be orthorhombic.')
    pbc = a.get_pbc()
    if not pbc[2] or pbc[0]:
        raise AssertionError('Should be periodic in z-direction and not periodic in x-direction')
    r = a.get_positions()    
    if np.any( r[:,1]<0 ): # index 1 is correct here 
        raise AssertionError('For bending, all atoms should be above xy-plane')
    
    # move and adjust
    a.rotate('y',rotation)
    for i in range(len(a)):
        x,y = r[i,0:2]
        R = x + radius
        phi = y*angle/L[2]
        r[i,0] = R*np.cos(phi)
        r[i,1] = R*np.sin(phi)
    a.set_positions(r)
    a = Atoms(a,container='Wedge')
    a.set_container(angle=angle,height=L[1],pbcz=pbc[1],physical=physical)
    return a