Exemple #1
0
    def apply(self, compound, orientation='', compound_port=''):
        """Arrange copies of a Compound as specified by the Pattern.

        Parameters
        ----------
        compound
        orientation

        Returns
        -------

        """
        compounds = list()
        if self.orientations.get(orientation):
            for port in self.orientations[orientation]:
                new_compound = clone(compound)
                new_port = new_compound.labels[compound_port]
                (new_compound, new_port['up'], port['up'])

                compounds.append(new_compound)
        else:
            for point in self.points:
                new_compound = clone(compound)
                translate(new_compound, point)

                compounds.append(new_compound)
        return compounds
Exemple #2
0
    def apply(self, compound, orientation='', compound_port=''):
        """Arrange copies of a Compound as specified by the Pattern.

        Parameters
        ----------
        compound
        orientation

        Returns
        -------

        """
        compounds = list()
        if self.orientations.get(orientation):
            for port in self.orientations[orientation]:
                new_compound = clone(compound)
                new_port = new_compound.labels[compound_port]
                equivalence_transform(new_compound, new_port['up'], port['up'])

                compounds.append(new_compound)
        else:
            for point in self.points:
                new_compound = clone(compound)
                translate(new_compound, point)

                compounds.append(new_compound)
        return compounds
    def __init__(self, tile, n_tiles, name=None):
        super(TiledCompound, self).__init__()

        n_tiles = np.asarray(n_tiles)
        if not np.all(n_tiles > 0):
            raise ValueError('Number of tiles must be positive.')

        # Check that the tile is periodic in the requested dimensions.
        if np.any(np.logical_and(n_tiles != 1, tile.periodicity == 0)):
            raise ValueError('Tile not periodic in at least one of the '
                             'specified dimensions.')

        if name is None:
            name = tile.name + '-'.join(str(d) for d in n_tiles)
        self.name = name
        self.periodicity = np.array(tile.periodicity * n_tiles)

        if all(n_tiles == 1):
            self._add_tile(tile, [(0, 0, 0)])
            self._hoist_ports(tile)
            return  # Don't waste time copying and checking bonds.

        # For every tile, assign temporary ID's to particles which are internal
        # to that tile. E.g., when replicating a tile with 1800 particles, every
        # tile will contain particles with ID's from 0-1799. These ID's are used
        # below to fix bonds crossing periodic boundary conditions where a new
        # tile has been placed.
        for idx, particle in enumerate(tile.particles(include_ports=True)):
            particle.index = idx

        # Replicate and place periodic tiles.
        # -----------------------------------
        for ijk in it.product(range(n_tiles[0]),
                              range(n_tiles[1]),
                              range(n_tiles[2])):
            new_tile = clone(tile)
            translate(new_tile, np.array(ijk * tile.periodicity))
            self._add_tile(new_tile, ijk)
            self._hoist_ports(new_tile)

        # Fix bonds across periodic boundaries.
        # -------------------------------------
        # Cutoff for long bonds is half the shortest periodic distance.
        bond_dist_thres = min(tile.periodicity[tile.periodicity > 0]) / 2

        # Bonds that were periodic in the original tile.
        indices_of_periodic_bonds = set()
        for particle1, particle2 in tile.bonds():
            if np.linalg.norm(particle1.pos - particle2.pos) > bond_dist_thres:
                indices_of_periodic_bonds.add((particle1.index,
                                                        particle2.index))

        # Build a periodic kdtree of all particle positions.
        self.particle_kdtree = PeriodicCKDTree(data=self.xyz, bounds=self.periodicity)
        all_particles = np.asarray(list(self.particles(include_ports=False)))

        # Store bonds to remove/add since we'll be iterating over all bonds.
        bonds_to_remove = set()
        bonds_to_add = set()
        for particle1, particle2 in self.bonds():
            if (particle1.index, particle2.index) not in indices_of_periodic_bonds \
                    and (particle2.index, particle1.index) not in indices_of_periodic_bonds:
                continue

            if self.min_periodic_distance(particle1.pos, particle2.pos) > bond_dist_thres:
                bonds_to_remove.add((particle1, particle2))
                image2 = self._find_particle_image(particle1, particle2,
                                                   all_particles)
                image1 = self._find_particle_image(particle2, particle1,
                                                   all_particles)

                if (image2, particle1) not in bonds_to_add:
                    bonds_to_add.add((particle1, image2))
                if (image1, particle2) not in bonds_to_add:
                    bonds_to_add.add((particle2, image1))

        for bond in bonds_to_remove:
            self.remove_bond(bond)

        for bond in bonds_to_add:
            self.add_bond(bond)

        # Clean up temporary data.
        for particle in self._particles(include_ports=True):
            particle.index = None
        del self.particle_kdtree
Exemple #4
0
 def _adjust_ports(self):
     for orientation, ports in self.orientations.items():
         for port, point in zip(ports, self.points):
             translate(port, point)
 def test_translate(self, methane):
     methane_atoms = list(methane.particles())
     translate(methane, -methane_atoms[0].pos)
     assert (methane_atoms[0].pos == np.array([0, 0, 0])).all()
Exemple #6
0
 def _adjust_ports(self):
     for orientation, ports in self.orientations.items():
         for port, point in zip(ports, self.points):
             translate(port, point)
 def test_translate(self, methane):
     methane_atoms = list(methane.particles())
     translate(methane, -methane_atoms[0].pos)
     assert (methane_atoms[0].pos == np.array([0, 0, 0])).all()
Exemple #8
0
    def __init__(self, tile, n_tiles, name=None):
        super(TiledCompound, self).__init__()

        n_tiles = np.asarray(n_tiles)
        if not np.all(n_tiles > 0):
            raise ValueError('Number of tiles must be positive.')

        # Check that the tile is periodic in the requested dimensions.
        if np.any(np.logical_and(n_tiles != 1, tile.periodicity == 0)):
            raise ValueError('Tile not periodic in at least one of the '
                             'specified dimensions.')

        if name is None:
            name = tile.name + '-'.join(str(d) for d in n_tiles)
        self.name = name
        self.periodicity = np.array(tile.periodicity * n_tiles)

        if all(n_tiles == 1):
            self._add_tile(tile, [(0, 0, 0)])
            self._hoist_ports(tile)
            return  # Don't waste time copying and checking bonds.

        # For every tile, assign temporary ID's to particles which are internal
        # to that tile. E.g., when replicating a tile with 1800 particles, every
        # tile will contain particles with ID's from 0-1799. These ID's are used
        # below to fix bonds crossing periodic boundary conditions where a new
        # tile has been placed.
        for idx, particle in enumerate(tile.particles(include_ports=True)):
            particle.index = idx

        # Replicate and place periodic tiles.
        # -----------------------------------
        for ijk in it.product(range(n_tiles[0]), range(n_tiles[1]),
                              range(n_tiles[2])):
            new_tile = clone(tile)
            translate(new_tile, np.array(ijk * tile.periodicity))
            self._add_tile(new_tile, ijk)
            self._hoist_ports(new_tile)

        # Fix bonds across periodic boundaries.
        # -------------------------------------
        # Cutoff for long bonds is half the shortest periodic distance.
        bond_dist_thres = min(tile.periodicity[tile.periodicity > 0]) / 2

        # Bonds that were periodic in the original tile.
        indices_of_periodic_bonds = set()
        for particle1, particle2 in tile.bonds():
            if np.linalg.norm(particle1.pos - particle2.pos) > bond_dist_thres:
                indices_of_periodic_bonds.add(
                    (particle1.index, particle2.index))

        # Build a periodic kdtree of all particle positions.
        self.particle_kdtree = PeriodicCKDTree(data=self.xyz,
                                               bounds=self.periodicity)
        all_particles = np.asarray(list(self.particles(include_ports=False)))

        # Store bonds to remove/add since we'll be iterating over all bonds.
        bonds_to_remove = set()
        bonds_to_add = set()
        for particle1, particle2 in self.bonds():
            if (particle1.index, particle2.index) not in indices_of_periodic_bonds \
                    and (particle2.index, particle1.index) not in indices_of_periodic_bonds:
                continue

            if self.min_periodic_distance(particle1.pos,
                                          particle2.pos) > bond_dist_thres:
                bonds_to_remove.add((particle1, particle2))
                image2 = self._find_particle_image(particle1, particle2,
                                                   all_particles)
                image1 = self._find_particle_image(particle2, particle1,
                                                   all_particles)

                if (image2, particle1) not in bonds_to_add:
                    bonds_to_add.add((particle1, image2))
                if (image1, particle2) not in bonds_to_add:
                    bonds_to_add.add((particle2, image1))

        for bond in bonds_to_remove:
            self.remove_bond(bond)

        for bond in bonds_to_add:
            self.add_bond(bond)

        # Clean up temporary data.
        for particle in self._particles(include_ports=True):
            particle.index = None
        del self.particle_kdtree