Exemplo n.º 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
Exemplo n.º 2
0
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.")