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 slice_sample(bulk, potential, potential_filename, temperature, pressure, lattice_delta, atom_delta, m_max, e0=None, init_d=0, num_configs=10, write_interval=-1, random_seed=None): info("Inside Slice Sample.") # Randomise the random seed if random_seed is None: random_seed = SystemRandom().randint(0, 2**63) quippy.system.system_set_random_seeds(random_seed) seed(random_seed) info("Quippy Random Seed {0}.".format(random_seed)) info("Python Random Seed {0}.".format(random_seed)) if not isinstance(potential, Potential): if potential_filename: potential = Potential(potential, param_filename=potential_filename) else: potential = Potential(potential) bulk = Atoms(bulk) # pressure in GPa -> eV/A^3 pressure = pressure / quippy.GPA density_function = create_density_function(bulk, potential, pressure, temperature, e0) # Convert to triangle lattice representation (lower triangle in cell) scaled_positions = bulk.get_scaled_positions() lattice_params = quippy.get_lattice_params(bulk.lattice) new_cell = quippy.make_lattice(*lattice_params).T bulk.set_cell(new_cell) bulk.set_scaled_positions(scaled_positions) params = [ bulk.cell[0][0], bulk.cell[1][0], bulk.cell[1][1], bulk.cell[2][0], bulk.cell[2][1], bulk.cell[2][2] ] info("Re-orineted to cell: {0}.".format(new_cell.tolist())) for atom in bulk.positions.tolist()[1:]: params.extend(atom) # value for the first iteration df_value = density_function(params) # Floating count so that division by write_interval make it integer for # written configurations count = 0.0 idx = init_d output = ParamWriter(bulk, bulk.info['name'], potential) # Only write once everything has changed if write_interval < 1: write_interval = len(params) info("Writing configurations after {0} steps.".format(write_interval)) # Loop just iterates to the next value of x while count / write_interval < num_configs: # Determine the delta value outside the incrementer, so we can make it # do less work if idx < 6: delta = lattice_delta else: delta = atom_delta # Here's where the magic happens params, df_value = increment_params(density_function, params, idx, delta, m_max, df_0=df_value) debug("SLICE_SAMPLE: {0:g}".format(count / write_interval)) debug("Params: {0}.".format(", ".join("{0}".format(x) for x in params))) if not count % write_interval: output.write_config(params) count += 1 idx += 1 if idx >= len(params): idx = 0 output.close() info("Slice Sample Done.")