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