Exemplo n.º 1
0
    def extended_copy(self,n):
        """ Get copies of atoms for all listed symmetry operations n.

        @param: n  i) list of 3-tuples for transformations explicitly
                      e.g. [(0,0,0),(1,0,0),(0,1,0)]
                   ii) 3-tuple for the number of transformations
                       (for infinite extensions -> start from zero;
                        for finite extensions -> symmetry ops around zero)
                       e.g. (10,10,1)
                   iii) 3-tuple of 2-tuples that give the ranges for symmetry ops
                       e.g. ((-3,3),(-3,3),1)

        Return normal ase.Atoms -instance.
        """
        r = self.container.get_symmetry_operation_ranges()
        if isinstance(n,list):
            n_list = copy(n)
        elif isinstance(n,tuple):
            ops = []
            for i in range(3):
                if isinstance(n[i],tuple):
                    ops.append( np.arange(n[i][0],n[i][1]+1) )
                elif isinstance(n[i],int):
                    assert n[i]>0
                    if r[i,0]==-np.Inf:
                        # this symmetry operation has the full range
                        rng = np.arange(0,n[i])
                    else:
                        # take copies around the 0-operation
                        start = max(r[i,0],-n[i]//2)
                        rng = np.arange(start,start+n[i])
                    ops.append( rng )


            n_list=[]
            for n1 in ops[0]:
                for n2 in ops[1]:
                    for n3 in ops[2]:
                        n_list.append( (n1,n2,n3) )

        atoms2=None
        for n in n_list:
            self._check_symmetry_operation(n)
            atomsn = ase_Atoms()
            atomsn += self
            atomsn.set_positions( np.array([self.transform(r,n) for r in self.get_positions()]) )
            try:
                atoms2 += atomsn
            except:
                atoms2 = atomsn

        atoms2.set_pbc(False)
        atoms2.set_cell((1,1,1))
        return atoms2
Exemplo n.º 2
0
 def extended_copy(self,n):
     """ Get copies of atoms for all listed symmetry operations n.
     
     @param: n  i) list of 3-tuples for transformations explicitly
                   e.g. [(0,0,0),(1,0,0),(0,1,0)]
                ii) 3-tuple for the number of transformations 
                    (for infinite extensions -> start from zero;
                     for finite extensions -> symmetry ops around zero)
                    e.g. (10,10,1)
                iii) 3-tuple of 2-tuples that give the ranges for symmetry ops 
                    e.g. ((-3,3),(-3,3),1)
     
     Return normal ase.Atoms -instance.
     """ 
     r = self.container.get_symmetry_operation_ranges()
     if isinstance(n,list):
         n_list = copy(n)
     elif isinstance(n,tuple):
         ops = []
         for i in range(3):
             if isinstance(n[i],tuple):
                 ops.append( np.arange(n[i][0],n[i][1]+1) )
             elif isinstance(n[i],int):
                 assert n[i]>0
                 if r[i,0]==-np.Inf:
                     # this symmetry operation has the full range
                     rng = np.arange(0,n[i])
                 else:
                     # take copies around the 0-operation
                     start = max(r[i,0],-n[i]/2)
                     rng = np.arange(start,start+n[i])
                 ops.append( rng )
             
                         
         n_list=[]
         for n1 in ops[0]:
             for n2 in ops[1]:
                 for n3 in ops[2]:
                     n_list.append( (n1,n2,n3) )
     
     atoms2=None
     for n in n_list:
         self._check_symmetry_operation(n)
         atomsn = ase_Atoms()
         atomsn += self
         atomsn.set_positions( np.array([self.transform(r,n) for r in self.get_positions()]) )
         try:
             atoms2 += atomsn
         except:
             atoms2 = atomsn
             
     atoms2.set_pbc(False)
     atoms2.set_cell((1,1,1))
     return atoms2       
Exemplo n.º 3
0
def armchair_ribbon(n1, n2, R, pbc='z'):
    """
    Make ribbon out of graphene with armchair edges: n1 armchair periods in x-direction
    and n2 stacked armchairs.
    
    parameters:
    ===========
    n1:    length (units in periodic direction)
    n2:    width
    R:     bond distance
    pbc:   periodic direction ('z' or 'x')
    """
    from hotbit import Atoms
    a1 = vec([3 * R, 0, 0])
    a2 = vec([0, 2 * R * np.cos(pi / 6), 0])
    atoms = ase_Atoms()
    r = []
    for i1 in range(n1):
        for i2 in range(n2):
            corner = i1 * a1 + i2 * a2
            atoms += Atom('C', corner)
            atoms += Atom('C', corner + vec([R, 0, 0]))
            atoms += Atom('C', corner + vec([1.5 * R, R * np.cos(pi / 6), 0]))
            atoms += Atom('C', corner + vec([2.5 * R, R * np.cos(pi / 6), 0]))

    if pbc == 'x':
        atoms.set_cell([n1 * 3 * R, n2 * 2 * R * np.cos(pi / 6), 1])
        atoms.center(vacuum=5, axis=2)
        atoms.center(vacuum=5, axis=1)
        atoms.set_pbc((True, False, False))
        return atoms
    elif pbc == 'z':
        atoms.translate(-atoms.get_center_of_mass())
        atoms.rotate('z', np.pi / 2)
        atoms.rotate('x', np.pi / 2)
        atoms.center(vacuum=5, axis=1)
        atoms.translate(-atoms.get_center_of_mass())
        zmin = atoms.get_positions()[:, 2].min()
        atoms.translate((0, 0, -zmin))
        atoms.set_cell([n2 * 2 * R * np.cos(pi / 6), 1, n1 * 3 * R])
        atoms.set_pbc((False, False, True))
        return atoms
    else:
        raise NotImplementedError('pbc only along x or z')
Exemplo n.º 4
0
def armchair_ribbon(n1,n2,R,pbc='z'):
    """
    Make ribbon out of graphene with armchair edges: n1 armchair periods in x-direction
    and n2 stacked armchairs.
    
    parameters:
    ===========
    n1:    length (units in periodic direction)
    n2:    width
    R:     bond distance
    pbc:   periodic direction ('z' or 'x')
    """
    from hotbit import Atoms
    a1=vec([3*R,0,0])
    a2=vec([0,2*R*np.cos(pi/6),0])
    atoms=ase_Atoms()
    r=[]
    for i1 in range(n1):
        for i2 in range(n2):
            corner=i1*a1+i2*a2
            atoms += Atom('C',corner)
            atoms += Atom('C',corner+vec([R,0,0]))
            atoms += Atom('C',corner+vec([1.5*R,R*np.cos(pi/6),0]))
            atoms += Atom('C',corner+vec([2.5*R,R*np.cos(pi/6),0]))

    if pbc=='x':
        atoms.set_cell( [n1*3*R,n2*2*R*np.cos(pi/6),1] )
        atoms.center(vacuum=5,axis=2)
        atoms.center(vacuum=5,axis=1)
        atoms.set_pbc((True,False,False))
        return atoms
    elif pbc=='z':
        atoms.translate( -atoms.get_center_of_mass() )
        atoms.rotate('z',np.pi/2)
        atoms.rotate('x',np.pi/2)
        atoms.center(vacuum=5,axis=1)
        atoms.translate( -atoms.get_center_of_mass() )
        zmin = atoms.get_positions()[:,2].min()
        atoms.translate( (0,0,-zmin) ) 
        atoms.set_cell( [n2*2*R*np.cos(pi/6),1,n1*3*R] )
        atoms.set_pbc((False,False,True))
        return atoms
    else:
        raise NotImplementedError('pbc only along x or z')
Exemplo n.º 5
0
def ZGNR(n, units=1, pbc='z', R=1.42):
    """
    Make an n-zigzag graphene nanoribbon.
    
    parameters:
    ===========
    n:      ribbon width (atomic rows)
    length: ribbon length (unit cells)
    pbc:    periodic direction, 'x' or 'z'
    R:      bond length 
    """
    from hotbit import Atoms
    a0 = R * np.sqrt(3)
    atoms = ase_Atoms()
    for i in range(n):
        x = 1
        if np.mod(i, 2) == 1:
            x = -1
        atoms += Atom('C', (0, 3 * R * i / 2 + 3 * R / 4 - x * R / 4, 0))
        atoms += Atom('C', (a0 / 2, 3 * R * i / 2 + 3 * R / 4 + x * R / 4, 0))

    a = atoms.copy()
    for i in range(units - 1):
        b = a.copy()
        b.translate(((i + 1) * a0, 0, 0))
        atoms += b
    if pbc == 'x':
        atoms.set_pbc((True, False, False))
        atoms.set_cell((units * a0, 1, 1))
        atoms.center(vacuum=6, axis=1)
        atoms.center(vacuum=6, axis=2)
    elif pbc == 'z':
        atoms.set_pbc((False, False, True))
        atoms.rotate('z', np.pi / 2)
        atoms.rotate('x', np.pi / 2)
        atoms.set_cell((n * 3 * R / 2 * 1.2 / 2, 1, units * a0))
        atoms.translate(-atoms.get_center_of_mass())
        atoms.center(axis=2)
    return atoms
Exemplo n.º 6
0
def ZGNR(n,units=1,pbc='z',R=1.42):
    """
    Make an n-zigzag graphene nanoribbon.
    
    parameters:
    ===========
    n:      ribbon width (atomic rows)
    length: ribbon length (unit cells)
    pbc:    periodic direction, 'x' or 'z'
    R:      bond length 
    """
    from hotbit import Atoms
    a0 = R*np.sqrt(3)
    atoms = ase_Atoms()
    for i in range(n):
        x = 1        
        if np.mod(i,2)==1:
            x=-1
        atoms += Atom('C',(0,3*R*i/2+3*R/4-x*R/4,0))
        atoms += Atom('C',(a0/2,3*R*i/2+3*R/4+x*R/4,0))
    
    a = atoms.copy()
    for i in range(units-1):
        b = a.copy()
        b.translate(((i+1)*a0,0,0))
        atoms += b
    if pbc=='x':
        atoms.set_pbc((True,False,False))
        atoms.set_cell((units*a0,1,1))
        atoms.center(vacuum=6,axis=1)
        atoms.center(vacuum=6,axis=2)
    elif pbc=='z':
        atoms.set_pbc((False,False,True))
        atoms.rotate('z',np.pi/2)
        atoms.rotate('x',np.pi/2)
        atoms.set_cell((n*3*R/2*1.2/2,1,units*a0))
        atoms.translate( -atoms.get_center_of_mass() )
        atoms.center(axis=2)
    return atoms
Exemplo n.º 7
0
def AGNR(n, units=1, pbc='z', R=1.42):
    """
    Make an n-armchair graphene nanoribbon.
    
    parameters:
    ===========
    n:      ribbon width (atomic rows)
    length: ribbon length (unit cells)
    pbc:    periodic direction, 'x' or 'z'
    R:      bond length 
    """
    from hotbit import Atoms
    a = R * np.sqrt(3)
    atoms = ase_Atoms()
    for i in range(n):
        x0 = 0.0
        if np.mod(i, 2) == 1:
            x0 = 1.5 * R
        atoms += Atom('C', (x0 + 0, i * a / 2, 0))
        atoms += Atom('C', (x0 + R, i * a / 2, 0))

    a = atoms.copy()
    for i in range(units - 1):
        b = a.copy()
        b.translate(((i + 1) * 3 * R, 0, 0))
        atoms += b
    if pbc == 'x':
        atoms.set_pbc((True, False, False))
        atoms.set_cell((units * 3 * R, 1, 1))
        atoms.center(vacuum=6, axis=1)
        atoms.center(vacuum=6, axis=2)
    elif pbc == 'z':
        atoms.set_pbc((False, False, True))
        atoms.rotate('z', np.pi / 2)
        atoms.rotate('x', np.pi / 2)
        atoms.set_cell((1, 1, units * 3 * R))
        atoms.translate(-atoms.get_center_of_mass())
    return atoms
Exemplo n.º 8
0
def AGNR(n,units=1,pbc='z',R=1.42):
    """
    Make an n-armchair graphene nanoribbon.
    
    parameters:
    ===========
    n:      ribbon width (atomic rows)
    length: ribbon length (unit cells)
    pbc:    periodic direction, 'x' or 'z'
    R:      bond length 
    """
    from hotbit import Atoms
    a = R*np.sqrt(3)
    atoms = ase_Atoms()
    for i in range(n):
        x0 = 0.0
        if np.mod(i,2)==1:
            x0 = 1.5*R
        atoms += Atom('C',(x0+0,i*a/2,0))
        atoms += Atom('C',(x0+R,i*a/2,0))
        
    a = atoms.copy()
    for i in range(units-1):
        b = a.copy()
        b.translate(((i+1)*3*R,0,0))
        atoms += b
    if pbc=='x':
        atoms.set_pbc((True,False,False))
        atoms.set_cell((units*3*R,1,1))
        atoms.center(vacuum=6,axis=1)
        atoms.center(vacuum=6,axis=2)
    elif pbc=='z':
        atoms.set_pbc((False,False,True))
        atoms.rotate('z',np.pi/2)
        atoms.rotate('x',np.pi/2)
        atoms.set_cell((1,1,units*3*R))
        atoms.translate( -atoms.get_center_of_mass() )
    return atoms
Exemplo n.º 9
0
def zigzag_ribbon(n1, n2, R, pbc='z'):
    """
    Make ribbon out of graphene with zigzag edges.
    """
    from hotbit import Atoms
    a1 = vec([2 * R * np.cos(pi / 6), 0, 0])
    a2 = vec([0, 3 * R, 0])
    r = []
    for i1 in range(n1):
        for i2 in range(n2):
            corner = i1 * a1 + i2 * a2
            r.append(corner + vec([R * np.cos(pi / 6), R / 2, 0]))
            r.append(corner + vec([0, R, 0]))
            r.append(corner + vec([0, 2 * R, 0]))
            r.append(corner + vec([R * np.cos(pi / 6), 2.5 * R, 0]))
    cell = [n1 * 2 * R * np.cos(pi / 6), n2 * 3 * R, 1]
    elements = ['C'] * len(r)
    atoms = ase_Atoms(elements, r, cell=cell)
    if pbc == 'x':
        atoms.set_cell([2 * R * np.cos(pi / 6), n1 * 3 * R, 1])
        atoms.center(vacuum=5, axis=2)
        atoms.center(vacuum=5, axis=1)
        atoms.set_pbc((True, False, False))
        return atoms
    elif pbc == 'z':
        atoms.translate(-atoms.get_center_of_mass())
        atoms.rotate('z', np.pi / 2)
        atoms.rotate('x', np.pi / 2)
        atoms.center(vacuum=5, axis=1)
        atoms.translate(-atoms.get_center_of_mass())
        zmin = atoms.get_positions()[:, 2].min()
        atoms.translate((0, 0, -zmin))
        atoms.set_cell([n2 * 2 * R * np.cos(pi / 6), 1, n1 * 3 * R])
        atoms.set_pbc((False, False, True))
        return atoms
    else:
        raise NotImplementedError('pbc only along x or z')
Exemplo n.º 10
0
def zigzag_ribbon(n1,n2,R,pbc='z'):
    """
    Make ribbon out of graphene with zigzag edges.
    """
    from hotbit import Atoms
    a1=vec([2*R*np.cos(pi/6),0,0])
    a2=vec([0,3*R,0])
    r=[]
    for i1 in range(n1):
        for i2 in range(n2):
            corner=i1*a1+i2*a2
            r.append(corner+vec([R*np.cos(pi/6),R/2,0]))
            r.append(corner+vec([0,R,0]))
            r.append(corner+vec([0,2*R,0]))
            r.append(corner+vec([R*np.cos(pi/6),2.5*R,0]))
    cell=[n1*2*R*np.cos(pi/6),n2*3*R,1]   
    elements=['C']*len(r)         
    atoms = ase_Atoms(elements,r,cell=cell)      
    if pbc=='x':
        atoms.set_cell( [2*R*np.cos(pi/6),n1*3*R,1] )
        atoms.center(vacuum=5,axis=2)
        atoms.center(vacuum=5,axis=1)
        atoms.set_pbc((True,False,False))
        return atoms
    elif pbc=='z':
        atoms.translate( -atoms.get_center_of_mass() )
        atoms.rotate('z',np.pi/2)
        atoms.rotate('x',np.pi/2)
        atoms.center(vacuum=5,axis=1)
        atoms.translate( -atoms.get_center_of_mass() )
        zmin = atoms.get_positions()[:,2].min()
        atoms.translate( (0,0,-zmin) ) 
        atoms.set_cell( [n2*2*R*np.cos(pi/6),1,n1*3*R] )
        atoms.set_pbc((False,False,True))
        return atoms
    else:
        raise NotImplementedError('pbc only along x or z')
Exemplo n.º 11
0
from hotbit.atoms import Atoms
from box.md import check_energy_conservation
from hotbit.test.misc import default_param


# check that C1H1-presentation of C6H6 goes right
SCC=True
cut=3.0
atoms = Atoms('CH',[(1.42,0,0),(2.0,1.0,0.2)],container='Wedge')
atoms.set_container(M=6,height=10)

calc = Hotbit(SCC=SCC,txt='tmp.cal',kpts=(6,1,1),gamma_cut=cut,**default_param)
atoms.set_calculator(calc)
e1 = atoms.get_potential_energy()

atoms6 = ase_Atoms(pbc=False)
atoms6 += atoms.extended_copy([(i-2,0,0) for i in range(6)])
#view(atoms)
calc = Hotbit(SCC=SCC,txt='tmp.cal',gamma_cut=cut,**default_param)
atoms6.set_calculator(calc)
e6 = atoms6.get_potential_energy()

assert abs(6*e1-e6)<1E-5


#
# energy conservation
#
atoms = Atoms('CH',[(1.42,0,0),(2.0,0.5,0.3)],container='Wedge')
atoms.set_container(M=6,height=10)
calc = Hotbit(SCC=SCC,txt='tmp.cal',kpts=(6,1,1),gamma_cut=cut,**default_param)
Exemplo n.º 12
0
# check that C1H1-presentation of C6H6 goes right
SCC = True
cut = 3.0
atoms = Atoms('CH', [(1.42, 0, 0), (2.0, 1.0, 0.2)], container='Wedge')
atoms.set_container(M=6, height=10)

calc = Hotbit(SCC=SCC,
              txt='tmp.cal',
              kpts=(6, 1, 1),
              gamma_cut=cut,
              **default_param)
atoms.set_calculator(calc)
e1 = atoms.get_potential_energy()

atoms6 = ase_Atoms(pbc=False)
atoms6 += atoms.extended_copy([(i - 2, 0, 0) for i in range(6)])
#view(atoms)
calc = Hotbit(SCC=SCC, txt='tmp.cal', gamma_cut=cut, **default_param)
atoms6.set_calculator(calc)
e6 = atoms6.get_potential_energy()

assert abs(6 * e1 - e6) < 1E-5

#
# energy conservation
#
atoms = Atoms('CH', [(1.42, 0, 0), (2.0, 0.5, 0.3)], container='Wedge')
atoms.set_container(M=6, height=10)
calc = Hotbit(SCC=SCC,
              txt='tmp.cal',