Exemple #1
0
    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
Exemple #2
0
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
Exemple #3
0
    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
Exemple #4
0
s_system = list(x)
s_system.extend(y)
name = ''.join(map(str, s_system)).replace('-', '')

print x, y, z

disloc = Dislocation(x=x, y=y, z=z, name=name)
disloc.gen_edge_dislocation()
POT_DIR = '/Users/lambert/pymodules/imeall/imeall/potentials'
eam_pot = os.path.join(POT_DIR, 'Fe_Mendelev.xml')

print 'Open Atoms'
at = Atoms('e{0}.xyz'.format(name))
at.set_cutoff(3.0)
at.calc_connect()

print 'Delete atoms'
at = gbr.delete_atoms(grain=at, rcut=1.5)
at.info['OrigHeight'] = at.positions[:, 1].max() - at.positions[:, 1].min()
r_scale = 1.00894848312
rem = []
for atom in at:
    if atom.position[0] <= 0.00 and atom.position[1] <= 100.0:
        rem.append(atom.index + 1)
print 'Removing ', len(rem), ' atoms.'
if len(rem) > 0:
    at.remove_atoms(rem)
else:
    print 'No atoms displaced from unitcell'
pot = Potential('IP EAM_ErcolAd do_rescale_r=T r_scale={0}'.format(r_scale),
Exemple #5
0
def pp_nye_tensor(at, rr=15.0, dis_type='edge'):
# Post Processing routine to append nye tensor information
# to atoms object.
# Load reference slab and calculate connectivity
    ref_slab   = Atoms('./ref_slab.xyz')
    at.set_cutoff(3.0)
    at.calc_connect()
    ref_slab.set_cutoff(3.0)
    ref_slab.calc_connect()
    core       = np.zeros(3)
# To save time it is possible to only
# calculate the nye tensor for a 'core' region
# determined by cutting out a cluster:
    if dis_type in ['edge','screw']:
      try:
        core   = at.info['core']
      except:
        sys.exit('No Core Info')
      print '\t Core Position: ', core
    elif dis_type == 'crack':
      core   = at.info['CrackPos']
      print '\t Crack Position: ', core

    fixed_mask = (np.sqrt((at.positions[:,0]-core[0])**2 + (at.positions[:,1]-core[1])**2) < rr)

    if dis_type in ['edge','screw']:
      at.add_property('edgex', 0.0)
      at.add_property('edgey', 0.0)
      at.add_property('screw', 0.0)
#Going to append full nye tensor to the crack tip:
    elif dis_type == 'crack':
      at.add_property('nye', 0.0, n_cols=9, overwrite=True)

    cl = at.select(mask=fixed_mask, orig_index=True) 
    print '\t Size of cluster: ', len(cl)
# Append screw and edge information
# Probably should just pass an array at this stage?
    alpha     = calc_nye_tensor(cl, ref_slab, 3, 3, cl.n)
    cl.edgex  = alpha[2,0,:]
    cl.edgey  = alpha[2,1,:]
    cl.screw  = alpha[2,2,:]
# Update quantum region according to the
# position of the dislocation core:
    if dis_type in ['edge', 'screw']:
      if dis_type  == 'screw':
        defect_pos = cl.screw
      elif dis_type == 'edge':
        defect_pos = cl.edgex
      total_def    = 0.
      c            = np.array([0.,0.,0.])
      for i in range(len(cl)):
        total_def = total_def + defect_pos[i]
        c[0] = c[0] + cl.positions[i,0]*defect_pos[i]
        c[1] = c[1] + cl.positions[i,1]*defect_pos[i]
      c[0] = c[0]/total_def
      c[1] = c[1]/total_def
      c[2] = cl.lattice[2,2]/2.
      core[:] = c.copy()
    if dis_type in ['edge', 'screw']:
      for index, screw, edgex, edgey in zip(cl.orig_index, cl.screw, cl.edgex, cl.edgey):
# Now thread atoms back in looks like select will have indices in the fortran convention.
        at.screw[index-1] = screw
        at.edgex[index-1] = edgex
        at.edgey[index-1] = edgey
    elif dis_type == 'crack':
      for orig_index, index in zip(cl.orig_index, range(len(cl))):
        at.nye[:, orig_index-1] = alpha[:,:,index].T.reshape(9)
    return core
Exemple #6
0
  defect.info['OrigHeight']        = orig_height
  strain_atoms = fix_edges_defect(defect)
  xpos = defect.positions[:,0]
  ypos = defect.positions[:,1]
  seed = 0.0
  tip  = 0.0

  if False:
    strain = G_to_strain(initial_G, E, nu, orig_height)
    print 'Applied strain: ', strain*100., '%'
    defect.info['strain'] = strain
    defect.info['G']      = initial_G
    defect.positions[:,1] += thin_strip_displacement_y(xpos, ypos, strain, seed, tip)

  defect.set_cutoff(3.0)
  defect.calc_connect()
  
  xlen = defect.positions[:,0].max() - defect.positions[:,0].min()
  ylen = defect.positions[:,2].max() - defect.positions[:,2].min()

  defect_object             = {}
  defect_object['x']        = x
  defect_object['y']        = y
  defect_object['z']        = z
  defect_object['T']        = sim_T/units.kB
  defect_json(**defect_object)

  if run_dyn:
  # Load atoms and set potential
  # If tight-binding need to re-initialize potential
  # with new defect atoms object.
Exemple #7
0
def pp_nye_tensor(at, rr=15.0, dis_type='edge'):
    # Post Processing routine to append nye tensor information
    # to atoms object.
    # Load reference slab and calculate connectivity
    ref_slab = Atoms('./ref_slab.xyz')
    at.set_cutoff(3.0)
    at.calc_connect()
    ref_slab.set_cutoff(3.0)
    ref_slab.calc_connect()
    core = np.zeros(3)
    # To save time it is possible to only
    # calculate the nye tensor for a 'core' region
    # determined by cutting out a cluster:
    if dis_type in ['edge', 'screw']:
        try:
            core = at.info['core']
        except:
            sys.exit('No Core Info')
        print '\t Core Position: ', core
    elif dis_type == 'crack':
        core = at.info['CrackPos']
        print '\t Crack Position: ', core

    fixed_mask = (np.sqrt((at.positions[:, 0] - core[0])**2 +
                          (at.positions[:, 1] - core[1])**2) < rr)

    if dis_type in ['edge', 'screw']:
        at.add_property('edgex', 0.0)
        at.add_property('edgey', 0.0)
        at.add_property('screw', 0.0)
#Going to append full nye tensor to the crack tip:
    elif dis_type == 'crack':
        at.add_property('nye', 0.0, n_cols=9, overwrite=True)

    cl = at.select(mask=fixed_mask, orig_index=True)
    print '\t Size of cluster: ', len(cl)
    # Append screw and edge information
    # Probably should just pass an array at this stage?
    alpha = calc_nye_tensor(cl, ref_slab, 3, 3, cl.n)
    cl.edgex = alpha[2, 0, :]
    cl.edgey = alpha[2, 1, :]
    cl.screw = alpha[2, 2, :]
    # Update quantum region according to the
    # position of the dislocation core:
    if dis_type in ['edge', 'screw']:
        if dis_type == 'screw':
            defect_pos = cl.screw
        elif dis_type == 'edge':
            defect_pos = cl.edgex
        total_def = 0.
        c = np.array([0., 0., 0.])
        for i in range(len(cl)):
            total_def = total_def + defect_pos[i]
            c[0] = c[0] + cl.positions[i, 0] * defect_pos[i]
            c[1] = c[1] + cl.positions[i, 1] * defect_pos[i]
        c[0] = c[0] / total_def
        c[1] = c[1] / total_def
        c[2] = cl.lattice[2, 2] / 2.
        core[:] = c.copy()
    if dis_type in ['edge', 'screw']:
        for index, screw, edgex, edgey in zip(cl.orig_index, cl.screw,
                                              cl.edgex, cl.edgey):
            # Now thread atoms back in looks like select will have indices in the fortran convention.
            at.screw[index - 1] = screw
            at.edgex[index - 1] = edgex
            at.edgey[index - 1] = edgey
    elif dis_type == 'crack':
        for orig_index, index in zip(cl.orig_index, range(len(cl))):
            at.nye[:, orig_index - 1] = alpha[:, :, index].T.reshape(9)
    return core
Exemple #8
0
    strain_atoms = fix_edges_defect(defect)
    xpos = defect.positions[:, 0]
    ypos = defect.positions[:, 1]
    seed = 0.0
    tip = 0.0

    if False:
        strain = G_to_strain(initial_G, E, nu, orig_height)
        print 'Applied strain: ', strain * 100., '%'
        defect.info['strain'] = strain
        defect.info['G'] = initial_G
        defect.positions[:, 1] += thin_strip_displacement_y(
            xpos, ypos, strain, seed, tip)

    defect.set_cutoff(3.0)
    defect.calc_connect()

    xlen = defect.positions[:, 0].max() - defect.positions[:, 0].min()
    ylen = defect.positions[:, 2].max() - defect.positions[:, 2].min()

    defect_object = {}
    defect_object['x'] = x
    defect_object['y'] = y
    defect_object['z'] = z
    defect_object['T'] = sim_T / units.kB
    defect_json(**defect_object)

    if run_dyn:
        # Load atoms and set potential
        # If tight-binding need to re-initialize potential
        # with new defect atoms object.
Exemple #9
0
      print 'Running WITH EAM as embedded cluster'
      qm_pot_file  = os.path.join(pot_dir, 'PotBH_fakemod.xml')
      print qm_pot_file
      mm_init_args = 'IP EAM_ErcolAd do_rescale_r=T r_scale=1.01' # Classical potential
      qm_pot       = Potential(mm_init_args, param_filename=qm_pot_file, cutoff_skin=cutoff_skin)
      qmmm_pot     = set_qmmm_pot(atoms, atoms.params['CrackPos'], mm_pot, qm_pot)

    strain_atoms = fix_edges(atoms)

    print 'Setup dynamics'
#If input_file is crack.xyz the cell has not been thermalized yet.
#Otherwise it will recover temperature from the previous run.
    print 'Attaching trajectories to dynamics'
    trajectory = AtomsWriter(traj_file)
#Only wriates trajectory if the system is in the LOTFDynamicas
#Interpolation 
    atoms.wrap()
    atoms.set_cutoff(3.0)
    atoms.calc_connect()
    print 'Running Crack Simulation'
    RELAXATION = False
    if RELAXATION:
      dynamics = FIRE(atoms)
      dynamics.attach(pass_trajectory_context(trajectory, dynamics), traj_interval, dynamics)
      dynamics.run(fmax=0.1)
    else:
      dynamics = LOTFDynamics(atoms, timestep, extrapolate_steps)
      dynamics.attach(pass_trajectory_context(trajectory, dynamics), traj_interval, dynamics)
      nsteps    = 2000
      dynamics.run(nsteps)
Exemple #10
0
ats.info['adsorbate_info']=None

with open('crack_info.pckl','r') as f:
  crack_dict= pickle.load(f)
print 'G: {}, H_d: {}, sim_T {}'.format(crack_dict['initial_G']*(units.m**2/units.J),
                                        crack_dict['H_d'], crack_dict['sim_T']/units.kB)
h_list  = hydrify.hydrogenate_gb(ats, mode='CrackTip', d_H=crack_dict['H_d'][0], tetrahedral=True, crackpos_fix=ats.params['CrackPos'])
for h in h_list:
  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: