def dia_100_2x1(sym, a0): sym = string2symbols(sym) if len(sym) == 1: a = Diamond(sym[0], size = [2*nx, nx, nz], latticeconstant = a0, directions=[ [1,-1,0], [1,1,0], [0,0,1] ] ) else: a = B3(sym, size = [2*nx, nx, nz], latticeconstant = a0, directions=[ [1,-1,0], [1,1,0], [0,0,1] ] ) sx, sy, sz = a.get_cell().diagonal() a.translate([sx/(8*nx), sy/(8*nx), sz/(8*nz)]) bulk = a.copy() for i in a: if i.z < sz/(4*nz) or i.z > sz-sz/(4*nz): if i.x < sx/2: i.x = i.x+0.5 else: i.x = i.x-0.5 return bulk, a
def test_sqlite(testdir): CP = Checkpoint('checkpoints.db') a = Diamond('Si', size=[2, 2, 2]) a = CP(op1)(a, 1.0) op1a = a.copy() a, ra = CP(op2)(a, 2.0) op2a = a.copy() op2ra = ra.copy() CP = Checkpoint('checkpoints.db') a = Diamond('Si', size=[2, 2, 2]) a = CP(op1)(a, 1.0) assert a == op1a a, ra = CP(op2)(a, 2.0) assert a == op2a assert(np.abs(ra - op2ra).max() < 1e-5)
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 test_dsygv_dgelsd(self): a = Diamond('C', size=[4,4,4]) b = a.copy() b.positions += (np.random.random(b.positions.shape)-0.5)*0.1 i, j = neighbour_list("ij", b, 1.85) dr_now = mic(b.positions[i] - b.positions[j], b.cell) dr_old = mic(a.positions[i] - a.positions[j], a.cell) dgrad1 = get_delta_plus_epsilon_dgesv(len(b), i, dr_now, dr_old) dgrad2 = get_delta_plus_epsilon(len(b), i, dr_now, dr_old) self.assertArrayAlmostEqual(dgrad1, dgrad2)
def test_sqlite(): print('test_single_file') try: os.remove('checkpoints.db') except OSError: pass CP = Checkpoint('checkpoints.db') a = Diamond('Si', size=[2, 2, 2]) a = CP(op1)(a, 1.0) op1a = a.copy() a, ra = CP(op2)(a, 2.0) op2a = a.copy() op2ra = ra.copy() CP = Checkpoint('checkpoints.db') a = Diamond('Si', size=[2, 2, 2]) a = CP(op1)(a, 1.0) assert a == op1a a, ra = CP(op2)(a, 2.0) assert a == op2a assert(np.abs(ra - op2ra).max() < 1e-5)
def test_sqlite(self): print('test_single_file') try: os.remove('checkpoints.db') except OSError: pass CP = Checkpoint('checkpoints.db') a = Diamond('Si', size=[2, 2, 2]) a = CP(self.op1)(a, 1.0) op1a = a.copy() a, ra = CP(self.op2)(a, 2.0) op2a = a.copy() op2ra = ra.copy() CP = Checkpoint('checkpoints.db') a = Diamond('Si', size=[2, 2, 2]) a = CP(self.op1)(a, 1.0) self.assertEqual(a, op1a) a, ra = CP(self.op2)(a, 2.0) self.assertEqual(a, op2a) self.assert_(np.abs(ra - op2ra).max() < 1e-5)
def test_sqlite(self): print('test_single_file') try: os.remove('checkpoints.db') except OSError: pass CP = Checkpoint('checkpoints.db') a = Diamond('Si', size=[2,2,2]) a = CP(self.op1)(a, 1.0) op1a = a.copy() a, ra = CP(self.op2)(a, 2.0) op2a = a.copy() op2ra = ra.copy() CP = Checkpoint('checkpoints.db') a = Diamond('Si', size=[2,2,2]) a = CP(self.op1)(a, 1.0) self.assertAtomsAlmostEqual(a, op1a) a, ra = CP(self.op2)(a, 2.0) self.assertAtomsAlmostEqual(a, op2a) self.assertArrayAlmostEqual(ra, op2ra)
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 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
ase.io.write(sys.stdout, bulk, format='extxyz') print 'expanded cell energy', eexp e_form = 0.5*(eexp - ebulk) / np.linalg.norm(np.cross(bulk.cell[0,:],bulk.cell[1,:])) print 'unrelaxed 110 surface formation energy', e_form return e_form # dictionary of computed properties - this is output of this test, to # be compared with other models n_steps = 35 max_opening = 3.5 openings = [] es = [] for i in range(n_steps + 1): opening = float(i)/float(n_steps)*max_opening openings.append(opening) bulk_copy = bulk.copy() bulk_copy.set_calculator(model.calculator) es.append(surface_energy(bulk_copy, 2.0, opening)) print "openings ", openings print "es ", es from scipy import interpolate spline = interpolate.splrep(openings, es, s=0) stresses = [x for x in interpolate.splev(openings, spline, der=1)] print "stresses ", stresses properties = {'surface_decohesion_unrelaxed_opening': openings, 'surface_decohesion_unrelaxed_energy' : es, 'surface_decohesion_unrelaxed_stress' : stresses}
# You could check elastic constants of this rotated system: # should lead to same Young's modulus and Poisson ratio 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 adding some vaccum along y surface = unit_slab.copy() surface.center(vacuum, axis=1) # ********** Surface energy ************ # Calculate surface energy per unit area surface.set_calculator(mm_pot) E_surf = surface.get_potential_energy() E_per_atom_bulk = si_bulk.get_potential_energy() / len(si_bulk) area = surface.get_volume() / surface.cell[1, 1] gamma = ((E_surf - E_per_atom_bulk * len(surface)) / (2.0 * area)) print('Surface energy of %s surface %.4f J/m^2\n' % (cleavage_plane, gamma / (units.J / units.m ** 2)))
unit_slab = Diamond(directions=[crack_direction, cleavage_plane, crack_front], size=(1, 1, 1), symbol='Si', pbc=True, latticeconstant=5.431) 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, axis=1) surface.set_calculator(mm_pot) E_surf = surface.get_potential_energy() E_per_atom_bulk = si_bulk.get_potential_energy() / len(si_bulk) area = surface.get_volume() / surface.cell[1, 1] gamma = ((E_surf - E_per_atom_bulk * len(surface)) / (2.0 * area)) nx = int(width / unit_slab.cell[0, 0]) ny = int(height / unit_slab.cell[1, 1]) # make sure ny is even so slab is centered on a bond if ny % 2 == 1:
else: bulk.set_calculator(model.calculator) bulk = relax_atoms_cell(bulk, tol=tol, traj_file=None) print 'bulk reference len=%d cell=%r' % (len(bulk), bulk.cell) bulk *= (N, N, N) bulk.set_calculator(model.calculator) e_bulk_per_atom = bulk.get_potential_energy() / len(bulk) print 'e_bulk_per_atom', e_bulk_per_atom if remove_index == 'center': half_cell = np.diag(bulk.cell) / 2. remove_index = ((bulk.positions - half_cell)**2).sum(axis=1).argmin() initial = bulk.copy() orig_pos = initial.get_positions()[remove_index, :] nl = NeighborList([a0 * sqrt(3.0) / 4 * 0.6] * len(initial), self_interaction=False, bothways=True) nl.update(initial) indices, offsets = nl.get_neighbors(remove_index) remove_index_f = None initial.arrays['ind'] = array([i for i in range(len(initial))]) offset_factor = 0.13 for i, offset in zip(indices, offsets): ri = initial.positions[remove_index] - (initial.positions[i] + dot(offset, initial.get_cell())) if remove_index_f is None: remove_index_f = i