Пример #1
0
    def build_surface(self, pot, size=(1, 1, 1)):
        """
    Create an equivalent surface unit cell for the fracture system.
    """
        if self.symbol == 'Si':
            unit_slab = Diamond(directions=[
                self.crack_direction, self.cleavage_plane, self.crack_front
            ],
                                size=size,
                                symbol=self.symbol,
                                pbc=True,
                                latticeconstant=self.a0)
        elif self.symbol == 'Fe':
            unit_slab = BodyCenteredCubic(directions=[
                self.crack_direction, self.cleavage_plane, self.crack_front
            ],
                                          size=size,
                                          symbol='Fe',
                                          pbc=(1, 1, 1),
                                          latticeconstant=self.a0)


# Does this work for more than 2 atoms?
        unit_slab.info['adsorbate_info'] = None
        unit_slab.positions[:, 1] += (unit_slab.positions[1, 1] -
                                      unit_slab.positions[0, 1]) / 2.0
        unit_slab.set_scaled_positions(unit_slab.get_scaled_positions())
        surface = unit_slab.copy()
        surface.center(vacuum=self.vacuum, axis=1)
        surface.set_calculator(pot)
        return surface
Пример #2
0
def diamond_110_001(el, a0, n, crack_surface=[1,1,0], crack_front=[0,0,1],
            skin_x=1.0, skin_y=1.0, vac=5.0):
    nx, ny, nz = n
    third_dir = np.cross(crack_surface, crack_front)
    directions = [ third_dir, crack_surface, crack_front ]
    if np.linalg.det(directions) < 0:
        third_dir = -third_dir
    directions = [ third_dir, crack_surface, crack_front ]
    a = Diamond(el, latticeconstant = a0, size = [ nx,ny,nz ], 
                directions = directions)
    sx, sy, sz = a.get_cell().diagonal()
    a.translate([a0/100,a0/100,a0/100])
    a.set_scaled_positions(a.get_scaled_positions())
    a.center()

    lx  = skin_x*sx/nx
    ly  = skin_y*sy/ny
    r   = a.get_positions()
    g   = np.where(
        np.logical_or(
            np.logical_or(
                np.logical_or(
                    r[:, 0] < lx, r[:, 0] > sx-lx),
                r[:, 1] < ly),
            r[:, 1] > sy-ly),
        np.zeros(len(a), dtype=int),
        np.ones(len(a), dtype=int))
    a.set_array('groups', g)

    a.set_cell([sx+2*vac, sy+2*vac, sz])
    a.translate([vac, vac, 0.0])
    a.set_pbc([False, False, True])

    return a
Пример #3
0
 def build_unit_slab(self, size=(1, 1, 1)):
     """
 Initialize the unit slab for the given crack geometry.
 Currently supports silicon and Fe.
 """
     if self.symbol == 'Si':
         unit_slab = Diamond(directions=[
             self.crack_direction, self.cleavage_plane, self.crack_front
         ],
                             size=size,
                             symbol=self.symbol,
                             pbc=True,
                             latticeconstant=self.a0)
     elif self.symbol == 'Fe':
         unit_slab = BodyCenteredCubic(directions=[
             self.crack_direction, self.cleavage_plane, self.crack_front
         ],
                                       size=size,
                                       symbol='Fe',
                                       pbc=(1, 1, 1),
                                       latticeconstant=self.a0)
     print 'Number atoms in unit slab', len(unit_slab)
     unit_slab.info['adsorbate_info'] = None
     unit_slab.positions[:, 1] += (unit_slab.positions[1, 1] -
                                   unit_slab.positions[0, 1]) / 2.0
     unit_slab.set_scaled_positions(unit_slab.get_scaled_positions())
     pot_dir = os.environ['POTDIR']
     pot_file = os.path.join(pot_dir, self.param_file)
     print pot_file
     print self.mm_init_args
     #pot = Potential(self.mm_init_args, param_filename = pot_file)
     #pot = Potential("IP EAM_ErcolAd do_rescale_r=T r_scale=1.00894848312" , param_filename = "/Users/lambert/pymodules/imeall/imeall/potentials/PotBH.xml")
     #unit_slab.set_calculator(pot)
     return unit_slab
Пример #4
0
def dia_111_glide(sym, a0):
    sym = string2symbols(sym)
    if len(sym) == 1:
        a = Diamond(sym[0],
                    size=[nx, nx, nz],
                    latticeconstant=a0,
                    directions=[[1, -1, 0], [1, 1, -2], [1, 1, 1]])
    else:
        a = B3(sym,
               size=[nx, nx, nz],
               latticeconstant=a0,
               directions=[[1, -1, 0], [1, 1, -2], [1, 1, 1]])
    sx, sy, sz = a.get_cell().diagonal()
    a.translate([sx / (12 * nx), sy / (4 * nx), sz / (12 * nz) - 0.2])
    a.set_scaled_positions(a.get_scaled_positions() % 1.0)
    return a
Пример #5
0
def dia_111_pandey(sym, a0, nx=nx, ny=nx, nz=nz):
    """2x1 Pandey reconstructed (111) surface."""
    sym = string2symbols(sym)
    if len(sym) == 1:
        a = Diamond(sym[0],
                    size             = [nx, ny, nz],
                    latticeconstant  = a0,
                    directions=[ [1,-1,0], [1,1,-2], [1,1,1] ]
                    )
    else:
        a = B3(sym,
               size             = [nx, ny, nz],
               latticeconstant  = a0,
               directions=[ [1,-1,0], [1,1,-2], [1,1,1] ]
               )
    sx, sy, sz = a.get_cell().diagonal()
    a.translate([sx/(12*nx), sy/(4*ny), sz/(6*nz)])
    a.set_scaled_positions(a.get_scaled_positions()%1.0)

    bulk = a.copy()

    bondlen = a0*sqrt(3)/4

    x, y, z = a.positions.T
    mask = np.abs(z-z.max()) < 0.1*a0
    top1, top2 = np.arange(len(a))[mask].reshape(-1, 2).T
    mask = np.logical_and(np.abs(z-z.max()) < bondlen, np.logical_not(mask))
    topA, topB = np.arange(len(a))[mask].reshape(-1, 2).T
    y[topA] += bondlen/3
    y[topB] -= bondlen/3
    y[top1] += bondlen
    x[top1] += a.cell[0,0]/(2*nx)
    x[top2] += a.cell[0,0]/(2*nx)

    mask = np.abs(z-z.min()) < 0.1*a0
    bot1, bot2 = np.arange(len(a))[mask].reshape(-1, 2).T
    mask = np.logical_and(np.abs(z-z.min()) < bondlen, np.logical_not(mask))
    botA, botB = np.arange(len(a))[mask].reshape(-1, 2).T
    y[botA] += bondlen/3
    y[botB] -= bondlen/3
    y[bot2] -= bondlen
    x[bot2] += a.cell[0,0]/(2*nx)
    x[bot1] += a.cell[0,0]/(2*nx)

    a.set_scaled_positions(a.get_scaled_positions()%1.0)

    return bulk, a
Пример #6
0
def diamond_110_110(el, a0, n, crack_surface=[1,1,0],
                    crack_front=[1,-1,0],
                    skin_x=0.5, skin_y=1.0,
                    central_x=-1.0, central_y=-1.0,
                    vac=5.0):
    nx, ny, nz = n
    third_dir = np.cross(crack_surface, crack_front)
    a = Diamond(el,
            latticeconstant = a0,
            size = [nx, ny, nz], 
            directions = [third_dir, crack_surface, crack_front]
            )
    sx, sy, sz = a.get_cell().diagonal()
    a.translate([sx/(8*nx), sy/(4*ny), sz/(4*nz)])
    a.set_scaled_positions(a.get_scaled_positions())

    skin_x = skin_x*sx/nx
    skin_y = skin_y*sy/ny
    r = a.get_positions()
    g = np.where(
        np.logical_or(
            np.logical_or(
                np.logical_or(
                    r[:, 0] < skin_x, r[:, 0] > sx-skin_x),
                r[:, 1] < skin_y),
            r[:, 1] > sy-skin_y),
        np.zeros(len(a), dtype=int),
        np.ones(len(a), dtype=int))

    g = np.where(
        np.logical_or(
            np.logical_or(
                np.logical_or(
                    r[:, 0] < sx/2-central_x, r[:, 0] > sx/2+central_x),
                r[:, 1] < sy/2-central_y),
            r[:, 1] > sy/2+central_y),
        g,
        2*np.ones(len(a), dtype=int))
    a.set_array('groups', g)

    a.set_cell([sx+2*vac, sy+2*vac, sz])
    a.translate([vac, vac, 0.0])
    a.set_pbc([False, False, True])

    return a
Пример #7
0
def dia_111_glide(sym, a0):
    sym = string2symbols(sym)
    if len(sym) == 1:
        a = Diamond(sym[0],
                    size             = [nx, nx, nz],
                    latticeconstant  = a0,
                    directions=[ [1,-1,0], [1,1,-2], [1,1,1] ]
                    )
    else:
        a = B3(sym,
               size             = [nx, nx, nz],
               latticeconstant  = a0,
               directions=[ [1,-1,0], [1,1,-2], [1,1,1] ]
               )
    sx, sy, sz = a.get_cell().diagonal()
    a.translate([sx/(12*nx), sy/(4*nx), sz/(12*nz)-0.2])
    a.set_scaled_positions(a.get_scaled_positions()%1.0)
    return a
Пример #8
0
  def build_surface(self,pot, size=(1,1,1)):
    """
    Create an equivalent surface unit cell for the fracture system.
    """
    if self.symbol=='Si':
      unit_slab = Diamond(directions = [self.crack_direction, self.cleavage_plane, self.crack_front],
                          size = size, symbol=self.symbol, pbc=True, latticeconstant= self.a0)
    elif self.symbol=='Fe':
      unit_slab = BodyCenteredCubic(directions=[self.crack_direction, self.cleavage_plane, self.crack_front],
                               size=size, symbol='Fe', pbc=(1,1,1),
                               latticeconstant=self.a0)
# Does this work for more than 2 atoms?
    unit_slab.info['adsorbate_info'] = None
    unit_slab.positions[:, 1] += (unit_slab.positions[1, 1]-unit_slab.positions[0, 1])/2.0
    unit_slab.set_scaled_positions(unit_slab.get_scaled_positions())
    surface = unit_slab.copy()
    surface.center(vacuum=self.vacuum, axis=1)
    surface.set_calculator(pot)
    return surface
Пример #9
0
 def build_unit_slab(self, size=(1,1,1)):
   """
   Initialize the unit slab for the given crack geometry.
   Currently supports silicon and Fe.
   """
   if self.symbol=='Si':
     unit_slab = Diamond(directions = [self.crack_direction, self.cleavage_plane, self.crack_front],
                         size = size, symbol=self.symbol, pbc=True, latticeconstant= self.a0)
   elif self.symbol=='Fe':
     unit_slab = BodyCenteredCubic(directions=[self.crack_direction, self.cleavage_plane, self.crack_front],
                              size=size, symbol='Fe', pbc=(1,1,1),
                              latticeconstant=self.a0)
   print 'Number atoms in unit slab', len(unit_slab)
   unit_slab.info['adsorbate_info'] = None
   unit_slab.positions[:, 1] += (unit_slab.positions[1, 1]-unit_slab.positions[0, 1])/2.0
   unit_slab.set_scaled_positions(unit_slab.get_scaled_positions())
   pot_dir = os.environ['POTDIR']
   pot_file = os.path.join(pot_dir, self.param_file)
   print pot_file
   print self.mm_init_args
   #pot = Potential(self.mm_init_args, param_filename = pot_file)
   #pot = Potential("IP EAM_ErcolAd do_rescale_r=T r_scale=1.00894848312" , param_filename = "/Users/lambert/pymodules/imeall/imeall/potentials/PotBH.xml")
   #unit_slab.set_calculator(pot)
   return unit_slab
Пример #10
0
        assert (abs(E_r - E) / units.GPa < 1e-3)

        nu_r = -S_r[1, 2] / S_r[1, 1]
        print('Possion ratio from C_r: %.3f' % (nu_r))
        assert (abs(nu_r - nu) < 1e-3)

print('Unit slab with %d atoms per unit cell:' % len(unit_slab))
print(unit_slab.cell)
print('')

# center vertically half way along the vertical bond between atoms 0 and 1
unit_slab.positions[:, 1] += (unit_slab.positions[1, 1] -
                              unit_slab.positions[0, 1]) / 2.0

# map positions back into unit cell
unit_slab.set_scaled_positions(unit_slab.get_scaled_positions())

# Make a surface unit cell by repllcating and adding some vaccum along y
surface = unit_slab * [1, params.surf_ny, 1]
surface.center(params.vacuum, axis=1)

# ********** Surface energy ************

# Calculate surface energy per unit area
surface.set_calculator(params.calc)

if hasattr(params, 'relax_bulk') and params.relax_bulk:
    print('Minimising surface unit cell...')
    opt = FIRE(surface)
    opt.run(fmax=params.bulk_fmax)
Пример #11
0
        assert (abs(E_r - E)/units.GPa < 1e-3)

        nu_r = -S_r[1,2]/S_r[1,1]
        print('Possion ratio from C_r: %.3f' % (nu_r))
        assert (abs(nu_r - nu) < 1e-3)

print('Unit slab with %d atoms per unit cell:' % len(unit_slab))
print(unit_slab.cell)
print('')

# center vertically half way along the vertical bond between atoms 0 and 1
unit_slab.positions[:, 1] += (unit_slab.positions[1, 1] -
                              unit_slab.positions[0, 1]) / 2.0

# map positions back into unit cell
unit_slab.set_scaled_positions(unit_slab.get_scaled_positions())

# Make a surface unit cell by repllcating and adding some vaccum along y
surface = unit_slab * [1, params.surf_ny, 1]
surface.center(params.vacuum, axis=1)


# ********** Surface energy ************

# Calculate surface energy per unit area
surface.set_calculator(params.calc)

if hasattr(params, 'relax_bulk') and params.relax_bulk:
    print('Minimising surface unit cell...')
    opt = FIRE(surface)
    opt.run(fmax=params.bulk_fmax)