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
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
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
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