def gen_super(self, grain=None, rbt=None, sup_v=6, sup_bxv=2, rcut=2.0): """ :method:`gen_super` Creates a :class:SubGrainBoundary super cell according to conventions described in Rittner and Seidman (PRB 54 6999). Args: grain(:class:`ase.Atoms`): atoms object passed from gen_super_rbt. rbt (list): rigid body translation as fractional translations of the supercell. sup_v(int): Size of supercell along v. sup_bxv(int): Size of supercell along boundary_plane_normal crossed with v. rcut(float): Atom deletion criterion in angstrom. """ io = ImeallIO() if rbt == None: x = Atoms('{0}.xyz'.format(os.path.join(self.grain_dir, self.gbid))) else: x = Atoms(grain) struct_dir = os.path.join(self.grain_dir, 'structs') self.name = '{0}_v{1}bxv{2}_tv{3}bxv{4}_d{5}z'.format(self.gbid, str(sup_v), str(sup_bxv), '0.0', '0.0', str(rcut)) #TODO fix this so it is more transparent. #if rcut = 0 then only a super cell is generated with no deletion of atoms. if rcut > 0.0: x.set_cutoff(2.4) x.calc_connect() x.calc_dists() rem = [] u = np.zeros(3) for i in range(x.n): for n in range(x.n_neighbours(i)): j = x.neighbour(i, n, distance=3.0, diff=u) if x.distance_min_image(i,j) < rcut and j != i: rem.append(sorted([j,i])) rem = list(set([a[0] for a in rem])) if len(rem) > 0: x.remove_atoms(rem) else: print 'No duplicate atoms in list.' else: x = x*(sup_v, sup_bxv, 1) x.set_scaled_positions(x.get_scaled_positions()) if rbt == None: self.struct_file = self.name self.subgrain_dir = io.make_dir(self.calc_dir, self.name) try: with open('{0}/subgb.json'.format(self.subgrain_dir), 'r') as f: j_dict = json.load(f) except IOError: j_dict = {} j_dict['name'] = self.name j_dict['param_file'] = self.param_file j_dict['rbt'] = [0.0, 0.0] j_dict['rcut'] = rcut with open('{0}/subgb.json'.format(self.subgrain_dir), 'w') as f: json.dump(j_dict, f, indent=2) else: return sup_v, sup_bxv, x
def del_atoms(x=None): rcut = 2.0 #x = Atoms('crack.xyz') if x == None: x = Atoms('1109337334_frac.xyz') else: pass x.set_cutoff(3.0) x.calc_connect() x.calc_dists() rem=[] r = farray(0.0) u = fzeros(3) print len(x) for i in frange(x.n): for n in frange(x.n_neighbours(i)): j = x.neighbour(i, n, distance=3.0, diff=u) if x.distance_min_image(i, j) < rcut and j!=i: rem.append(sorted([j,i])) if i%10000==0: print i rem = list(set([a[0] for a in rem])) if len(rem) > 0: print rem x.remove_atoms(rem) else: print 'No duplicate atoms in list.' x.write('crack_nodup.xyz') return x
def delete_atoms(self, grain=None, rcut=2.0): """ Delete atoms below a certain distance threshold. Args: grain(:class:`quippy.Atoms`): Atoms object of the grain. rcut(float): Atom deletion criterion. Returns: :class:`quippy.Atoms` object with atoms nearer than deletion criterion removed. """ io = ImeallIO() if grain == None: x = Atoms('{0}.xyz'.format(os.path.join(self.grain_dir, self.gbid))) else: x = Atoms(grain) x.set_cutoff(2.4) x.calc_connect() x.calc_dists() rem = [] u = fzeros(3) for i in frange(x.n): for n in frange(x.n_neighbours(i)): j = x.neighbour(i, n, distance=3.0, diff=u) if x.distance_min_image(i, j) < rcut and j != i: rem.append(sorted([j, i])) rem = list(set([a[0] for a in rem])) if len(rem) > 0: x.remove_atoms(rem) else: print 'No duplicate atoms in list.' if grain == None: self.name = '{0}_d{1}'.format(self.gbid, str(rcut)) self.subgrain_dir = io.make_dir(self.calc_dir, self.name) self.struct_file = gbid + '_' + 'n' + str( len(rem)) + 'd' + str(rcut) x.write('{0}.xyz'.format( os.path.join(self.subgrain_dir, self.struct_file))) return len(rem) else: return x
ats.add_atoms(h,1) #ats.wrap() ats.write('crackH.xyz') ats = None ats = Atoms('crackH.xyz') ats.set_cutoff(2.4) ats.calc_connect() ats.calc_dists() filter_mask = (ats.get_atomic_numbers()==1) h_atoms = ats.select(filter_mask, orig_index=True) rem=[] u = np.zeros(3) for i in h_atoms.orig_index: print 'hindex', i print 'nneighbs', ats.n_neighbours(i) for n in range(ats.n_neighbours(i)): j = ats.neighbour(i, n+1, distance=2.4, diff=u) print 'neighb index', j if ats.distance_min_image(i,j) < 1.1 and j!=i: rem.append(i) rem = list(set(rem)) if len(rem) > 0: print 'Removing {} H atoms'.format(len(rem)) ats.remove_atoms(rem) else: print 'No H atoms closer than threshold.' #Now a little housekeeping. In the vicinity of a cracktip #Delaunay can go a little haywire. We remove any H that is far too close to an Fe atom # |h-fe| < 1.1. and we remove the vacuum Hs ats.write('crackH.xyz')